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

fix[ux]: error messages relating to initializer issues #3831

Merged
2 changes: 1 addition & 1 deletion tests/functional/syntax/modules/test_initializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ def foo():
with pytest.raises(InitializerException) as e:
compile_code(main, input_bundle=input_bundle)
assert e.value._message == "`lib2` uses `lib1`, but it is not initialized with `lib1`"
assert e.value._hint == "add `lib1` to its initializer list"
assert e.value._hint == "did you mean lib2[lib1 := lib1]?"


def test_missing_uses(make_input_bundle):
Expand Down
8 changes: 6 additions & 2 deletions vyper/semantics/analysis/global_.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,12 @@ def _validate_global_initializes_constraint(module_t: ModuleT):
if u not in all_initialized_modules:
found_module = module_t.find_module_info(u)
if found_module is not None:
hint = f"add `initializes: {found_module.alias}` to the top level of "
hint += "your main contract"
# TODO: do something about these constants
if str(module_t) in ("<unknown>", "VyperContract.vy"):
module_str = "the top level of your main contract"
else:
module_str = f"`{module_t}`"
hint = f"add `initializes: {found_module.alias}` to {module_str}"
else:
# CMC 2024-02-06 is this actually reachable?
hint = f"ensure `{module_t}` is imported in your main contract!"
Expand Down
25 changes: 23 additions & 2 deletions vyper/semantics/analysis/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,13 @@ def validate_initialized_modules(self):
msg = "not initialized!"
hint = f"add `{s.module_info.alias}.__init__()` to "
hint += "your `__init__()` function"
err_list.append(InitializerException(msg, s.node, hint=hint))

# grab the init function AST node for error message
# (it could be None, it's ok since it's just for diagnostics)
init_func_node = None
if module_t.init_function:
init_func_node = module_t.init_function.decl_node
err_list.append(InitializerException(msg, init_func_node, s.node, hint=hint))

err_list.raise_if_not_empty()

Expand Down Expand Up @@ -489,7 +495,22 @@ def visit_InitializesDecl(self, node):
item = next(iter(used_modules.values())) # just pick one
msg = f"`{module_info.alias}` uses `{item.alias}`, but it is not "
msg += f"initialized with `{item.alias}`"
hint = f"add `{item.alias}` to its initializer list"

lhs = item.alias
rhs = None
# find the alias of the uninitialized module in this contract
# to fill out the error message with.
for k, v in self.namespace.items():
if isinstance(v, ModuleInfo) and v.module_t == item.module_t:
rhs = k
break

if rhs is None:
hint = "try importing {item.alias} first"
charles-cooper marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be an f-string, right

elif isinstance(module_ref, vy_ast.Name):
hint = f"did you mean {module_ref.id}[{lhs} := {rhs}]?"
else:
hint = f"add `{lhs} := {rhs}` to its initializer list"
charles-cooper marked this conversation as resolved.
Show resolved Hide resolved
raise InitializerException(msg, node, hint=hint)

# note: try to refactor. not a huge fan of mutating the
Expand Down
Loading