From 7e4a54865aaac85454be8a72c331deeaad7dc04e Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Sat, 23 Mar 2024 10:13:01 -0400 Subject: [PATCH 1/5] improve some error messages --- vyper/exceptions.py | 3 ++- vyper/semantics/analysis/module.py | 2 +- vyper/semantics/types/module.py | 3 +++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/vyper/exceptions.py b/vyper/exceptions.py index ced249f247..3897f0ea41 100644 --- a/vyper/exceptions.py +++ b/vyper/exceptions.py @@ -127,8 +127,9 @@ def format_annotation(self, value): return None if isinstance(node, vy_ast.VyperNode): - module_node = node.get_ancestor(vy_ast.Module) + module_node = node.module_node + # TODO: handle cases where module is None or vy_ast.Module if module_node.get("path") not in (None, ""): node_msg = f'{node_msg}contract "{module_node.path}:{node.lineno}", ' diff --git a/vyper/semantics/analysis/module.py b/vyper/semantics/analysis/module.py index 90493d643b..5cec8b42af 100644 --- a/vyper/semantics/analysis/module.py +++ b/vyper/semantics/analysis/module.py @@ -524,7 +524,7 @@ def visit_ExportsDecl(self, node): decl_node = func_t.decl_node if not isinstance(func_t, ContractFunctionT): - raise StructureException("not a function!", decl_node, item) + raise StructureException(f"not a function: `{func_t}`", decl_node, item) if not func_t.is_external: raise StructureException("can't export non-external functions!", decl_node, item) diff --git a/vyper/semantics/types/module.py b/vyper/semantics/types/module.py index a242bfa1fe..b828cdf6bc 100644 --- a/vyper/semantics/types/module.py +++ b/vyper/semantics/types/module.py @@ -323,6 +323,9 @@ def __init__(self, module: vy_ast.Module, name: Optional[str] = None): # can access interfaces in type position self._helper.add_member(name, TYPE_T(interface_t)) + def __str__(self): + return f"module {self._id}" + # __eq__ is very strict on ModuleT - object equality! this is because we # don't want to reason about where a module came from (i.e. input bundle, # search path, symlinked vs normalized path, etc.) From 484cc8ac23f6de733f4d304f7fc5df11adeda27e Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Sat, 23 Mar 2024 10:42:04 -0400 Subject: [PATCH 2/5] fix transitive exports put exports into the module type namespace --- vyper/semantics/types/module.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/vyper/semantics/types/module.py b/vyper/semantics/types/module.py index b828cdf6bc..f5202e6707 100644 --- a/vyper/semantics/types/module.py +++ b/vyper/semantics/types/module.py @@ -296,6 +296,10 @@ def __init__(self, module: vy_ast.Module, name: Optional[str] = None): # note: this checks for collisions self.add_member(f.name, f._metadata["func_type"]) + for item in self.exports_decls: + for fn_t in item._metadata["exports_info"].functions: + self.add_member(fn_t.name, fn_t) + for e in self.event_defs: # add the type of the event so it can be used in call position self.add_member(e.name, TYPE_T(e._metadata["event_type"])) # type: ignore From 9585f933ff40018ca10ec07fc07e21ebe58bb28a Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Sat, 23 Mar 2024 10:46:06 -0400 Subject: [PATCH 3/5] fix: error message regression --- vyper/semantics/types/module.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/vyper/semantics/types/module.py b/vyper/semantics/types/module.py index f5202e6707..a74f7d1b6e 100644 --- a/vyper/semantics/types/module.py +++ b/vyper/semantics/types/module.py @@ -327,9 +327,6 @@ def __init__(self, module: vy_ast.Module, name: Optional[str] = None): # can access interfaces in type position self._helper.add_member(name, TYPE_T(interface_t)) - def __str__(self): - return f"module {self._id}" - # __eq__ is very strict on ModuleT - object equality! this is because we # don't want to reason about where a module came from (i.e. input bundle, # search path, symlinked vs normalized path, etc.) From 047165a5cde182f8ea0cceb157054bc4f469e512 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Sat, 23 Mar 2024 10:47:35 -0400 Subject: [PATCH 4/5] enable xfailing test --- tests/functional/codegen/modules/test_exports.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/functional/codegen/modules/test_exports.py b/tests/functional/codegen/modules/test_exports.py index 042d231211..25ae01e9b1 100644 --- a/tests/functional/codegen/modules/test_exports.py +++ b/tests/functional/codegen/modules/test_exports.py @@ -131,9 +131,7 @@ def foo() -> uint256: assert c.foo() == 5 -# not sure if this one should work -@pytest.mark.xfail(reason="ambiguous spec") -def test_recursive_export(make_input_bundle, get_contract): +def test_transitive_export(make_input_bundle, get_contract): lib1 = """ @external def foo() -> uint256: From 164bb56af084fb6cb78de3de8e158b2458bc0446 Mon Sep 17 00:00:00 2001 From: Charles Cooper Date: Sat, 23 Mar 2024 10:54:09 -0400 Subject: [PATCH 5/5] fix lint --- tests/functional/codegen/modules/test_exports.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/functional/codegen/modules/test_exports.py b/tests/functional/codegen/modules/test_exports.py index 25ae01e9b1..2dc90bfe74 100644 --- a/tests/functional/codegen/modules/test_exports.py +++ b/tests/functional/codegen/modules/test_exports.py @@ -1,6 +1,3 @@ -import pytest - - def test_simple_export(make_input_bundle, get_contract): lib1 = """ @external