diff --git a/src/griffe/loader.py b/src/griffe/loader.py index afa57269..aabed786 100644 --- a/src/griffe/loader.py +++ b/src/griffe/loader.py @@ -225,7 +225,10 @@ def expand_wildcards( # noqa: WPS231 del obj[name] # noqa: WPS420 for new_member, alias_lineno, alias_endlineno in expanded: - obj[new_member.name] = Alias(new_member.name, new_member, lineno=alias_lineno, endlineno=alias_endlineno) + if new_member.name not in obj.members or obj[new_member.name].lineno < alias_lineno: + obj[new_member.name] = Alias( + new_member.name, new_member, lineno=alias_lineno, endlineno=alias_endlineno + ) def resolve_module_aliases( # noqa: WPS231 self, diff --git a/tests/test_loader.py b/tests/test_loader.py index 4d83ab06..88da8bf3 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -64,3 +64,19 @@ def test_dont_shortcut_alias_chain_after_expanding_wildcards(): assert isinstance(base, Name) assert base.source == "Base" assert base.full == "package.mod_b.Base" + + +def test_dont_overwrite_lower_member_when_expanding_wildcard(): + """Check that we don't overwrite a member defined after the import when expanding a wildcard.""" + with temporary_pypackage("package", ["mod_a.py", "mod_b.py"]) as tmp_package: + mod_a = tmp_package.path / "mod_a.py" + mod_b = tmp_package.path / "mod_b.py" + + mod_a.write_text("overwritten = 0\nfrom package.mod_b import *\nnot_overwritten = 0\n") + mod_b.write_text("overwritten = 1\nnot_overwritten = 1\n") + + loader = GriffeLoader(search_paths=[tmp_package.tmpdir]) + package = loader.load_module(tmp_package.name) + loader.resolve_aliases() + assert package["mod_a.overwritten"].value == "1" + assert package["mod_a.not_overwritten"].value == "0"