Skip to content

Commit

Permalink
feat(core): handle local modules without __init__.py
Browse files Browse the repository at this point in the history
  • Loading branch information
mkniewallner committed Jan 29, 2023
1 parent d725951 commit eeda478
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 16 deletions.
21 changes: 16 additions & 5 deletions deptry/core.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from __future__ import annotations

import logging
import os
import sys
from dataclasses import dataclass
from pathlib import Path
Expand Down Expand Up @@ -110,13 +109,25 @@ def _get_dependencies(self, dependency_management_format: DependencyManagementFo
raise IncorrectDependencyFormatError

def _get_local_modules(self) -> set[str]:
directories = [f for f in os.scandir(self.root) if f.is_dir()]
guessed_local_modules = {
subdirectory.name for subdirectory in directories if "__init__.py" in os.listdir(subdirectory)
}
"""
Get all local Python modules from the root directory and `known_first_party` list.
A module is considered a local Python module if it matches at least one of those conditions:
- it is a directory that contains at least one Python file
- it is a Python file that is not named `__init__.py` (since it is a special case)
- it is set in the `known_first_party` list
"""
guessed_local_modules = {path.stem for path in self.root.iterdir() if self._is_local_module(path)}

return guessed_local_modules | set(self.known_first_party)

@staticmethod
def _is_local_module(path: Path) -> bool:
"""Guess if a module is a local Python module."""
return bool(
(path.is_file() and path.name != "__init__.py" and path.suffix == ".py")
or (path.is_dir() and list(path.glob("*.py")))
)

@staticmethod
def _get_stdlib_modules() -> frozenset[str]:
if sys.version_info[:2] >= (3, 10):
Expand Down
2 changes: 1 addition & 1 deletion tests/cli/test_cli_src_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def test_cli_with_src_directory(pep_621_dir_with_src_directory: Path) -> None:
assert result.returncode == 1
assert get_issues_report() == {
"misplaced_dev": [],
"missing": ["white"],
"missing": ["httpx", "white"],
"obsolete": ["isort", "requests", "mypy", "pytest"],
"transitive": [],
}
2 changes: 1 addition & 1 deletion tests/data/project_with_src_directory/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ dev = [
"mypy==0.982",
]
test = [
"pytest==7.2.0",
"pytest==7.2.0",
]

[build-system]
Expand Down
5 changes: 5 additions & 0 deletions tests/data/project_with_src_directory/src/foobar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import httpx


def another_local_method():
...
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from project_with_src_directory.foo import a_local_method
from foobar import another_local_method
14 changes: 5 additions & 9 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,17 @@
(
(),
"",
{"module_with_init"},
),
(
("module_without_init",),
"",
{"module_with_init", "module_without_init"},
{"module_with_init", "module_without_init", "local_file"},
),
(
("module_with_init", "module_without_init"),
"",
{"module_with_init", "module_without_init"},
{"module_with_init", "module_without_init", "local_file"},
),
(
("module_without_init",),
"module_with_init",
{"module_without_init", "subdirectory"},
{"foo", "module_without_init", "subdirectory"},
),
],
)
Expand All @@ -47,7 +42,8 @@ def test__get_local_modules(
{"dir": "module_with_init", "file": "foo.py"},
{"dir": "module_with_init/subdirectory", "file": "__init__.py"},
{"dir": "module_with_init/subdirectory", "file": "foo.py"},
{"dir": "module_without_init", "file": "foo.py"},
{"dir": "module_without_init", "file": "bar.py"},
{"dir": ".", "file": "local_file.py"},
]
create_files_from_list_of_dicts(paths)

Expand Down

0 comments on commit eeda478

Please sign in to comment.