Skip to content

Commit

Permalink
reject weird exports of value types
Browse files Browse the repository at this point in the history
also add a test for an exception case that was not tested before
  • Loading branch information
charles-cooper committed Oct 22, 2024
1 parent 7a2d36d commit ac43beb
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
33 changes: 33 additions & 0 deletions tests/functional/syntax/modules/test_exports.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,3 +485,36 @@ def an_internal_function():
# as_posix() for windows
lib1_path = (tmp_path / "lib1.vy").as_posix()
assert e.value._message == f"lib1 (located at `{lib1_path}`) has no external functions!"


def test_invalid_export(make_input_bundle):
lib1 = """
@external
def foo():
pass
"""
main = """
import lib1
a: address
exports: lib1.__interface__(self.a).foo
"""
input_bundle = make_input_bundle({"lib1.vy": lib1})

with pytest.raises(StructureException) as e:
compile_code(main, input_bundle=input_bundle)

assert e.value._message == "invalid export of a value"
assert e.value._hint == "exports should look like <module>.<function | interface>"

main = """
interface Foo:
def foo(): nonpayable
exports: Foo
"""
with pytest.raises(StructureException) as e:
compile_code(main)

assert e.value._message == "invalid export"
assert e.value._hint == "exports should look like <module>.<function | interface>"
10 changes: 9 additions & 1 deletion vyper/semantics/analysis/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
)
from vyper.semantics.data_locations import DataLocation
from vyper.semantics.namespace import Namespace, get_namespace, override_global_namespace
from vyper.semantics.types import EventT, FlagT, InterfaceT, StructT, is_type_t
from vyper.semantics.types import TYPE_T, EventT, FlagT, InterfaceT, StructT, is_type_t
from vyper.semantics.types.function import ContractFunctionT
from vyper.semantics.types.module import ModuleT
from vyper.semantics.types.utils import type_from_annotation
Expand Down Expand Up @@ -499,6 +499,14 @@ def visit_ExportsDecl(self, node):
raise StructureException("not a public variable!", decl, item)
funcs = [decl._expanded_getter._metadata["func_type"]]
elif isinstance(info.typ, ContractFunctionT):
# e.g. lib1.__interface__(self._addr).foo
if not isinstance(get_expr_info(item.value).typ, (ModuleT, TYPE_T)):
raise StructureException(
"invalid export of a value",
item.value,
hint="exports should look like <module>.<function | interface>",
)

# regular function
funcs = [info.typ]
elif is_type_t(info.typ, InterfaceT):
Expand Down

0 comments on commit ac43beb

Please sign in to comment.