diff --git a/src/_griffe/models.py b/src/_griffe/models.py index 4cf2648f..0c7b1e91 100644 --- a/src/_griffe/models.py +++ b/src/_griffe/models.py @@ -774,17 +774,12 @@ def resolve(self, name: str) -> str: return self.members[name].target_path # type: ignore[union-attr] return self.members[name].path - # Name was imported. - if name in self.imports: - return self.imports[name] - # Name unknown and no more parent scope. if self.parent is None: # could be a built-in raise NameResolutionError(f"{name} could not be resolved in the scope of {self.path}") # Name is parent, non-module object. - # NOTE: possibly useless branch. if name == self.parent.name and not self.parent.is_module: return self.parent.path diff --git a/tests/test_models.py b/tests/test_models.py index 6e2a7578..f40c567f 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -12,6 +12,7 @@ Docstring, GriffeLoader, Module, + NameResolutionError, module_vtree, temporary_inspected_module, temporary_pypackage, @@ -443,3 +444,52 @@ class Derived(Base): derived_params = [p.name for p in module["Derived"].parameters] assert base_params == ["self", "a"] assert derived_params == ["self", "a", "d"] + + +def test_name_resolution() -> None: + """Name are correctly resolved in the scope of an object.""" + code = """ + module_attribute = 0 + + class Class: + import imported + + class_attribute = 0 + + def __init__(self): + self.instance_attribute = 0 + + def method(self): + local_variable = 0 + """ + with temporary_visited_module(code) as module: + assert module.resolve("module_attribute") == "module.module_attribute" + assert module.resolve("Class") == "module.Class" + + assert module["module_attribute"].resolve("Class") == "module.Class" + with pytest.raises(NameResolutionError): + module["module_attribute"].resolve("class_attribute") + + assert module["Class"].resolve("module_attribute") == "module.module_attribute" + assert module["Class"].resolve("imported") == "imported" + assert module["Class"].resolve("class_attribute") == "module.Class.class_attribute" + assert module["Class"].resolve("instance_attribute") == "module.Class.instance_attribute" + assert module["Class"].resolve("method") == "module.Class.method" + + assert module["Class.class_attribute"].resolve("module_attribute") == "module.module_attribute" + assert module["Class.class_attribute"].resolve("Class") == "module.Class" + assert module["Class.class_attribute"].resolve("imported") == "imported" + assert module["Class.class_attribute"].resolve("instance_attribute") == "module.Class.instance_attribute" + assert module["Class.class_attribute"].resolve("method") == "module.Class.method" + + assert module["Class.instance_attribute"].resolve("module_attribute") == "module.module_attribute" + assert module["Class.instance_attribute"].resolve("Class") == "module.Class" + assert module["Class.instance_attribute"].resolve("imported") == "imported" + assert module["Class.instance_attribute"].resolve("class_attribute") == "module.Class.class_attribute" + assert module["Class.instance_attribute"].resolve("method") == "module.Class.method" + + assert module["Class.method"].resolve("module_attribute") == "module.module_attribute" + assert module["Class.method"].resolve("Class") == "module.Class" + assert module["Class.method"].resolve("imported") == "imported" + assert module["Class.method"].resolve("class_attribute") == "module.Class.class_attribute" + assert module["Class.method"].resolve("instance_attribute") == "module.Class.instance_attribute"