Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enable dynarrays of strings #2922

Merged
merged 6 commits into from
Jun 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions tests/parser/features/iteration/test_for_in_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,43 @@ def data() -> int128:
return -1""",
7,
),
(
# test variable string dynarray
"""
@external
def data() -> String[33]:
xs: DynArray[String[33], 3] = ["hello", ",", "world"]
for x in xs:
if x == ",":
return x
return ""
""",
",",
),
(
# test literal string dynarray
"""
@external
def data() -> String[33]:
for x in ["hello", ",", "world"]:
if x == ",":
return x
return ""
""",
",",
),
(
# test nested string dynarray
"""
@external
def data() -> DynArray[String[33], 2]:
for x in [["hello", "world"], ["goodbye", "world!"]]:
if x[1] == "world":
return x
return []
""",
["hello", "world"],
),
# test nested array
(
"""
Expand Down
68 changes: 0 additions & 68 deletions tests/parser/syntax/test_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,74 +226,6 @@ def foo(x: int128[2][2]):
""",
TypeMismatch,
),
(
"""
@external
def foo():
for str in ["hello", "world"]:
pass
""",
StructureException,
),
(
"""
@external
def foo():
a: String[6] = "hello"
b: String[6] = "world"
for str in [a, b]:
pass
""",
StructureException,
),
(
"""
a: String[6]
b: String[6]

@external
def foo():
self.a = "hello"
self.b = "world"
for str in [self.a, self.b]:
pass
""",
StructureException,
),
(
"""
@external
def foo():
for str in [b"hello,", b"world"]:
pass
""",
StructureException,
),
(
"""
@external
def foo():
a: Bytes[6] = b"hello"
b: Bytes[6] = b"world"
for str in [a, b]:
pass
""",
StructureException,
),
(
"""
a: Bytes[6]
b: Bytes[6]

@external
def foo():
self.a = b"hello"
self.b = b"world"
for str in [self.a, self.b]:
pass
""",
StructureException,
),
]


Expand Down
67 changes: 40 additions & 27 deletions tests/parser/types/test_dynamic_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
InvalidType,
OverflowException,
StateAccessViolation,
StructureException,
TypeMismatch,
)

Expand Down Expand Up @@ -61,6 +60,46 @@ def loo(x: DynArray[DynArray[int128, 2], 2]) -> int128:
print("Passed list tests")


def test_string_list(get_contract):
code = """
@external
def foo1(x: DynArray[String[32], 2]) -> DynArray[String[32], 2]:
return x

@external
def foo2(x: DynArray[DynArray[String[32], 2], 2]) -> DynArray[DynArray[String[32], 2], 2]:
return x

@external
def foo3(x: DynArray[DynArray[String[32], 2], 2]) -> DynArray[String[32], 2]:
return x[0]

@external
def foo4(x: DynArray[DynArray[String[32], 2], 2]) -> String[32]:
return x[0][0]

@external
def foo5() -> DynArray[String[32], 2]:
ret: DynArray[String[32], 2] = ["hello"]
ret.append("world")
return ret

@external
def foo6() -> DynArray[DynArray[String[32], 2], 2]:
ret: DynArray[DynArray[String[32], 2], 2] = []
ret.append(["hello", "world"])
return ret
"""

c = get_contract(code)
assert c.foo1(["hello", "world"]) == ["hello", "world"]
assert c.foo2([["hello", "world"]]) == [["hello", "world"]]
assert c.foo3([["hello", "world"]]) == ["hello", "world"]
assert c.foo4([["hello", "world"]]) == "hello"
assert c.foo5() == ["hello", "world"]
assert c.foo6() == [["hello", "world"]]


def test_list_output_tester_code(get_contract_with_gas_estimation):
list_output_tester_code = """
z: DynArray[int128, 2]
Expand Down Expand Up @@ -1601,29 +1640,3 @@ def foo(i: uint256) -> {return_type}:
return MY_CONSTANT[i]
"""
assert_compile_failed(lambda: get_contract(code), TypeMismatch)


INVALID_ARRAY_VALUES = [
"""
a: DynArray[Bytes[5], 2]
""",
"""
a: DynArray[String[5], 2]
""",
"""
a: DynArray[DynArray[Bytes[5], 2], 2]
""",
"""
a: DynArray[DynArray[String[5], 2], 2]
""",
]


@pytest.mark.parametrize("invalid_contracts", INVALID_ARRAY_VALUES)
def test_invalid_dyn_array_values(
get_contract_with_gas_estimation, assert_compile_failed, invalid_contracts
):

assert_compile_failed(
lambda: get_contract_with_gas_estimation(invalid_contracts), StructureException
)
4 changes: 0 additions & 4 deletions vyper/semantics/types/indexable/sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
IndexableTypeDefinition,
MemberTypeDefinition,
)
from vyper.semantics.types.value.array_value import BytesArrayDefinition, StringDefinition
from vyper.semantics.types.value.numeric import Uint256Definition # type: ignore


Expand Down Expand Up @@ -248,9 +247,6 @@ def from_annotation(
node.slice.value.elements[0], location, is_constant, is_public, is_immutable
)

if isinstance(value_type, (BytesArrayDefinition, StringDefinition)):
raise StructureException(f"{value_type._id} arrays are not supported", node)

max_length = node.slice.value.elements[1].value
return DynamicArrayDefinition(
value_type, max_length, location, is_constant, is_public, is_immutable
Expand Down
6 changes: 0 additions & 6 deletions vyper/semantics/validation/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
DynamicArrayDefinition,
TupleDefinition,
)
from vyper.semantics.types.value.array_value import BytesArrayDefinition, StringDefinition
from vyper.semantics.types.value.boolean import BoolDefinition
from vyper.semantics.validation.levenshtein_utils import get_levenshtein_error_suggestions

Expand Down Expand Up @@ -240,11 +239,6 @@ def types_from_List(self, node):

types_list = get_common_types(*node.elements)

# Throw exception if only possible type is String or Bytes
if len(types_list) == 1:
if isinstance(types_list[0], (StringDefinition, BytesArrayDefinition)):
raise StructureException(f"{types_list[0]._id} arrays are not supported", node)

if len(types_list) > 0:
count = len(node.elements)
ret = []
Expand Down