Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/vyperlang/vyper into feat…
Browse files Browse the repository at this point in the history
…/const_interface
  • Loading branch information
tserg committed Jan 15, 2024
2 parents 0c0f4ae + af5c49f commit 4924a85
Show file tree
Hide file tree
Showing 26 changed files with 444 additions and 180 deletions.
1 change: 1 addition & 0 deletions docs/resources.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Frameworks and tooling
- `🐍 snekmate – Vyper smart contract building blocks <https://github.com/pcaversaccio/snekmate>`_
- `Serpentor – A set of smart contracts tools for governance <https://github.com/yearn/serpentor>`_
- `Smart contract development frameworks and tools for Vyper on Ethreum.org <https://ethereum.org/en/developers/docs/programming-languages/python/>`_
- `Vyper Online Compiler - an online platform for compiling and deploying Vyper smart contracts <https://github.com/0x0077/vyper-online-compiler>`_

Security
--------
Expand Down
2 changes: 1 addition & 1 deletion requirements-docs.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
sphinx==4.5.0
sphinx==5.0.0
recommonmark==0.6.0
sphinx_rtd_theme==0.5.2
29 changes: 29 additions & 0 deletions tests/functional/codegen/features/iteration/test_for_in_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
NamespaceCollision,
StateAccessViolation,
StructureException,
SyntaxException,
TypeMismatch,
UnknownType,
)

BASIC_FOR_LOOP_CODE = [
Expand Down Expand Up @@ -803,6 +805,33 @@ def test_for() -> int128:
""",
TypeMismatch,
),
(
"""
@external
def foo():
for i in [1, 2, 3]:
pass
""",
SyntaxException,
),
(
"""
@external
def foo():
for i: $$$ in [1, 2, 3]:
pass
""",
SyntaxException,
),
(
"""
@external
def foo():
for i: uint9 in [1, 2, 3]:
pass
""",
UnknownType,
),
]

BAD_CODE = [code if isinstance(code, tuple) else (code, StructureException) for code in BAD_CODE]
Expand Down
8 changes: 0 additions & 8 deletions tests/functional/codegen/features/test_assert.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,6 @@ def test():
assert self.ret1() == 1
""",
"""
@internal
def valid_address(sender: address) -> bool:
selfdestruct(sender)
@external
def test():
assert self.valid_address(msg.sender)
""",
"""
@external
def test():
assert raw_call(msg.sender, b'', max_outsize=1, gas=10, value=1000*1000) == b''
Expand Down
1 change: 0 additions & 1 deletion tests/functional/codegen/features/test_conditionals.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ def foo(i: bool) -> int128:
else:
assert 2 != 0
return 7
return 11
"""

c = get_contract_with_gas_estimation(conditional_return_code)
Expand Down
31 changes: 31 additions & 0 deletions tests/functional/codegen/modules/test_interface_imports.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
def test_import_interface_types(make_input_bundle, get_contract):
ifaces = """
interface IFoo:
def foo() -> uint256: nonpayable
"""

foo_impl = """
import ifaces
implements: ifaces.IFoo
@external
def foo() -> uint256:
return block.number
"""

contract = """
import ifaces
@external
def test_foo(s: ifaces.IFoo) -> bool:
assert s.foo() == block.number
return True
"""

input_bundle = make_input_bundle({"ifaces.vy": ifaces})

foo = get_contract(foo_impl, input_bundle=input_bundle)
c = get_contract(contract, input_bundle=input_bundle)

assert c.test_foo(foo.address) is True
78 changes: 78 additions & 0 deletions tests/functional/codegen/modules/test_module_constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
def test_module_constant(make_input_bundle, get_contract):
mod1 = """
X: constant(uint256) = 12345
"""
contract = """
import mod1
@external
def foo() -> uint256:
return mod1.X
"""

input_bundle = make_input_bundle({"mod1.vy": mod1})

c = get_contract(contract, input_bundle=input_bundle)

assert c.foo() == 12345


def test_nested_module_constant(make_input_bundle, get_contract):
# test nested module constants
# test at least 3 modules deep to test the `path.reverse()` gizmo
# in ConstantFolder.visit_Attribute()
mod1 = """
X: constant(uint256) = 12345
"""
mod2 = """
import mod1
X: constant(uint256) = 54321
"""
mod3 = """
import mod2
X: constant(uint256) = 98765
"""

contract = """
import mod1
import mod2
import mod3
@external
def test_foo() -> bool:
assert mod1.X == 12345
assert mod2.X == 54321
assert mod3.X == 98765
assert mod2.mod1.X == mod1.X
assert mod3.mod2.mod1.X == mod1.X
assert mod3.mod2.X == mod2.X
return True
"""

input_bundle = make_input_bundle({"mod1.vy": mod1, "mod2.vy": mod2, "mod3.vy": mod3})

c = get_contract(contract, input_bundle=input_bundle)
assert c.test_foo() is True


def test_import_constant_array(make_input_bundle, get_contract, tx_failed):
mod1 = """
X: constant(uint256[3]) = [1,2,3]
"""
contract = """
import mod1
@external
def foo(ix: uint256) -> uint256:
return mod1.X[ix]
"""

input_bundle = make_input_bundle({"mod1.vy": mod1})

c = get_contract(contract, input_bundle=input_bundle)

assert c.foo(0) == 1
assert c.foo(1) == 2
assert c.foo(2) == 3
with tx_failed():
c.foo(3)
12 changes: 12 additions & 0 deletions tests/functional/syntax/exceptions/test_syntax_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ def f(a:uint256,/): # test posonlyargs blocked
def g():
self.f()
""",
"""
@external
def foo():
for i in range(0, 10):
pass
""",
"""
@external
def foo():
for i: $$$ in range(0, 10):
pass
""",
]


Expand Down
48 changes: 47 additions & 1 deletion tests/functional/syntax/test_for_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
StateAccessViolation,
StructureException,
TypeMismatch,
UnknownType,
)

fail_list = [
Expand Down Expand Up @@ -235,9 +236,54 @@ def foo():
"Bound must be at least 1",
"FOO",
),
(
"""
@external
def foo():
for i: DynArra[uint256, 3] in [1, 2, 3]:
pass
""",
UnknownType,
"No builtin or user-defined type named 'DynArra'. Did you mean 'DynArray'?",
"DynArra",
),
(
# test for loop target broken into multiple lines
"""
@external
def foo():
for i: \\
\\
\\
\\
\\
\\
uint9 in [1,2,3]:
pass
""",
UnknownType,
"No builtin or user-defined type named 'uint9'. Did you mean 'uint96', or maybe 'uint8'?",
"uint9",
),
(
# test an even more deranged example
"""
@external
def foo():
for i: \\
\\
DynArray[\\
uint9, 3\\
] in [1,2,3]:
pass
""",
UnknownType,
"No builtin or user-defined type named 'uint9'. Did you mean 'uint96', or maybe 'uint8'?",
"uint9",
),
]

for_code_regex = re.compile(r"for .+ in (.*):")
for_code_regex = re.compile(r"for .+ in (.*):", re.DOTALL)
fail_test_names = [
(
f"{i:02d}: {for_code_regex.search(code).group(1)}" # type: ignore[union-attr]
Expand Down
2 changes: 1 addition & 1 deletion tests/functional/syntax/test_interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def foo(): nonpayable
"""
implements: self.x
""",
StructureException,
InvalidType,
),
(
"""
Expand Down
Loading

0 comments on commit 4924a85

Please sign in to comment.