Repository: vyperlang/vyper

Issue:
Converting sliced bytes to non-bytes32 doesn't work
### Version Information
* vyper Version: 0.1.0b4

### What's your issue about?
Vyper doesn't like converting a slice of `bytes` (slice len <=32) to a type other than `bytes32`:

```python
# Compiles!
@public
@constant
def foo(_arg: bytes[100]) -> bytes32:
    return convert(slice(_arg, start=20, len=32), bytes32)

# Does not compile....
@public
@constant
def bar(_arg: bytes[100]) -> uint256:
    return convert(slice(_arg, start=20, len=32), uint256)

# Compiles! (Workaround)
@public
@constant
def baz(_arg: bytes[100]) -> uint256:
    return convert(convert(slice(_arg, start=20, len=32), bytes32), uint256)

# Note: above does not work for addresses!
```

### How can it be fixed?
Make it so!

#### Cute Animal Picture

![fluffy pony](https://i.ytimg.com/vi/sNv1s5lAZts/maxresdefault.jpg)



Discussion:
@fubuloubu I'm starting to look into this one. One note for now, this guy also compiles:

```python
# Compiles!
@public
@constant
def who(_arg: bytes[100]) -> int128:
    return convert(slice(_arg, start=20, len=32), int128)
```

Seems like we may want to re-name this issue to be more specific to converting from `bytes` to `int128`, though perhaps we do want to also add converting from `bytes` to `address`? Though perhaps not converting from `bytes` to `decimal` as converting from `bytes32` to `decimal` is also not currently supported. Thoughts?

Resolving patch:
diff --git a/vyper/types/convert.py b/vyper/types/convert.py
--- a/vyper/types/convert.py
+++ b/vyper/types/convert.py
@@ -49,7 +49,7 @@ def to_int128(expr, args, kwargs, context):
         return byte_array_to_num(in_node, expr, 'int128')
 
 
-@signature(('num_literal', 'int128', 'bytes32', 'address', 'bool'), '*')
+@signature(('num_literal', 'int128', 'bytes32', 'bytes', 'address', 'bool'), '*')
 def to_uint256(expr, args, kwargs, context):
     in_node = args[0]
     input_type, len = get_type(in_node)
@@ -67,6 +67,11 @@ def to_uint256(expr, args, kwargs, context):
     elif isinstance(in_node, LLLnode) and input_type in ('bytes32', 'address'):
         return LLLnode(value=in_node.value, args=in_node.args, typ=BaseType('uint256'), pos=getpos(expr))
 
+    elif isinstance(in_node, LLLnode) and input_type is 'bytes':
+        if in_node.typ.maxlen > 32:
+            raise InvalidLiteralException("Cannot convert bytes array of max length {} to uint256".format(in_node.value), expr)
+        return byte_array_to_num(in_node, expr, 'uint256')
+
     else:
         raise InvalidLiteralException("Invalid input for uint256: %r" % in_node, expr)
 


Test patch:
diff --git a/tests/parser/functions/test_convert_uint256.py b/tests/parser/functions/test_convert_uint256.py
--- a/tests/parser/functions/test_convert_uint256.py
+++ b/tests/parser/functions/test_convert_uint256.py
@@ -1,3 +1,54 @@
+from vyper.exceptions import (
+    InvalidLiteralException
+)
+
+
+def test_convert_bytes_to_uint256(assert_compile_failed, get_contract_with_gas_estimation):
+    # Test valid bytes input for conversion
+    test_success = """
+@public
+def foo(bar: bytes[5]) -> uint256:
+    return convert(bar, uint256)
+    """
+
+    c = get_contract_with_gas_estimation(test_success)
+    assert c.foo(b'\x00\x00\x00\x00\x00') == 0
+    assert c.foo(b'\x00\x07\x5B\xCD\x15') == 123456789
+
+    test_success = """
+@public
+def foo(bar: bytes[32]) -> uint256:
+    return convert(bar, uint256)
+    """
+
+    c = get_contract_with_gas_estimation(test_success)
+    assert c.foo(b'\x00' * 32) == 0
+    assert c.foo(b'\xff' * 32) == ((2**256) - 1)
+
+    # Test overflow bytes input for conversion
+    test_fail = """
+@public
+def foo(bar: bytes[33]) -> uint256:
+    return convert(bar, uint256)
+    """
+
+    assert_compile_failed(
+        lambda: get_contract_with_gas_estimation(test_fail),
+        InvalidLiteralException
+    )
+
+    test_fail = """
+@public
+def foobar() -> uint256:
+    barfoo: bytes[63] = "Hello darkness, my old friend I've come to talk with you again."
+    return convert(barfoo, uint256)
+    """
+
+    assert_compile_failed(
+        lambda: get_contract_with_gas_estimation(test_fail),
+        InvalidLiteralException
+    )
+
 
 def test_convert_from_bool(get_contract_with_gas_estimation):
     code = """
diff --git a/tests/parser/types/numbers/test_uint256.py b/tests/parser/types/numbers/test_uint256.py
--- a/tests/parser/types/numbers/test_uint256.py
+++ b/tests/parser/types/numbers/test_uint256.py
@@ -1,5 +1,3 @@
-# from ethereum.abi import ValueOutOfBounds
-
 
 def test_uint256_code(assert_tx_failed, get_contract_with_gas_estimation):
     uint256_code = """