From 897f00e2003eae3f10cc2668cbd65f03d87fa691 Mon Sep 17 00:00:00 2001 From: Florian Maas Date: Sun, 17 Mar 2024 07:21:44 +0100 Subject: [PATCH 01/12] fix unit tests --- tests/utils.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/utils.py b/tests/utils.py index 4f7f348f..c97193d7 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -79,8 +79,10 @@ def setup(self, setup_commands: list[str], deptry_directory: Path) -> None: shutil.copytree(deptry_directory / "tests/data" / self.project, self.project_path / "project") + path_to_wheel_file = self._get_path_to_wheel_file(deptry_directory / DEPTRY_WHEEL_DIRECTORY) + for setup_command in [ - f"pip install --find-links {deptry_directory / DEPTRY_WHEEL_DIRECTORY} deptry", + f"pip install --no-cache-dir {path_to_wheel_file}", *setup_commands, ]: self.run(setup_command, check=True, cwd=self.project_path / "project") @@ -95,6 +97,16 @@ def run(self, command: str, check: bool = False, cwd: Path | None = None) -> sub cwd=cwd, ) + @staticmethod + def _get_path_to_wheel_file(directory: Path) -> Path: + """ + Get the path to a single wheel file in the specified directory. If there is not exactly one wheel file, raise an error. + """ + wheel_files = list(directory.glob("*.whl")) + if len(wheel_files) != 1: + raise ValueError(f"Expected exactly one wheel file in {directory}, but found {len(wheel_files)}.") # noqa: TRY003 + return wheel_files[0] + @contextmanager def run_within_dir(path: Path) -> Generator[None, None, None]: From 23cb9df5fe5298c760fab182aca1c36cf841e16a Mon Sep 17 00:00:00 2001 From: Florian Maas Date: Sat, 16 Mar 2024 17:42:17 +0100 Subject: [PATCH 02/12] rename requirements-txt and requirements-txt-dev to requirements-file and requirements-file-dev --- docs/usage.md | 12 +-- python/deptry/cli.py | 34 ++++++-- python/deptry/core.py | 12 +-- ...quirements_txt.py => requirements_file.py} | 10 +-- .../dependency_specification_detector.py | 16 ++-- python/deptry/deprecate/requirements_txt.py | 15 ++++ python/deptry/exceptions.py | 4 +- .../cli/test_cli_requirements_txt.py | 4 +- .../test_requirements_txt.py | 20 ++--- tests/unit/deprecate/test_requirements_txt.py | 82 +++++++++++++++++++ tests/unit/test_config.py | 16 ++-- tests/unit/test_core.py | 4 +- .../test_dependency_specification_detector.py | 12 +-- 13 files changed, 178 insertions(+), 63 deletions(-) rename python/deptry/dependency_getter/{requirements_txt.py => requirements_file.py} (93%) create mode 100644 python/deptry/deprecate/requirements_txt.py create mode 100644 tests/unit/deprecate/test_requirements_txt.py diff --git a/docs/usage.md b/docs/usage.md index 0305993a..3b7f0e05 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -227,36 +227,36 @@ ignore_notebooks = true deptry . --ignore-notebooks ``` -#### Requirements txt +#### Requirements file List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-files) that contain the source dependencies. - Type: `List[str]` - Default: `["requirements.txt"]` -- `pyproject.toml` option name: `requirements_txt` +- `pyproject.toml` option name: `requirements_file` - CLI option name: `--requirements-txt` (short: `-rt`) - `pyproject.toml` example: ```toml [tool.deptry] -requirements_txt = ["requirements.txt", "requirements-private.txt"] +requirements_file = ["requirements.txt", "requirements-private.txt"] ``` - CLI example: ```shell deptry . --requirements-txt requirements.txt,requirements-private.txt ``` -#### Requirements txt dev +#### Requirements file dev List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-files) that contain the source development dependencies. - Type: `List[str]` - Default: `["dev-requirements.txt", "requirements-dev.txt"]` -- `pyproject.toml` option name: `requirements_txt_dev` +- `pyproject.toml` option name: `requirements_file_dev` - CLI option name: `--requirements-txt-dev` (short: `-rtd`) - `pyproject.toml` example: ```toml [tool.deptry] -requirements_txt_dev = ["requirements-dev.txt", "requirements-tests.txt"] +requirements_file_dev = ["requirements-dev.txt", "requirements-tests.txt"] ``` - CLI example: ```shell diff --git a/python/deptry/cli.py b/python/deptry/cli.py index 0d395607..297fc636 100644 --- a/python/deptry/cli.py +++ b/python/deptry/cli.py @@ -12,6 +12,10 @@ from deptry.config import read_configuration_from_pyproject_toml from deptry.core import Core from deptry.deprecate.ignore_flags import get_value_for_per_rule_ignores_argument +from deptry.deprecate.requirements_txt import ( + REQUIREMENTS_TXT_DEPRECATION_MESSAGE, + REQUIREMENTS_TXT_DEV_DEPRECATION_MESSAGE, +) from deptry.deprecate.skip_flags import get_value_for_ignore_argument if TYPE_CHECKING: @@ -243,19 +247,25 @@ def display_deptry_version(ctx: click.Context, _param: click.Parameter, value: b help="Display the current version and exit.", ) @click.option( - "--requirements-txt", - "-rt", + "--requirements-txt", "-rt", type=COMMA_SEPARATED_TUPLE, help="To be deprecated.", hidden=True, default=() +) +@click.option( + "--requirements-txt-dev", "-rtd", type=COMMA_SEPARATED_TUPLE, help="To be deprecated.", hidden=True, default=() +) +@click.option( + "--requirements-file", + "-rf", type=COMMA_SEPARATED_TUPLE, - help=""".txt files to scan for dependencies. If a file called pyproject.toml with a [tool.poetry.dependencies] section is found, this argument is ignored + help=""".txt files to scan for dependencies. If a file called pyproject.toml with a [tool.poetry.dependencies] or [project] section is found, this argument is ignored and the dependencies are extracted from the pyproject.toml file instead. Can be multiple e.g. `deptry . --requirements-txt req/prod.txt,req/extra.txt`""", default=("requirements.txt",), show_default=True, ) @click.option( - "--requirements-txt-dev", - "-rtd", + "--requirements-file-dev", + "-rfd", type=COMMA_SEPARATED_TUPLE, - help=""".txt files to scan for additional development dependencies. If a file called pyproject.toml with a [tool.poetry.dependencies] section is found, this argument is ignored + help=""".txt files to scan for additional development dependencies. If a file called pyproject.toml with a [tool.poetry.dependencies] or [project] section is found, this argument is ignored and the dependencies are extracted from the pyproject.toml file instead. Can be multiple e.g. `deptry . --requirements-txt-dev req/dev.txt,req/test.txt`""", default=("dev-requirements.txt", "requirements-dev.txt"), show_default=True, @@ -305,6 +315,8 @@ def deptry( ignore_notebooks: bool, requirements_txt: tuple[str, ...], requirements_txt_dev: tuple[str, ...], + requirements_file: tuple[str, ...], + requirements_file_dev: tuple[str, ...], known_first_party: tuple[str, ...], json_output: str, package_module_name_map: MutableMapping[str, tuple[str, ...]], @@ -322,6 +334,12 @@ def deptry( deptry src worker """ + if requirements_txt: + logging.warning(REQUIREMENTS_TXT_DEPRECATION_MESSAGE) + + if requirements_txt_dev: + logging.warning(REQUIREMENTS_TXT_DEV_DEPRECATION_MESSAGE) + ignore = get_value_for_ignore_argument( ignore, skip_missing=skip_missing, @@ -348,8 +366,8 @@ def deptry( ignore_notebooks=ignore_notebooks, ignore=ignore, per_rule_ignores=per_rule_ignores, - requirements_txt=requirements_txt, - requirements_txt_dev=requirements_txt_dev, + requirements_file=requirements_txt if requirements_txt else requirements_file, + requirements_file_dev=requirements_txt_dev if requirements_txt_dev else requirements_file_dev, known_first_party=known_first_party, json_output=json_output, package_module_name_map=package_module_name_map, diff --git a/python/deptry/core.py b/python/deptry/core.py index ff8b0ec1..81f3c4b2 100644 --- a/python/deptry/core.py +++ b/python/deptry/core.py @@ -9,7 +9,7 @@ from deptry.dependency_getter.pdm import PDMDependencyGetter from deptry.dependency_getter.pep_621 import PEP621DependencyGetter from deptry.dependency_getter.poetry import PoetryDependencyGetter -from deptry.dependency_getter.requirements_txt import RequirementsTxtDependencyGetter +from deptry.dependency_getter.requirements_file import RequirementsTxtDependencyGetter from deptry.dependency_specification_detector import DependencyManagementFormat, DependencySpecificationDetector from deptry.exceptions import IncorrectDependencyFormatError, UnsupportedPythonVersionError from deptry.imports.extract import get_imported_modules_from_list_of_files @@ -48,8 +48,8 @@ class Core: extend_exclude: tuple[str, ...] using_default_exclude: bool ignore_notebooks: bool - requirements_txt: tuple[str, ...] - requirements_txt_dev: tuple[str, ...] + requirements_file: tuple[str, ...] + requirements_file_dev: tuple[str, ...] known_first_party: tuple[str, ...] json_output: str package_module_name_map: Mapping[str, tuple[str, ...]] @@ -58,7 +58,7 @@ def run(self) -> None: self._log_config() dependency_management_format = DependencySpecificationDetector( - self.config, requirements_txt=self.requirements_txt + self.config, requirements_file=self.requirements_file ).detect() dependencies_extract = self._get_dependencies(dependency_management_format) @@ -144,9 +144,9 @@ def _get_dependencies(self, dependency_management_format: DependencyManagementFo return PDMDependencyGetter(self.config, self.package_module_name_map).get() if dependency_management_format is DependencyManagementFormat.PEP_621: return PEP621DependencyGetter(self.config, self.package_module_name_map).get() - if dependency_management_format is DependencyManagementFormat.REQUIREMENTS_TXT: + if dependency_management_format is DependencyManagementFormat.requirements_file: return RequirementsTxtDependencyGetter( - self.config, self.package_module_name_map, self.requirements_txt, self.requirements_txt_dev + self.config, self.package_module_name_map, self.requirements_file, self.requirements_file_dev ).get() raise IncorrectDependencyFormatError diff --git a/python/deptry/dependency_getter/requirements_txt.py b/python/deptry/dependency_getter/requirements_file.py similarity index 93% rename from python/deptry/dependency_getter/requirements_txt.py rename to python/deptry/dependency_getter/requirements_file.py index 19da3e5d..d3072b43 100644 --- a/python/deptry/dependency_getter/requirements_txt.py +++ b/python/deptry/dependency_getter/requirements_file.py @@ -16,13 +16,13 @@ class RequirementsTxtDependencyGetter(DependencyGetter): """Extract dependencies from requirements.txt files.""" - requirements_txt: tuple[str, ...] = ("requirements.txt",) - requirements_txt_dev: tuple[str, ...] = ("dev-requirements.txt", "requirements-dev.txt") + requirements_file: tuple[str, ...] = ("requirements.txt",) + requirements_file_dev: tuple[str, ...] = ("dev-requirements.txt", "requirements-dev.txt") def get(self) -> DependenciesExtract: dependencies = list( itertools.chain( - *(self._get_dependencies_from_requirements_file(file_name) for file_name in self.requirements_txt) + *(self._get_dependencies_from_requirements_file(file_name) for file_name in self.requirements_file) ) ) self._log_dependencies(dependencies=dependencies) @@ -41,9 +41,9 @@ def get(self) -> DependenciesExtract: def _scan_for_dev_requirements_files(self) -> list[str]: """ - Check if any of the files passed as requirements_txt_dev exist, and if so; return them. + Check if any of the files passed as requirements_file_dev exist, and if so; return them. """ - dev_requirements_files = [file_name for file_name in self.requirements_txt_dev if file_name in os.listdir()] + dev_requirements_files = [file_name for file_name in self.requirements_file_dev if file_name in os.listdir()] if dev_requirements_files: logging.debug("Found files with development requirements! %s", dev_requirements_files) return dev_requirements_files diff --git a/python/deptry/dependency_specification_detector.py b/python/deptry/dependency_specification_detector.py index 92bb4839..7f6608cb 100644 --- a/python/deptry/dependency_specification_detector.py +++ b/python/deptry/dependency_specification_detector.py @@ -12,7 +12,7 @@ class DependencyManagementFormat(Enum): PDM = "pdm" PEP_621 = "pep_621" POETRY = "poetry" - REQUIREMENTS_TXT = "requirements_txt" + REQUIREMENTS_TXT = "requirements_file" class DependencySpecificationDetector: @@ -25,9 +25,9 @@ class DependencySpecificationDetector: """ - def __init__(self, config: Path, requirements_txt: tuple[str, ...] = ("requirements.txt",)) -> None: + def __init__(self, config: Path, requirements_file: tuple[str, ...] = ("requirements.txt",)) -> None: self.config = config - self.requirements_txt = requirements_txt + self.requirements_file = requirements_file def detect(self) -> DependencyManagementFormat: pyproject_toml_found = self._project_contains_pyproject_toml() @@ -37,10 +37,10 @@ def detect(self) -> DependencyManagementFormat: return DependencyManagementFormat.PDM if pyproject_toml_found and self._project_uses_pep_621(): return DependencyManagementFormat.PEP_621 - if self._project_uses_requirements_txt(): + if self._project_uses_requirements_file(): return DependencyManagementFormat.REQUIREMENTS_TXT - raise DependencySpecificationNotFoundError(self.requirements_txt) + raise DependencySpecificationNotFoundError(self.requirements_file) def _project_contains_pyproject_toml(self) -> bool: if self.config.exists(): @@ -100,11 +100,11 @@ def _project_uses_pep_621(self) -> bool: else: return True - def _project_uses_requirements_txt(self) -> bool: - check = any(Path(requirements_txt).is_file() for requirements_txt in self.requirements_txt) + def _project_uses_requirements_file(self) -> bool: + check = any(Path(requirements_file).is_file() for requirements_file in self.requirements_file) if check: logging.debug( "Dependency specification found in '%s'. Will use this to determine the project's dependencies.\n", - ", ".join(self.requirements_txt), + ", ".join(self.requirements_file), ) return check diff --git a/python/deptry/deprecate/requirements_txt.py b/python/deptry/deprecate/requirements_txt.py new file mode 100644 index 00000000..e8534790 --- /dev/null +++ b/python/deptry/deprecate/requirements_txt.py @@ -0,0 +1,15 @@ +from __future__ import annotations + +REQUIREMENTS_TXT_DEPRECATION_MESSAGE = ( + "Warning: In an upcoming release, support for the `--requirements-txt` command-line " + "option and the `requirements_txt` configuration parameter will be discontinued. " + "Instead, use `--requirements-file` or `requirements_txt` under the `[tool.deptry]` " + "section in pyproject.toml." +) + +REQUIREMENTS_TXT_DEV_DEPRECATION_MESSAGE = ( + "Warning: In an upcoming release, support for the `--requirements-txt-dev` command-line " + "option and the `requirements_txt_dev` configuration parameter will be discontinued. " + "Instead, use `--requirements-file-dev` or `requirements_txt_dev` under the `[tool.deptry]` " + "section in pyproject.toml." +) diff --git a/python/deptry/exceptions.py b/python/deptry/exceptions.py index 78e545ed..5dc17daa 100644 --- a/python/deptry/exceptions.py +++ b/python/deptry/exceptions.py @@ -9,10 +9,10 @@ class DependencySpecificationNotFoundError(FileNotFoundError): - def __init__(self, requirements_txt: tuple[str, ...]) -> None: + def __init__(self, requirements_file: tuple[str, ...]) -> None: super().__init__( "No file called 'pyproject.toml' with a [tool.poetry.dependencies], [tool.pdm] or [project] section or" - f" file(s) called '{', '.join(requirements_txt)}' found. Exiting." + f" file(s) called '{', '.join(requirements_file)}' found. Exiting." ) diff --git a/tests/functional/cli/test_cli_requirements_txt.py b/tests/functional/cli/test_cli_requirements_txt.py index 59eccc17..5677be47 100644 --- a/tests/functional/cli/test_cli_requirements_txt.py +++ b/tests/functional/cli/test_cli_requirements_txt.py @@ -14,7 +14,7 @@ @pytest.mark.xdist_group(name=Project.REQUIREMENTS_TXT) -def test_cli_single_requirements_txt(pip_venv_factory: PipVenvFactory) -> None: +def test_cli_single_requirements_file(pip_venv_factory: PipVenvFactory) -> None: with pip_venv_factory( Project.REQUIREMENTS_TXT, install_command=( @@ -105,7 +105,7 @@ def test_cli_single_requirements_txt(pip_venv_factory: PipVenvFactory) -> None: @pytest.mark.xdist_group(name=Project.REQUIREMENTS_TXT) -def test_cli_multiple_requirements_txt(pip_venv_factory: PipVenvFactory) -> None: +def test_cli_multiple_requirements_file(pip_venv_factory: PipVenvFactory) -> None: with pip_venv_factory( Project.REQUIREMENTS_TXT, install_command=( diff --git a/tests/unit/dependency_getter/test_requirements_txt.py b/tests/unit/dependency_getter/test_requirements_txt.py index 096931fa..6094fd4a 100644 --- a/tests/unit/dependency_getter/test_requirements_txt.py +++ b/tests/unit/dependency_getter/test_requirements_txt.py @@ -4,12 +4,12 @@ import pytest -from deptry.dependency_getter.requirements_txt import RequirementsTxtDependencyGetter +from deptry.dependency_getter.requirements_file import RequirementsTxtDependencyGetter from tests.utils import run_within_dir -def test_parse_requirements_txt(tmp_path: Path) -> None: - fake_requirements_txt = """click==8.1.3 #123asd +def test_parse_requirements_file(tmp_path: Path) -> None: + fake_requirements_file = """click==8.1.3 #123asd colorama==0.4.5 importlib-metadata==4.2.0 ; python_version >= "3.7" and python_version < "3.8" isort==5.10.1, <6.0 @@ -33,7 +33,7 @@ def test_parse_requirements_txt(tmp_path: Path) -> None: """ with run_within_dir(tmp_path): with Path("requirements.txt").open("w") as f: - f.write(fake_requirements_txt) + f.write(fake_requirements_file) getter = RequirementsTxtDependencyGetter( config=Path("pyproject.toml"), @@ -66,8 +66,8 @@ def test_parse_requirements_txt(tmp_path: Path) -> None: assert "fox" in dependencies[17].top_levels -def test_parse_requirements_txt_urls(tmp_path: Path) -> None: - fake_requirements_txt = """urllib3 @ https://github.com/urllib3/urllib3/archive/refs/tags/1.26.8.zip +def test_parse_requirements_file_urls(tmp_path: Path) -> None: + fake_requirements_file = """urllib3 @ https://github.com/urllib3/urllib3/archive/refs/tags/1.26.8.zip https://github.com/urllib3/urllib3/archive/refs/tags/1.26.8.zip git+https://github.com/baz/foo-bar.git@asd#egg=foo-bar git+https://github.com/baz/foo-bar.git@asd @@ -75,7 +75,7 @@ def test_parse_requirements_txt_urls(tmp_path: Path) -> None: with run_within_dir(tmp_path): with Path("requirements.txt").open("w") as f: - f.write(fake_requirements_txt) + f.write(fake_requirements_file) dependencies_extract = RequirementsTxtDependencyGetter(Path("pyproject.toml")).get() dependencies = dependencies_extract.dependencies @@ -96,7 +96,7 @@ def test_single(tmp_path: Path) -> None: f.write("click==8.1.3 #123asd\ncolorama==0.4.5") dependencies_extract = RequirementsTxtDependencyGetter( - Path("pyproject.toml"), requirements_txt=("req.txt",) + Path("pyproject.toml"), requirements_file=("req.txt",) ).get() dependencies = dependencies_extract.dependencies @@ -116,7 +116,7 @@ def test_multiple(tmp_path: Path) -> None: f.write("bar") dependencies_extract = RequirementsTxtDependencyGetter( - Path("pyproject.toml"), requirements_txt=("foo.txt", "bar.txt") + Path("pyproject.toml"), requirements_file=("foo.txt", "bar.txt") ).get() dependencies = dependencies_extract.dependencies @@ -180,7 +180,7 @@ def test_dev_multiple_with_arguments(tmp_path: Path) -> None: f.write("bar") dependencies_extract = RequirementsTxtDependencyGetter( - Path("pyproject.toml"), requirements_txt_dev=("foo.txt", "bar.txt") + Path("pyproject.toml"), requirements_file_dev=("foo.txt", "bar.txt") ).get() dev_dependencies = dependencies_extract.dev_dependencies diff --git a/tests/unit/deprecate/test_requirements_txt.py b/tests/unit/deprecate/test_requirements_txt.py new file mode 100644 index 00000000..fecc9dda --- /dev/null +++ b/tests/unit/deprecate/test_requirements_txt.py @@ -0,0 +1,82 @@ +from __future__ import annotations + +from unittest.mock import ANY, patch + +from click.testing import CliRunner + +from deptry.cli import deptry +from deptry.deprecate.requirements_txt import ( + REQUIREMENTS_TXT_DEPRECATION_MESSAGE, + REQUIREMENTS_TXT_DEV_DEPRECATION_MESSAGE, +) + +DEFAULT_CORE_ARGS = { + "root": (ANY,), + "config": ANY, + "no_ansi": ANY, + "exclude": ANY, + "extend_exclude": ANY, + "using_default_exclude": ANY, + "ignore_notebooks": ANY, + "ignore": ANY, + "per_rule_ignores": ANY, + "known_first_party": ANY, + "json_output": ANY, + "package_module_name_map": ANY, +} + + +def test_requirements_txt_deprecated(): + with patch("deptry.cli.Core") as mock_core, patch("logging.warning") as mock_warning: + result = CliRunner().invoke(deptry, [".", "--requirements-txt", "somefile.txt"]) + + assert result.exit_code == 0 + mock_warning.assert_called_once_with(REQUIREMENTS_TXT_DEPRECATION_MESSAGE) + + # Assert that Core was instantiated with the correct arguments + mock_core.assert_called_once_with( + **DEFAULT_CORE_ARGS, + requirements_file=("somefile.txt",), + requirements_file_dev=("dev-requirements.txt", "requirements-dev.txt"), + ) + + +def test_requirements_txt_dev_deprecated(): + with patch("deptry.cli.Core") as mock_core, patch("logging.warning") as mock_warning: + result = CliRunner().invoke(deptry, [".", "--requirements-txt-dev", "somefile.txt"]) + + assert result.exit_code == 0 + mock_warning.assert_called_once_with(REQUIREMENTS_TXT_DEV_DEPRECATION_MESSAGE) + + # Assert that Core was instantiated with the correct arguments + mock_core.assert_called_once_with( + **DEFAULT_CORE_ARGS, requirements_file=("requirements.txt",), requirements_file_dev=("somefile.txt",) + ) + + +def test_requirements_file_works_as_expected(): + with patch("deptry.cli.Core") as mock_core, patch("logging.warning") as mock_warning: + result = CliRunner().invoke(deptry, [".", "--requirements-file", "somefile.txt"]) + + assert result.exit_code == 0 + mock_warning.assert_not_called() + + # Assert that Core was instantiated with the correct arguments + mock_core.assert_called_once_with( + **DEFAULT_CORE_ARGS, + requirements_file=("somefile.txt",), + requirements_file_dev=("dev-requirements.txt", "requirements-dev.txt"), + ) + + +def test_requirements_file_dev_works_as_expected(): + with patch("deptry.cli.Core") as mock_core, patch("logging.warning") as mock_warning: + result = CliRunner().invoke(deptry, [".", "--requirements-file-dev", "somefile.txt"]) + + assert result.exit_code == 0 + mock_warning.assert_not_called() + + # Assert that Core was instantiated with the correct arguments + mock_core.assert_called_once_with( + **DEFAULT_CORE_ARGS, requirements_file=("requirements.txt",), requirements_file_dev=("somefile.txt",) + ) diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index 2e42387d..0e70b8da 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -24,8 +24,8 @@ Argument(param_decls=["per_rule_ignores"]), Argument(param_decls=["ignore"]), Argument(param_decls=["ignore_notebooks"]), - Argument(param_decls=["requirements_txt"]), - Argument(param_decls=["requirements_txt_dev"]), + Argument(param_decls=["requirements_file"]), + Argument(param_decls=["requirements_file_dev"]), ], ) @@ -40,8 +40,8 @@ def test_read_configuration_from_pyproject_toml_exists(tmp_path: Path) -> None: "DEP002": ["baz", "bar"], }, "ignore": [], - "requirements_txt": "requirements.txt", - "requirements_txt_dev": ["requirements-dev.txt"], + "requirements_file": "requirements.txt", + "requirements_file_dev": ["requirements-dev.txt"], }, ) @@ -51,8 +51,8 @@ def test_read_configuration_from_pyproject_toml_exists(tmp_path: Path) -> None: extend_exclude = ["bar", "foo"] ignore_notebooks = true ignore = ["DEP001", "DEP002", "DEP003", "DEP004"] - requirements_txt = "foo.txt" - requirements_txt_dev = ["dev.txt", "tests.txt"] + requirements_file = "foo.txt" + requirements_file_dev = ["dev.txt", "tests.txt"] [tool.deptry.per_rule_ignores] DEP001 = ["baz", "foobar"] @@ -83,8 +83,8 @@ def test_read_configuration_from_pyproject_toml_exists(tmp_path: Path) -> None: "DEP004": ["barfoo"], }, "ignore": ["DEP001", "DEP002", "DEP003", "DEP004"], - "requirements_txt": "foo.txt", - "requirements_txt_dev": ["dev.txt", "tests.txt"], + "requirements_file": "foo.txt", + "requirements_file_dev": ["dev.txt", "tests.txt"], } diff --git a/tests/unit/test_core.py b/tests/unit/test_core.py index 4a91aa27..f841d8be 100644 --- a/tests/unit/test_core.py +++ b/tests/unit/test_core.py @@ -86,8 +86,8 @@ def test__get_local_modules( extend_exclude=(), using_default_exclude=True, ignore_notebooks=False, - requirements_txt=(), - requirements_txt_dev=(), + requirements_file=(), + requirements_file_dev=(), known_first_party=known_first_party, json_output="", package_module_name_map={}, diff --git a/tests/unit/test_dependency_specification_detector.py b/tests/unit/test_dependency_specification_detector.py index ae129c92..dc7ea3ac 100644 --- a/tests/unit/test_dependency_specification_detector.py +++ b/tests/unit/test_dependency_specification_detector.py @@ -21,7 +21,7 @@ def test_poetry(tmp_path: Path) -> None: assert spec == DependencyManagementFormat.POETRY -def test_requirements_txt(tmp_path: Path) -> None: +def test_requirements_file(tmp_path: Path) -> None: with run_within_dir(tmp_path): with Path("requirements.txt").open("w") as f: f.write('foo >= "1.0"') @@ -84,23 +84,23 @@ def test_both(tmp_path: Path) -> None: assert spec == DependencyManagementFormat.POETRY -def test_requirements_txt_with_argument(tmp_path: Path) -> None: +def test_requirements_file_with_argument(tmp_path: Path) -> None: with run_within_dir(tmp_path): with Path("req.txt").open("w") as f: f.write('foo >= "1.0"') - spec = DependencySpecificationDetector(Path("pyproject.toml"), requirements_txt=("req.txt",)).detect() + spec = DependencySpecificationDetector(Path("pyproject.toml"), requirements_file=("req.txt",)).detect() assert spec == DependencyManagementFormat.REQUIREMENTS_TXT -def test_requirements_txt_with_argument_not_root_directory(tmp_path: Path) -> None: +def test_requirements_file_with_argument_not_root_directory(tmp_path: Path) -> None: with run_within_dir(tmp_path): Path("req").mkdir() with Path("req/req.txt").open("w") as f: f.write('foo >= "1.0"') - spec = DependencySpecificationDetector(Path("pyproject.toml"), requirements_txt=("req/req.txt",)).detect() + spec = DependencySpecificationDetector(Path("pyproject.toml"), requirements_file=("req/req.txt",)).detect() assert spec == DependencyManagementFormat.REQUIREMENTS_TXT @@ -112,4 +112,4 @@ def test_dependency_specification_not_found_raises_exception(tmp_path: Path) -> " file(s) called 'req/req.txt' found. Exiting." ), ): - DependencySpecificationDetector(Path("pyproject.toml"), requirements_txt=("req/req.txt",)).detect() + DependencySpecificationDetector(Path("pyproject.toml"), requirements_file=("req/req.txt",)).detect() From 313af12f5621965c9bf1577729ee342b9f523df7 Mon Sep 17 00:00:00 2001 From: Florian Maas Date: Sat, 16 Mar 2024 17:45:04 +0100 Subject: [PATCH 03/12] fix docs --- docs/usage.md | 10 +++++----- tests/functional/cli/test_cli_requirements_txt.py | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 3b7f0e05..28712ea9 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -35,7 +35,7 @@ To determine the project's dependencies, _deptry_ will scan the directory it is - development dependencies from `dev-dependencies.txt` and `dependencies-dev.txt`, if any exist _deptry_ can be configured to look for `pip` requirements files with other names or in other directories. -See [Requirements txt](#requirements-txt) and [Requirements txt dev](#requirements-txt-dev). +See [Requirements txt](#requirements-file) and [Requirements txt dev](#requirements-file-dev). ## Excluding files and directories @@ -234,7 +234,7 @@ List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#req - Type: `List[str]` - Default: `["requirements.txt"]` - `pyproject.toml` option name: `requirements_file` -- CLI option name: `--requirements-txt` (short: `-rt`) +- CLI option name: `--requirements-file` (short: `-rt`) - `pyproject.toml` example: ```toml [tool.deptry] @@ -242,7 +242,7 @@ requirements_file = ["requirements.txt", "requirements-private.txt"] ``` - CLI example: ```shell -deptry . --requirements-txt requirements.txt,requirements-private.txt +deptry . --requirements-file requirements.txt,requirements-private.txt ``` #### Requirements file dev @@ -252,7 +252,7 @@ List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#req - Type: `List[str]` - Default: `["dev-requirements.txt", "requirements-dev.txt"]` - `pyproject.toml` option name: `requirements_file_dev` -- CLI option name: `--requirements-txt-dev` (short: `-rtd`) +- CLI option name: `--requirements-file-dev` (short: `-rtd`) - `pyproject.toml` example: ```toml [tool.deptry] @@ -260,7 +260,7 @@ requirements_file_dev = ["requirements-dev.txt", "requirements-tests.txt"] ``` - CLI example: ```shell -deptry . --requirements-txt-dev requirements-dev.txt,requirements-tests.txt +deptry . --requirements-file-dev requirements-dev.txt,requirements-tests.txt ``` #### Known first party diff --git a/tests/functional/cli/test_cli_requirements_txt.py b/tests/functional/cli/test_cli_requirements_txt.py index 5677be47..bd4f4c57 100644 --- a/tests/functional/cli/test_cli_requirements_txt.py +++ b/tests/functional/cli/test_cli_requirements_txt.py @@ -23,7 +23,7 @@ def test_cli_single_requirements_file(pip_venv_factory: PipVenvFactory) -> None: ) as virtual_env: issue_report = f"{uuid.uuid4()}.json" result = virtual_env.run( - "deptry . --requirements-txt requirements.txt --requirements-txt-dev requirements-dev.txt -o" + "deptry . --requirements-file requirements.txt --requirements-file-dev requirements-dev.txt -o" f" {issue_report}" ) @@ -114,7 +114,7 @@ def test_cli_multiple_requirements_file(pip_venv_factory: PipVenvFactory) -> Non ) as virtual_env: issue_report = f"{uuid.uuid4()}.json" result = virtual_env.run( - "deptry . --requirements-txt requirements.txt,requirements-2.txt --requirements-txt-dev" + "deptry . --requirements-file requirements.txt,requirements-2.txt --requirements-file-dev" f" requirements-dev.txt -o {issue_report}" ) From 9553dd154c79993e1ab9fa188d50d528140fab85 Mon Sep 17 00:00:00 2001 From: Florian Maas Date: Sat, 16 Mar 2024 17:53:32 +0100 Subject: [PATCH 04/12] mypy --- python/deptry/core.py | 2 +- python/deptry/dependency_specification_detector.py | 4 ++-- tests/unit/deprecate/test_requirements_txt.py | 8 ++++---- tests/unit/test_dependency_specification_detector.py | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/python/deptry/core.py b/python/deptry/core.py index 81f3c4b2..7be00ee0 100644 --- a/python/deptry/core.py +++ b/python/deptry/core.py @@ -144,7 +144,7 @@ def _get_dependencies(self, dependency_management_format: DependencyManagementFo return PDMDependencyGetter(self.config, self.package_module_name_map).get() if dependency_management_format is DependencyManagementFormat.PEP_621: return PEP621DependencyGetter(self.config, self.package_module_name_map).get() - if dependency_management_format is DependencyManagementFormat.requirements_file: + if dependency_management_format is DependencyManagementFormat.REQUIREMENTS_FILE: return RequirementsTxtDependencyGetter( self.config, self.package_module_name_map, self.requirements_file, self.requirements_file_dev ).get() diff --git a/python/deptry/dependency_specification_detector.py b/python/deptry/dependency_specification_detector.py index 7f6608cb..ee03ec3d 100644 --- a/python/deptry/dependency_specification_detector.py +++ b/python/deptry/dependency_specification_detector.py @@ -12,7 +12,7 @@ class DependencyManagementFormat(Enum): PDM = "pdm" PEP_621 = "pep_621" POETRY = "poetry" - REQUIREMENTS_TXT = "requirements_file" + REQUIREMENTS_FILE = "requirements_file" class DependencySpecificationDetector: @@ -38,7 +38,7 @@ def detect(self) -> DependencyManagementFormat: if pyproject_toml_found and self._project_uses_pep_621(): return DependencyManagementFormat.PEP_621 if self._project_uses_requirements_file(): - return DependencyManagementFormat.REQUIREMENTS_TXT + return DependencyManagementFormat.REQUIREMENTS_FILE raise DependencySpecificationNotFoundError(self.requirements_file) diff --git a/tests/unit/deprecate/test_requirements_txt.py b/tests/unit/deprecate/test_requirements_txt.py index fecc9dda..ae47a833 100644 --- a/tests/unit/deprecate/test_requirements_txt.py +++ b/tests/unit/deprecate/test_requirements_txt.py @@ -26,7 +26,7 @@ } -def test_requirements_txt_deprecated(): +def test_requirements_txt_deprecated() -> None: with patch("deptry.cli.Core") as mock_core, patch("logging.warning") as mock_warning: result = CliRunner().invoke(deptry, [".", "--requirements-txt", "somefile.txt"]) @@ -41,7 +41,7 @@ def test_requirements_txt_deprecated(): ) -def test_requirements_txt_dev_deprecated(): +def test_requirements_txt_dev_deprecated() -> None: with patch("deptry.cli.Core") as mock_core, patch("logging.warning") as mock_warning: result = CliRunner().invoke(deptry, [".", "--requirements-txt-dev", "somefile.txt"]) @@ -54,7 +54,7 @@ def test_requirements_txt_dev_deprecated(): ) -def test_requirements_file_works_as_expected(): +def test_requirements_file_works_as_expected() -> None: with patch("deptry.cli.Core") as mock_core, patch("logging.warning") as mock_warning: result = CliRunner().invoke(deptry, [".", "--requirements-file", "somefile.txt"]) @@ -69,7 +69,7 @@ def test_requirements_file_works_as_expected(): ) -def test_requirements_file_dev_works_as_expected(): +def test_requirements_file_dev_works_as_expected() -> None: with patch("deptry.cli.Core") as mock_core, patch("logging.warning") as mock_warning: result = CliRunner().invoke(deptry, [".", "--requirements-file-dev", "somefile.txt"]) diff --git a/tests/unit/test_dependency_specification_detector.py b/tests/unit/test_dependency_specification_detector.py index dc7ea3ac..f21d6662 100644 --- a/tests/unit/test_dependency_specification_detector.py +++ b/tests/unit/test_dependency_specification_detector.py @@ -27,7 +27,7 @@ def test_requirements_file(tmp_path: Path) -> None: f.write('foo >= "1.0"') spec = DependencySpecificationDetector(Path("pyproject.toml")).detect() - assert spec == DependencyManagementFormat.REQUIREMENTS_TXT + assert spec == DependencyManagementFormat.REQUIREMENTS_FILE def test_pdm_with_dev_dependencies(tmp_path: Path) -> None: @@ -90,7 +90,7 @@ def test_requirements_file_with_argument(tmp_path: Path) -> None: f.write('foo >= "1.0"') spec = DependencySpecificationDetector(Path("pyproject.toml"), requirements_file=("req.txt",)).detect() - assert spec == DependencyManagementFormat.REQUIREMENTS_TXT + assert spec == DependencyManagementFormat.REQUIREMENTS_FILE def test_requirements_file_with_argument_not_root_directory(tmp_path: Path) -> None: @@ -101,7 +101,7 @@ def test_requirements_file_with_argument_not_root_directory(tmp_path: Path) -> N f.write('foo >= "1.0"') spec = DependencySpecificationDetector(Path("pyproject.toml"), requirements_file=("req/req.txt",)).detect() - assert spec == DependencyManagementFormat.REQUIREMENTS_TXT + assert spec == DependencyManagementFormat.REQUIREMENTS_FILE def test_dependency_specification_not_found_raises_exception(tmp_path: Path) -> None: From 1c6eacabbfb246a603bfe2ee93131cd47d78ed9a Mon Sep 17 00:00:00 2001 From: Florian Maas Date: Tue, 19 Mar 2024 13:24:36 +0100 Subject: [PATCH 05/12] remove unused files --- Cargo.lock | 8 +++--- pdm.lock | 2 +- src/imports/location.rs | 27 --------------------- src/imports/visitor.rs | 54 ----------------------------------------- 4 files changed, 5 insertions(+), 86 deletions(-) delete mode 100644 src/imports/location.rs delete mode 100644 src/imports/visitor.rs diff --git a/Cargo.lock b/Cargo.lock index 024fd0b3..4531cb9d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -43,9 +43,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] name = "bstr" @@ -506,7 +506,7 @@ version = "0.0.0" source = "git+https://github.com/astral-sh/ruff?tag=v0.3.3#608df9a1bc0e6025049add877d1d833f1739e966" dependencies = [ "aho-corasick", - "bitflags 2.4.2", + "bitflags 2.5.0", "is-macro", "itertools", "once_cell", @@ -522,7 +522,7 @@ version = "0.0.0" source = "git+https://github.com/astral-sh/ruff?tag=v0.3.3#608df9a1bc0e6025049add877d1d833f1739e966" dependencies = [ "anyhow", - "bitflags 2.4.2", + "bitflags 2.5.0", "bstr", "is-macro", "itertools", diff --git a/pdm.lock b/pdm.lock index 3a38d00d..218bfc85 100644 --- a/pdm.lock +++ b/pdm.lock @@ -5,7 +5,7 @@ groups = ["default", "dev", "docs", "typing"] strategy = ["cross_platform", "inherit_metadata"] lock_version = "4.4.1" -content_hash = "sha256:075a94a78d7250b4bdc64a8e66445f285b6afec47004ca0e45aab3b0744eec29" +content_hash = "sha256:8ebb6c1f321887e2f1b32d8b0cd92c661e9a8879b57df2f1a5aa777ac884bd32" [[package]] name = "babel" diff --git a/src/imports/location.rs b/src/imports/location.rs deleted file mode 100644 index c7e59d1b..00000000 --- a/src/imports/location.rs +++ /dev/null @@ -1,27 +0,0 @@ -use pyo3::prelude::*; - -#[pyclass] -#[derive(Clone, Debug)] -pub struct Location { - #[pyo3(get, set)] - pub file: String, - #[pyo3(get, set)] - pub line: Option, - #[pyo3(get, set)] - pub column: Option, -} - -#[pymethods] -impl Location { - #[new] - pub fn new(file: String, line: Option, column: Option) -> Self { - Location { file, line, column } - } - - fn __repr__(&self) -> PyResult { - Ok(format!( - "Location(file='{}', line={:?}, column={:?})", - self.file, self.line, self.column - )) - } -} diff --git a/src/imports/visitor.rs b/src/imports/visitor.rs deleted file mode 100644 index b478acdc..00000000 --- a/src/imports/visitor.rs +++ /dev/null @@ -1,54 +0,0 @@ -use rustpython_ast::{self, Int, StmtImport, StmtImportFrom, Visitor}; -use rustpython_parser::text_size::TextRange; -use std::collections::HashMap; - -#[derive(Debug, Clone)] -pub struct ImportVisitor { - imports: HashMap>, -} - -impl ImportVisitor { - pub fn new() -> Self { - ImportVisitor { - imports: HashMap::new(), - } - } - - pub fn get_imports(self) -> HashMap> { - self.imports - } -} - -impl Visitor for ImportVisitor { - fn visit_stmt_import(&mut self, node: StmtImport) { - for alias in &node.names { - let top_level_module = get_top_level_module_name(&alias.name); - self.imports - .entry(top_level_module) - .or_default() - .push(alias.range); - } - } - - fn visit_stmt_import_from(&mut self, node: StmtImportFrom) { - let Some(module) = &node.module else { return }; - if node.level != Some(Int::new(0)) { - return; - } - - self.imports - .entry(get_top_level_module_name(module.as_str())) - .or_default() - .push(node.range); - } -} - -/// Extracts the top-level module name from a potentially nested module path. -/// e.g. when a module_name is `foo.bar`, this returns `foo`. -fn get_top_level_module_name(module_name: &str) -> String { - module_name - .split('.') - .next() - .unwrap_or(module_name) - .to_string() -} From ba9175bcf0e95273bf78a7cddbec7a79654b7cf3 Mon Sep 17 00:00:00 2001 From: Florian Maas Date: Sun, 24 Mar 2024 08:08:50 +0100 Subject: [PATCH 06/12] Update docs/usage.md Co-authored-by: Mathieu Kniewallner --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index c1fdb99c..01746b1a 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -36,7 +36,7 @@ To determine the project's dependencies, _deptry_ will scan the directory it is - development dependencies from `dev-dependencies.txt` and `dependencies-dev.txt`, if any exist _deptry_ can be configured to look for `pip` requirements files with other names or in other directories. -See [Requirements txt](#requirements-file) and [Requirements txt dev](#requirements-file-dev). +See [Requirements file](#requirements-file) and [Requirements file dev](#requirements-file-dev). ## Excluding files and directories From bbbc58a07c30f0d8ea7c2114594c08db2ee9e250 Mon Sep 17 00:00:00 2001 From: Florian Maas Date: Sun, 24 Mar 2024 08:09:06 +0100 Subject: [PATCH 07/12] Update python/deptry/cli.py Co-authored-by: Mathieu Kniewallner --- python/deptry/cli.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/deptry/cli.py b/python/deptry/cli.py index dcce71d3..9096c2cc 100644 --- a/python/deptry/cli.py +++ b/python/deptry/cli.py @@ -292,8 +292,8 @@ def deptry( ignore_notebooks=ignore_notebooks, ignore=ignore, per_rule_ignores=per_rule_ignores, - requirements_file=requirements_txt if requirements_txt else requirements_file, - requirements_file_dev=requirements_txt_dev if requirements_txt_dev else requirements_file_dev, + requirements_file=requirements_txt or requirements_file, + requirements_file_dev=requirements_txt_dev or requirements_file_dev, known_first_party=known_first_party, json_output=json_output, package_module_name_map=package_module_name_map, From 310b36c79c633b9213eff3c77a94019ff804da9a Mon Sep 17 00:00:00 2001 From: Florian Maas Date: Sun, 24 Mar 2024 08:09:26 +0100 Subject: [PATCH 08/12] Update python/deptry/deprecate/requirements_txt.py Co-authored-by: Mathieu Kniewallner --- python/deptry/deprecate/requirements_txt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/deptry/deprecate/requirements_txt.py b/python/deptry/deprecate/requirements_txt.py index e8534790..a404ded5 100644 --- a/python/deptry/deprecate/requirements_txt.py +++ b/python/deptry/deprecate/requirements_txt.py @@ -3,7 +3,7 @@ REQUIREMENTS_TXT_DEPRECATION_MESSAGE = ( "Warning: In an upcoming release, support for the `--requirements-txt` command-line " "option and the `requirements_txt` configuration parameter will be discontinued. " - "Instead, use `--requirements-file` or `requirements_txt` under the `[tool.deptry]` " + "Instead, use `--requirements-file` or `requirements_file` under the `[tool.deptry]` " "section in pyproject.toml." ) From 820d02050833e4e1fd836187c8705ae59dcbe65e Mon Sep 17 00:00:00 2001 From: Florian Maas Date: Sun, 24 Mar 2024 08:09:35 +0100 Subject: [PATCH 09/12] Update python/deptry/deprecate/requirements_txt.py Co-authored-by: Mathieu Kniewallner --- python/deptry/deprecate/requirements_txt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/deptry/deprecate/requirements_txt.py b/python/deptry/deprecate/requirements_txt.py index a404ded5..a551db9c 100644 --- a/python/deptry/deprecate/requirements_txt.py +++ b/python/deptry/deprecate/requirements_txt.py @@ -10,6 +10,6 @@ REQUIREMENTS_TXT_DEV_DEPRECATION_MESSAGE = ( "Warning: In an upcoming release, support for the `--requirements-txt-dev` command-line " "option and the `requirements_txt_dev` configuration parameter will be discontinued. " - "Instead, use `--requirements-file-dev` or `requirements_txt_dev` under the `[tool.deptry]` " + "Instead, use `--requirements-file-dev` or `requirements_file_dev` under the `[tool.deptry]` " "section in pyproject.toml." ) From 921ee712a51d323244f1d11d5a94cb07532e24e2 Mon Sep 17 00:00:00 2001 From: Florian Maas Date: Sun, 24 Mar 2024 08:19:29 +0100 Subject: [PATCH 10/12] requirements-files instead of requirements-file --- docs/usage.md | 26 +++++++++---------- python/deptry/cli.py | 12 ++++----- python/deptry/core.py | 10 +++---- ...irements_file.py => requirements_files.py} | 24 ++++++++--------- .../dependency_specification_detector.py | 16 ++++++------ python/deptry/deprecate/requirements_txt.py | 4 +-- python/deptry/exceptions.py | 4 +-- .../cli/test_cli_requirements_txt.py | 8 +++--- .../test_requirements_txt.py | 20 +++++++------- tests/unit/deprecate/test_requirements_txt.py | 20 +++++++------- tests/unit/test_config.py | 16 ++++++------ tests/unit/test_core.py | 4 +-- .../test_dependency_specification_detector.py | 12 ++++----- 13 files changed, 88 insertions(+), 88 deletions(-) rename python/deptry/dependency_getter/{requirements_file.py => requirements_files.py} (84%) diff --git a/docs/usage.md b/docs/usage.md index 01746b1a..edfa8cfa 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -36,7 +36,7 @@ To determine the project's dependencies, _deptry_ will scan the directory it is - development dependencies from `dev-dependencies.txt` and `dependencies-dev.txt`, if any exist _deptry_ can be configured to look for `pip` requirements files with other names or in other directories. -See [Requirements file](#requirements-file) and [Requirements file dev](#requirements-file-dev). +See [Requirements file](#requirements-files) and [Requirements file dev](#requirements-files-dev). ## Excluding files and directories @@ -228,40 +228,40 @@ ignore_notebooks = true deptry . --ignore-notebooks ``` -#### Requirements file +#### Requirements files -List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-files) that contain the source dependencies. +List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-filess) that contain the source dependencies. - Type: `list[str]` - Default: `["requirements.txt"]` -- `pyproject.toml` option name: `requirements_file` -- CLI option name: `--requirements-file` (short: `-rt`) +- `pyproject.toml` option name: `requirements_files` +- CLI option name: `--requirements-files` (short: `-rt`) - `pyproject.toml` example: ```toml [tool.deptry] -requirements_file = ["requirements.txt", "requirements-private.txt"] +requirements_files = ["requirements.txt", "requirements-private.txt"] ``` - CLI example: ```shell -deptry . --requirements-file requirements.txt,requirements-private.txt +deptry . --requirements-files requirements.txt,requirements-private.txt ``` -#### Requirements file dev +#### Requirements files dev -List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-files) that contain the source development dependencies. +List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-filess) that contain the source development dependencies. - Type: `list[str]` - Default: `["dev-requirements.txt", "requirements-dev.txt"]` -- `pyproject.toml` option name: `requirements_file_dev` -- CLI option name: `--requirements-file-dev` (short: `-rtd`) +- `pyproject.toml` option name: `requirements_files_dev` +- CLI option name: `--requirements-files-dev` (short: `-rtd`) - `pyproject.toml` example: ```toml [tool.deptry] -requirements_file_dev = ["requirements-dev.txt", "requirements-tests.txt"] +requirements_files_dev = ["requirements-dev.txt", "requirements-tests.txt"] ``` - CLI example: ```shell -deptry . --requirements-file-dev requirements-dev.txt,requirements-tests.txt +deptry . --requirements-files-dev requirements-dev.txt,requirements-tests.txt ``` #### Known first party diff --git a/python/deptry/cli.py b/python/deptry/cli.py index 9096c2cc..0ea607e8 100644 --- a/python/deptry/cli.py +++ b/python/deptry/cli.py @@ -193,7 +193,7 @@ def display_deptry_version(ctx: click.Context, _param: click.Parameter, value: b "--requirements-txt-dev", "-rtd", type=COMMA_SEPARATED_TUPLE, help="To be deprecated.", hidden=True, default=() ) @click.option( - "--requirements-file", + "--requirements-files", "-rf", type=COMMA_SEPARATED_TUPLE, help=""".txt files to scan for dependencies. If a file called pyproject.toml with a [tool.poetry.dependencies] or [project] section is found, this argument is ignored @@ -202,7 +202,7 @@ def display_deptry_version(ctx: click.Context, _param: click.Parameter, value: b show_default=True, ) @click.option( - "--requirements-file-dev", + "--requirements-files-dev", "-rfd", type=COMMA_SEPARATED_TUPLE, help=""".txt files to scan for additional development dependencies. If a file called pyproject.toml with a [tool.poetry.dependencies] or [project] section is found, this argument is ignored @@ -256,8 +256,8 @@ def deptry( ignore_notebooks: bool, requirements_txt: tuple[str, ...], requirements_txt_dev: tuple[str, ...], - requirements_file: tuple[str, ...], - requirements_file_dev: tuple[str, ...], + requirements_files: tuple[str, ...], + requirements_files_dev: tuple[str, ...], known_first_party: tuple[str, ...], json_output: str, package_module_name_map: MutableMapping[str, tuple[str, ...]], @@ -292,8 +292,8 @@ def deptry( ignore_notebooks=ignore_notebooks, ignore=ignore, per_rule_ignores=per_rule_ignores, - requirements_file=requirements_txt or requirements_file, - requirements_file_dev=requirements_txt_dev or requirements_file_dev, + requirements_files=requirements_txt or requirements_files, + requirements_files_dev=requirements_txt_dev or requirements_files_dev, known_first_party=known_first_party, json_output=json_output, package_module_name_map=package_module_name_map, diff --git a/python/deptry/core.py b/python/deptry/core.py index f4176208..45422cd8 100644 --- a/python/deptry/core.py +++ b/python/deptry/core.py @@ -9,7 +9,7 @@ from deptry.dependency_getter.pdm import PDMDependencyGetter from deptry.dependency_getter.pep_621 import PEP621DependencyGetter from deptry.dependency_getter.poetry import PoetryDependencyGetter -from deptry.dependency_getter.requirements_file import RequirementsTxtDependencyGetter +from deptry.dependency_getter.requirements_files import RequirementsTxtDependencyGetter from deptry.dependency_specification_detector import DependencyManagementFormat, DependencySpecificationDetector from deptry.exceptions import IncorrectDependencyFormatError, UnsupportedPythonVersionError from deptry.imports.extract import get_imported_modules_from_list_of_files @@ -48,8 +48,8 @@ class Core: extend_exclude: tuple[str, ...] using_default_exclude: bool ignore_notebooks: bool - requirements_file: tuple[str, ...] - requirements_file_dev: tuple[str, ...] + requirements_files: tuple[str, ...] + requirements_files_dev: tuple[str, ...] known_first_party: tuple[str, ...] json_output: str package_module_name_map: Mapping[str, tuple[str, ...]] @@ -59,7 +59,7 @@ def run(self) -> None: self._log_config() dependency_management_format = DependencySpecificationDetector( - self.config, requirements_file=self.requirements_file + self.config, requirements_files=self.requirements_files ).detect() dependencies_extract = self._get_dependencies(dependency_management_format) @@ -153,7 +153,7 @@ def _get_dependencies(self, dependency_management_format: DependencyManagementFo ).get() if dependency_management_format is DependencyManagementFormat.REQUIREMENTS_FILE: return RequirementsTxtDependencyGetter( - self.config, self.package_module_name_map, self.requirements_file, self.requirements_file_dev + self.config, self.package_module_name_map, self.requirements_files, self.requirements_files_dev ).get() raise IncorrectDependencyFormatError diff --git a/python/deptry/dependency_getter/requirements_file.py b/python/deptry/dependency_getter/requirements_files.py similarity index 84% rename from python/deptry/dependency_getter/requirements_file.py rename to python/deptry/dependency_getter/requirements_files.py index 87329bc4..7dcef476 100644 --- a/python/deptry/dependency_getter/requirements_file.py +++ b/python/deptry/dependency_getter/requirements_files.py @@ -16,37 +16,37 @@ class RequirementsTxtDependencyGetter(DependencyGetter): """Extract dependencies from requirements.txt files.""" - requirements_file: tuple[str, ...] = ("requirements.txt",) - requirements_file_dev: tuple[str, ...] = ("dev-requirements.txt", "requirements-dev.txt") + requirements_files: tuple[str, ...] = ("requirements.txt",) + requirements_files_dev: tuple[str, ...] = ("dev-requirements.txt", "requirements-dev.txt") def get(self) -> DependenciesExtract: dependencies = list( itertools.chain( - *(self._get_dependencies_from_requirements_file(file_name) for file_name in self.requirements_file) + *(self._get_dependencies_from_requirements_files(file_name) for file_name in self.requirements_files) ) ) dev_dependencies = list( itertools.chain( *( - self._get_dependencies_from_requirements_file(file_name) - for file_name in self._scan_for_dev_requirements_files() + self._get_dependencies_from_requirements_files(file_name) + for file_name in self._scan_for_dev_requirements_filess() ) ) ) return DependenciesExtract(dependencies, dev_dependencies) - def _scan_for_dev_requirements_files(self) -> list[str]: + def _scan_for_dev_requirements_filess(self) -> list[str]: """ - Check if any of the files passed as requirements_file_dev exist, and if so; return them. + Check if any of the files passed as requirements_files_dev exist, and if so; return them. """ - dev_requirements_files = [file_name for file_name in self.requirements_file_dev if file_name in os.listdir()] - if dev_requirements_files: - logging.debug("Found files with development requirements! %s", dev_requirements_files) - return dev_requirements_files + dev_requirements_filess = [file_name for file_name in self.requirements_files_dev if file_name in os.listdir()] + if dev_requirements_filess: + logging.debug("Found files with development requirements! %s", dev_requirements_filess) + return dev_requirements_filess - def _get_dependencies_from_requirements_file(self, file_name: str, is_dev: bool = False) -> list[Dependency]: + def _get_dependencies_from_requirements_files(self, file_name: str, is_dev: bool = False) -> list[Dependency]: logging.debug("Scanning %s for %s", file_name, "dev dependencies" if is_dev else "dependencies") dependencies = [] diff --git a/python/deptry/dependency_specification_detector.py b/python/deptry/dependency_specification_detector.py index ee03ec3d..0cd72d5f 100644 --- a/python/deptry/dependency_specification_detector.py +++ b/python/deptry/dependency_specification_detector.py @@ -12,7 +12,7 @@ class DependencyManagementFormat(Enum): PDM = "pdm" PEP_621 = "pep_621" POETRY = "poetry" - REQUIREMENTS_FILE = "requirements_file" + REQUIREMENTS_FILE = "requirements_files" class DependencySpecificationDetector: @@ -25,9 +25,9 @@ class DependencySpecificationDetector: """ - def __init__(self, config: Path, requirements_file: tuple[str, ...] = ("requirements.txt",)) -> None: + def __init__(self, config: Path, requirements_files: tuple[str, ...] = ("requirements.txt",)) -> None: self.config = config - self.requirements_file = requirements_file + self.requirements_files = requirements_files def detect(self) -> DependencyManagementFormat: pyproject_toml_found = self._project_contains_pyproject_toml() @@ -37,10 +37,10 @@ def detect(self) -> DependencyManagementFormat: return DependencyManagementFormat.PDM if pyproject_toml_found and self._project_uses_pep_621(): return DependencyManagementFormat.PEP_621 - if self._project_uses_requirements_file(): + if self._project_uses_requirements_files(): return DependencyManagementFormat.REQUIREMENTS_FILE - raise DependencySpecificationNotFoundError(self.requirements_file) + raise DependencySpecificationNotFoundError(self.requirements_files) def _project_contains_pyproject_toml(self) -> bool: if self.config.exists(): @@ -100,11 +100,11 @@ def _project_uses_pep_621(self) -> bool: else: return True - def _project_uses_requirements_file(self) -> bool: - check = any(Path(requirements_file).is_file() for requirements_file in self.requirements_file) + def _project_uses_requirements_files(self) -> bool: + check = any(Path(requirements_files).is_file() for requirements_files in self.requirements_files) if check: logging.debug( "Dependency specification found in '%s'. Will use this to determine the project's dependencies.\n", - ", ".join(self.requirements_file), + ", ".join(self.requirements_files), ) return check diff --git a/python/deptry/deprecate/requirements_txt.py b/python/deptry/deprecate/requirements_txt.py index a551db9c..2a4c69cc 100644 --- a/python/deptry/deprecate/requirements_txt.py +++ b/python/deptry/deprecate/requirements_txt.py @@ -3,13 +3,13 @@ REQUIREMENTS_TXT_DEPRECATION_MESSAGE = ( "Warning: In an upcoming release, support for the `--requirements-txt` command-line " "option and the `requirements_txt` configuration parameter will be discontinued. " - "Instead, use `--requirements-file` or `requirements_file` under the `[tool.deptry]` " + "Instead, use `--requirements-files` or `requirements_files` under the `[tool.deptry]` " "section in pyproject.toml." ) REQUIREMENTS_TXT_DEV_DEPRECATION_MESSAGE = ( "Warning: In an upcoming release, support for the `--requirements-txt-dev` command-line " "option and the `requirements_txt_dev` configuration parameter will be discontinued. " - "Instead, use `--requirements-file-dev` or `requirements_file_dev` under the `[tool.deptry]` " + "Instead, use `--requirements-files-dev` or `requirements_files_dev` under the `[tool.deptry]` " "section in pyproject.toml." ) diff --git a/python/deptry/exceptions.py b/python/deptry/exceptions.py index 5dc17daa..2dc2428f 100644 --- a/python/deptry/exceptions.py +++ b/python/deptry/exceptions.py @@ -9,10 +9,10 @@ class DependencySpecificationNotFoundError(FileNotFoundError): - def __init__(self, requirements_file: tuple[str, ...]) -> None: + def __init__(self, requirements_files: tuple[str, ...]) -> None: super().__init__( "No file called 'pyproject.toml' with a [tool.poetry.dependencies], [tool.pdm] or [project] section or" - f" file(s) called '{', '.join(requirements_file)}' found. Exiting." + f" file(s) called '{', '.join(requirements_files)}' found. Exiting." ) diff --git a/tests/functional/cli/test_cli_requirements_txt.py b/tests/functional/cli/test_cli_requirements_txt.py index 387d0fc1..28f3fbc0 100644 --- a/tests/functional/cli/test_cli_requirements_txt.py +++ b/tests/functional/cli/test_cli_requirements_txt.py @@ -14,7 +14,7 @@ @pytest.mark.xdist_group(name=Project.REQUIREMENTS_TXT) -def test_cli_single_requirements_file(pip_venv_factory: PipVenvFactory) -> None: +def test_cli_single_requirements_files(pip_venv_factory: PipVenvFactory) -> None: with pip_venv_factory( Project.REQUIREMENTS_TXT, install_command=( @@ -23,7 +23,7 @@ def test_cli_single_requirements_file(pip_venv_factory: PipVenvFactory) -> None: ) as virtual_env: issue_report = f"{uuid.uuid4()}.json" result = virtual_env.run( - "deptry . --requirements-file requirements.txt --requirements-file-dev requirements-dev.txt -o" + "deptry . --requirements-files requirements.txt --requirements-files-dev requirements-dev.txt -o" f" {issue_report}" ) @@ -105,7 +105,7 @@ def test_cli_single_requirements_file(pip_venv_factory: PipVenvFactory) -> None: @pytest.mark.xdist_group(name=Project.REQUIREMENTS_TXT) -def test_cli_multiple_requirements_file(pip_venv_factory: PipVenvFactory) -> None: +def test_cli_multiple_requirements_files(pip_venv_factory: PipVenvFactory) -> None: with pip_venv_factory( Project.REQUIREMENTS_TXT, install_command=( @@ -114,7 +114,7 @@ def test_cli_multiple_requirements_file(pip_venv_factory: PipVenvFactory) -> Non ) as virtual_env: issue_report = f"{uuid.uuid4()}.json" result = virtual_env.run( - "deptry . --requirements-file requirements.txt,requirements-2.txt --requirements-file-dev" + "deptry . --requirements-files requirements.txt,requirements-2.txt --requirements-files-dev" f" requirements-dev.txt -o {issue_report}" ) diff --git a/tests/unit/dependency_getter/test_requirements_txt.py b/tests/unit/dependency_getter/test_requirements_txt.py index 6094fd4a..c2cbb0b0 100644 --- a/tests/unit/dependency_getter/test_requirements_txt.py +++ b/tests/unit/dependency_getter/test_requirements_txt.py @@ -4,12 +4,12 @@ import pytest -from deptry.dependency_getter.requirements_file import RequirementsTxtDependencyGetter +from deptry.dependency_getter.requirements_files import RequirementsTxtDependencyGetter from tests.utils import run_within_dir -def test_parse_requirements_file(tmp_path: Path) -> None: - fake_requirements_file = """click==8.1.3 #123asd +def test_parse_requirements_files(tmp_path: Path) -> None: + fake_requirements_files = """click==8.1.3 #123asd colorama==0.4.5 importlib-metadata==4.2.0 ; python_version >= "3.7" and python_version < "3.8" isort==5.10.1, <6.0 @@ -33,7 +33,7 @@ def test_parse_requirements_file(tmp_path: Path) -> None: """ with run_within_dir(tmp_path): with Path("requirements.txt").open("w") as f: - f.write(fake_requirements_file) + f.write(fake_requirements_files) getter = RequirementsTxtDependencyGetter( config=Path("pyproject.toml"), @@ -66,8 +66,8 @@ def test_parse_requirements_file(tmp_path: Path) -> None: assert "fox" in dependencies[17].top_levels -def test_parse_requirements_file_urls(tmp_path: Path) -> None: - fake_requirements_file = """urllib3 @ https://github.com/urllib3/urllib3/archive/refs/tags/1.26.8.zip +def test_parse_requirements_files_urls(tmp_path: Path) -> None: + fake_requirements_files = """urllib3 @ https://github.com/urllib3/urllib3/archive/refs/tags/1.26.8.zip https://github.com/urllib3/urllib3/archive/refs/tags/1.26.8.zip git+https://github.com/baz/foo-bar.git@asd#egg=foo-bar git+https://github.com/baz/foo-bar.git@asd @@ -75,7 +75,7 @@ def test_parse_requirements_file_urls(tmp_path: Path) -> None: with run_within_dir(tmp_path): with Path("requirements.txt").open("w") as f: - f.write(fake_requirements_file) + f.write(fake_requirements_files) dependencies_extract = RequirementsTxtDependencyGetter(Path("pyproject.toml")).get() dependencies = dependencies_extract.dependencies @@ -96,7 +96,7 @@ def test_single(tmp_path: Path) -> None: f.write("click==8.1.3 #123asd\ncolorama==0.4.5") dependencies_extract = RequirementsTxtDependencyGetter( - Path("pyproject.toml"), requirements_file=("req.txt",) + Path("pyproject.toml"), requirements_files=("req.txt",) ).get() dependencies = dependencies_extract.dependencies @@ -116,7 +116,7 @@ def test_multiple(tmp_path: Path) -> None: f.write("bar") dependencies_extract = RequirementsTxtDependencyGetter( - Path("pyproject.toml"), requirements_file=("foo.txt", "bar.txt") + Path("pyproject.toml"), requirements_files=("foo.txt", "bar.txt") ).get() dependencies = dependencies_extract.dependencies @@ -180,7 +180,7 @@ def test_dev_multiple_with_arguments(tmp_path: Path) -> None: f.write("bar") dependencies_extract = RequirementsTxtDependencyGetter( - Path("pyproject.toml"), requirements_file_dev=("foo.txt", "bar.txt") + Path("pyproject.toml"), requirements_files_dev=("foo.txt", "bar.txt") ).get() dev_dependencies = dependencies_extract.dev_dependencies diff --git a/tests/unit/deprecate/test_requirements_txt.py b/tests/unit/deprecate/test_requirements_txt.py index b9535693..6b9920bb 100644 --- a/tests/unit/deprecate/test_requirements_txt.py +++ b/tests/unit/deprecate/test_requirements_txt.py @@ -37,8 +37,8 @@ def test_requirements_txt_deprecated() -> None: # Assert that Core was instantiated with the correct arguments mock_core.assert_called_once_with( **DEFAULT_CORE_ARGS, - requirements_file=("somefile.txt",), - requirements_file_dev=("dev-requirements.txt", "requirements-dev.txt"), + requirements_files=("somefile.txt",), + requirements_files_dev=("dev-requirements.txt", "requirements-dev.txt"), ) @@ -51,13 +51,13 @@ def test_requirements_txt_dev_deprecated() -> None: # Assert that Core was instantiated with the correct arguments mock_core.assert_called_once_with( - **DEFAULT_CORE_ARGS, requirements_file=("requirements.txt",), requirements_file_dev=("somefile.txt",) + **DEFAULT_CORE_ARGS, requirements_files=("requirements.txt",), requirements_files_dev=("somefile.txt",) ) -def test_requirements_file_works_as_expected() -> None: +def test_requirements_files_works_as_expected() -> None: with patch("deptry.cli.Core") as mock_core, patch("logging.warning") as mock_warning: - result = CliRunner().invoke(deptry, [".", "--requirements-file", "somefile.txt"]) + result = CliRunner().invoke(deptry, [".", "--requirements-files", "somefile.txt"]) assert result.exit_code == 0 mock_warning.assert_not_called() @@ -65,19 +65,19 @@ def test_requirements_file_works_as_expected() -> None: # Assert that Core was instantiated with the correct arguments mock_core.assert_called_once_with( **DEFAULT_CORE_ARGS, - requirements_file=("somefile.txt",), - requirements_file_dev=("dev-requirements.txt", "requirements-dev.txt"), + requirements_files=("somefile.txt",), + requirements_files_dev=("dev-requirements.txt", "requirements-dev.txt"), ) -def test_requirements_file_dev_works_as_expected() -> None: +def test_requirements_files_dev_works_as_expected() -> None: with patch("deptry.cli.Core") as mock_core, patch("logging.warning") as mock_warning: - result = CliRunner().invoke(deptry, [".", "--requirements-file-dev", "somefile.txt"]) + result = CliRunner().invoke(deptry, [".", "--requirements-files-dev", "somefile.txt"]) assert result.exit_code == 0 mock_warning.assert_not_called() # Assert that Core was instantiated with the correct arguments mock_core.assert_called_once_with( - **DEFAULT_CORE_ARGS, requirements_file=("requirements.txt",), requirements_file_dev=("somefile.txt",) + **DEFAULT_CORE_ARGS, requirements_files=("requirements.txt",), requirements_files_dev=("somefile.txt",) ) diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index 0e70b8da..0d06b217 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -24,8 +24,8 @@ Argument(param_decls=["per_rule_ignores"]), Argument(param_decls=["ignore"]), Argument(param_decls=["ignore_notebooks"]), - Argument(param_decls=["requirements_file"]), - Argument(param_decls=["requirements_file_dev"]), + Argument(param_decls=["requirements_files"]), + Argument(param_decls=["requirements_files_dev"]), ], ) @@ -40,8 +40,8 @@ def test_read_configuration_from_pyproject_toml_exists(tmp_path: Path) -> None: "DEP002": ["baz", "bar"], }, "ignore": [], - "requirements_file": "requirements.txt", - "requirements_file_dev": ["requirements-dev.txt"], + "requirements_files": "requirements.txt", + "requirements_files_dev": ["requirements-dev.txt"], }, ) @@ -51,8 +51,8 @@ def test_read_configuration_from_pyproject_toml_exists(tmp_path: Path) -> None: extend_exclude = ["bar", "foo"] ignore_notebooks = true ignore = ["DEP001", "DEP002", "DEP003", "DEP004"] - requirements_file = "foo.txt" - requirements_file_dev = ["dev.txt", "tests.txt"] + requirements_files = "foo.txt" + requirements_files_dev = ["dev.txt", "tests.txt"] [tool.deptry.per_rule_ignores] DEP001 = ["baz", "foobar"] @@ -83,8 +83,8 @@ def test_read_configuration_from_pyproject_toml_exists(tmp_path: Path) -> None: "DEP004": ["barfoo"], }, "ignore": ["DEP001", "DEP002", "DEP003", "DEP004"], - "requirements_file": "foo.txt", - "requirements_file_dev": ["dev.txt", "tests.txt"], + "requirements_files": "foo.txt", + "requirements_files_dev": ["dev.txt", "tests.txt"], } diff --git a/tests/unit/test_core.py b/tests/unit/test_core.py index ee41dbce..e05d6eea 100644 --- a/tests/unit/test_core.py +++ b/tests/unit/test_core.py @@ -88,8 +88,8 @@ def test__get_local_modules( extend_exclude=(), using_default_exclude=True, ignore_notebooks=False, - requirements_file=(), - requirements_file_dev=(), + requirements_files=(), + requirements_files_dev=(), known_first_party=known_first_party, json_output="", package_module_name_map={}, diff --git a/tests/unit/test_dependency_specification_detector.py b/tests/unit/test_dependency_specification_detector.py index f21d6662..648f019b 100644 --- a/tests/unit/test_dependency_specification_detector.py +++ b/tests/unit/test_dependency_specification_detector.py @@ -21,7 +21,7 @@ def test_poetry(tmp_path: Path) -> None: assert spec == DependencyManagementFormat.POETRY -def test_requirements_file(tmp_path: Path) -> None: +def test_requirements_files(tmp_path: Path) -> None: with run_within_dir(tmp_path): with Path("requirements.txt").open("w") as f: f.write('foo >= "1.0"') @@ -84,23 +84,23 @@ def test_both(tmp_path: Path) -> None: assert spec == DependencyManagementFormat.POETRY -def test_requirements_file_with_argument(tmp_path: Path) -> None: +def test_requirements_files_with_argument(tmp_path: Path) -> None: with run_within_dir(tmp_path): with Path("req.txt").open("w") as f: f.write('foo >= "1.0"') - spec = DependencySpecificationDetector(Path("pyproject.toml"), requirements_file=("req.txt",)).detect() + spec = DependencySpecificationDetector(Path("pyproject.toml"), requirements_files=("req.txt",)).detect() assert spec == DependencyManagementFormat.REQUIREMENTS_FILE -def test_requirements_file_with_argument_not_root_directory(tmp_path: Path) -> None: +def test_requirements_files_with_argument_not_root_directory(tmp_path: Path) -> None: with run_within_dir(tmp_path): Path("req").mkdir() with Path("req/req.txt").open("w") as f: f.write('foo >= "1.0"') - spec = DependencySpecificationDetector(Path("pyproject.toml"), requirements_file=("req/req.txt",)).detect() + spec = DependencySpecificationDetector(Path("pyproject.toml"), requirements_files=("req/req.txt",)).detect() assert spec == DependencyManagementFormat.REQUIREMENTS_FILE @@ -112,4 +112,4 @@ def test_dependency_specification_not_found_raises_exception(tmp_path: Path) -> " file(s) called 'req/req.txt' found. Exiting." ), ): - DependencySpecificationDetector(Path("pyproject.toml"), requirements_file=("req/req.txt",)).detect() + DependencySpecificationDetector(Path("pyproject.toml"), requirements_files=("req/req.txt",)).detect() From c93d6d130077b81ab77f7c03028787372a27413f Mon Sep 17 00:00:00 2001 From: Florian Maas Date: Sun, 24 Mar 2024 10:13:02 +0100 Subject: [PATCH 11/12] fix replacement error --- docs/usage.md | 4 ++-- .../deptry/dependency_getter/requirements_files.py | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index edfa8cfa..617228fb 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -230,7 +230,7 @@ deptry . --ignore-notebooks #### Requirements files -List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-filess) that contain the source dependencies. +List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-files) that contain the source dependencies. - Type: `list[str]` - Default: `["requirements.txt"]` @@ -248,7 +248,7 @@ deptry . --requirements-files requirements.txt,requirements-private.txt #### Requirements files dev -List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-filess) that contain the source development dependencies. +List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-files) that contain the source development dependencies. - Type: `list[str]` - Default: `["dev-requirements.txt", "requirements-dev.txt"]` diff --git a/python/deptry/dependency_getter/requirements_files.py b/python/deptry/dependency_getter/requirements_files.py index 7dcef476..b0f1099d 100644 --- a/python/deptry/dependency_getter/requirements_files.py +++ b/python/deptry/dependency_getter/requirements_files.py @@ -30,21 +30,21 @@ def get(self) -> DependenciesExtract: itertools.chain( *( self._get_dependencies_from_requirements_files(file_name) - for file_name in self._scan_for_dev_requirements_filess() + for file_name in self._scan_for_dev_requirements_files() ) ) ) return DependenciesExtract(dependencies, dev_dependencies) - def _scan_for_dev_requirements_filess(self) -> list[str]: + def _scan_for_dev_requirements_files(self) -> list[str]: """ Check if any of the files passed as requirements_files_dev exist, and if so; return them. """ - dev_requirements_filess = [file_name for file_name in self.requirements_files_dev if file_name in os.listdir()] - if dev_requirements_filess: - logging.debug("Found files with development requirements! %s", dev_requirements_filess) - return dev_requirements_filess + dev_requirements_files = [file_name for file_name in self.requirements_files_dev if file_name in os.listdir()] + if dev_requirements_files: + logging.debug("Found files with development requirements! %s", dev_requirements_files) + return dev_requirements_files def _get_dependencies_from_requirements_files(self, file_name: str, is_dev: bool = False) -> list[Dependency]: logging.debug("Scanning %s for %s", file_name, "dev dependencies" if is_dev else "dependencies") From fdc835718f39f2409b161fa51d7b7e416f55079f Mon Sep 17 00:00:00 2001 From: Florian Maas Date: Sun, 24 Mar 2024 10:13:27 +0100 Subject: [PATCH 12/12] Update docs/usage.md Co-authored-by: Mathieu Kniewallner --- docs/usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/usage.md b/docs/usage.md index 617228fb..263edc12 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -36,7 +36,7 @@ To determine the project's dependencies, _deptry_ will scan the directory it is - development dependencies from `dev-dependencies.txt` and `dependencies-dev.txt`, if any exist _deptry_ can be configured to look for `pip` requirements files with other names or in other directories. -See [Requirements file](#requirements-files) and [Requirements file dev](#requirements-files-dev). +See [Requirements files](#requirements-files) and [Requirements files dev](#requirements-files-dev). ## Excluding files and directories