Skip to content

Commit

Permalink
fix: Support setuptools' new editable modules using type annotations
Browse files Browse the repository at this point in the history
Issue-273: #273
  • Loading branch information
pawamoy committed May 23, 2024
1 parent 88e7e71 commit 14d45e8
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 10 deletions.
15 changes: 9 additions & 6 deletions src/griffe/finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -468,14 +468,17 @@ def _handle_editable_module(path: Path) -> list[_SP]:
if _match_pattern(path.name, _editable_setuptools_patterns):
# Support for how 'setuptools' writes these files:
# example line: `MAPPING = {'griffe': '/media/data/dev/griffe/src/griffe', 'briffe': '/media/data/dev/griffe/src/briffe'}`.
# with annotation: `MAPPING: dict[str, str] = {...}`.
parsed_module = ast.parse(path.read_text())
for node in parsed_module.body:
if (
isinstance(node, ast.Assign)
and isinstance(node.targets[0], ast.Name)
and node.targets[0].id == "MAPPING"
) and isinstance(node.value, ast.Dict):
return [_SP(Path(cst.value).parent) for cst in node.value.values if isinstance(cst, ast.Constant)]
if isinstance(node, ast.Assign):
target = node.targets[0]
elif isinstance(node, ast.AnnAssign):
target = node.target
else:
continue
if isinstance(target, ast.Name) and target.id == "MAPPING" and isinstance(node.value, ast.Dict): # type: ignore[attr-defined]
return [_SP(Path(cst.value).parent) for cst in node.value.values if isinstance(cst, ast.Constant)] # type: ignore[attr-defined]
if _match_pattern(path.name, _editable_meson_python_patterns):
# Support for how 'meson-python' writes these files:
# example line: `install({'package', 'module1'}, '/media/data/dev/griffe/build/cp311', ["path"], False)`.
Expand Down
14 changes: 10 additions & 4 deletions tests/test_finder.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,27 +128,33 @@ def test_editables_file_handling(tmp_path: Path, editable_file_name: str) -> Non
assert paths == [Path("src")]


def test_setuptools_file_handling(tmp_path: Path) -> None:
@pytest.mark.parametrize("annotation", ["", ": dict[str, str]"])
def test_setuptools_file_handling(tmp_path: Path, annotation: str) -> None:
"""Assert editable modules by `setuptools` are handled.
Parameters:
tmp_path: Pytest fixture.
annotation: The type annotation of the MAPPING variable.
"""
pth_file = tmp_path / "__editable__whatever.py"
pth_file.write_text("hello\nMAPPING = {'griffe': 'src/griffe'}")
pth_file.write_text(f"hello\nMAPPING{annotation} = {{'griffe': 'src/griffe'}}")
paths = [sp.path for sp in _handle_editable_module(pth_file)]
assert paths == [Path("src")]


def test_setuptools_file_handling_multiple_paths(tmp_path: Path) -> None:
@pytest.mark.parametrize("annotation", ["", ": dict[str, str]"])
def test_setuptools_file_handling_multiple_paths(tmp_path: Path, annotation: str) -> None:
"""Assert editable modules by `setuptools` are handled when multiple packages are installed in the same editable.
Parameters:
tmp_path: Pytest fixture.
annotation: The type annotation of the MAPPING variable.
"""
pth_file = tmp_path / "__editable__whatever.py"
pth_file.write_text(
"hello=1\nMAPPING = {\n'griffe':\n 'src1/griffe', 'briffe':'src2/briffe'}\ndef printer():\n print(hello)",
"hello=1\n"
f"MAPPING{annotation} = {{\n'griffe':\n 'src1/griffe', 'briffe':'src2/briffe'}}\n"
"def printer():\n print(hello)",
)
paths = [sp.path for sp in _handle_editable_module(pth_file)]
assert paths == [Path("src1"), Path("src2")]
Expand Down

0 comments on commit 14d45e8

Please sign in to comment.