diff --git a/deptry/cli.py b/deptry/cli.py index 91b8bcab..0d395607 100644 --- a/deptry/cli.py +++ b/deptry/cli.py @@ -11,10 +11,11 @@ from deptry.config import read_configuration_from_pyproject_toml from deptry.core import Core -from deptry.deprecate_obsolete import get_value_for_ignore_unused, get_value_for_skip_unused +from deptry.deprecate.ignore_flags import get_value_for_per_rule_ignores_argument +from deptry.deprecate.skip_flags import get_value_for_ignore_argument if TYPE_CHECKING: - from collections.abc import Mapping, Sequence + from collections.abc import MutableMapping, Sequence if sys.platform == "win32": from colorama import just_fix_windows_console @@ -64,7 +65,7 @@ def convert( self, # In the mapping value below, although a str is a Sequence[str] itself, # they are treated differently from other sequences of str. - value: str | Mapping[str, Sequence[str] | str], + value: str | MutableMapping[str, Sequence[str] | str], param: click.Parameter | None, ctx: click.Context | None, ) -> dict[str, tuple[str, ...]]: @@ -135,64 +136,77 @@ def display_deptry_version(ctx: click.Context, _param: click.Parameter, value: b @click.option( "--skip-unused", is_flag=True, - help="Boolean flag to specify if deptry should skip scanning the project for unused dependencies.", + help="To be deprecated.", + hidden=True, ) @click.option( "--skip-missing", is_flag=True, - help="Boolean flag to specify if deptry should skip scanning the project for missing dependencies.", + help="To be deprecated.", + hidden=True, ) @click.option( "--skip-transitive", is_flag=True, - help="Boolean flag to specify if deptry should skip scanning the project for transitive dependencies.", + help="To be deprecated.", + hidden=True, ) @click.option( "--skip-misplaced-dev", is_flag=True, - help=( - "Boolean flag to specify if deptry should skip scanning the project for development dependencies that should be" - " regular dependencies." - ), + help="To be deprecated.", + hidden=True, ) -@click.option("--ignore-obsolete", "-io", type=COMMA_SEPARATED_TUPLE, default=(), hidden=True) +@click.option("--ignore-obsolete", "-io", help="To be deprecated.", type=COMMA_SEPARATED_TUPLE, default=(), hidden=True) @click.option( "--ignore-unused", "-iu", type=COMMA_SEPARATED_TUPLE, - help=""" - Comma-separated list of dependencies that should never be marked as unused, even if they are not imported in any of the files scanned. - For example; `deptry . --ignore-unused foo,bar`. - """, + hidden=True, + help="To be deprecated.", default=(), ) @click.option( "--ignore-missing", "-im", type=COMMA_SEPARATED_TUPLE, - help="""Comma-separated list of modules that should never be marked as missing dependencies, even if the matching package for the import statement cannot be found. - For example; `deptry . --ignore-missing foo,bar`. - """, + hidden=True, + help="To be deprecated.", default=(), ) @click.option( "--ignore-transitive", "-it", type=COMMA_SEPARATED_TUPLE, - help="""Comma-separated list of dependencies that should never be marked as an issue due to it being a transitive dependency, even though deptry determines them to be transitive. - For example; `deptry . --ignore-transitive foo,bar`. - """, + hidden=True, + help="To be deprecated.", default=(), ) @click.option( "--ignore-misplaced-dev", "-id", type=COMMA_SEPARATED_TUPLE, - help="""Comma-separated list of modules that should never be marked as a misplaced development dependency, even though it seems to not be used solely for development purposes. - For example; `deptry . --ignore-misplaced-dev foo,bar`. - """, + hidden=True, + help="To be deprecated.", + default=(), +) +@click.option( + "--ignore", + "-i", + type=COMMA_SEPARATED_TUPLE, + help="""A comma-separated list of error codes to ignore. e.g. `deptry --ignore DEP001,DEP002` + For more information regarding the error codes, see https://fpgmaas.github.io/deptry/issue-codes/""", default=(), ) +@click.option( + "--per-rule-ignores", + "-pri", + type=COMMA_SEPARATED_MAPPING, + help="""A comma-separated mapping of packages or modules to be ignored per error code. + . e.g. ``deptry . --per-rule-ignores DEP001=matplotlib,DEP002=pandas|numpy`` + For more information regarding the error codes, see https://fpgmaas.github.io/deptry/issue-codes/""", + default={}, +) @click.option( "--exclude", "-e", @@ -284,6 +298,8 @@ def deptry( skip_missing: bool, skip_transitive: bool, skip_misplaced_dev: bool, + ignore: tuple[str, ...], + per_rule_ignores: MutableMapping[str, tuple[str, ...]], exclude: tuple[str, ...], extend_exclude: tuple[str, ...], ignore_notebooks: bool, @@ -291,7 +307,7 @@ def deptry( requirements_txt_dev: tuple[str, ...], known_first_party: tuple[str, ...], json_output: str, - package_module_name_map: Mapping[str, Sequence[str]], + package_module_name_map: MutableMapping[str, tuple[str, ...]], ) -> None: """Find dependency issues in your Python project. @@ -306,23 +322,32 @@ def deptry( deptry src worker """ - + ignore = get_value_for_ignore_argument( + ignore, + skip_missing=skip_missing, + skip_obsolete=skip_obsolete, + skip_unused=skip_unused, + skip_transitive=skip_transitive, + skip_misplaced_dev=skip_misplaced_dev, + ) + per_rule_ignores = get_value_for_per_rule_ignores_argument( + per_rule_ignores=per_rule_ignores, + ignore_missing=ignore_missing, + ignore_obsolete=ignore_obsolete, + ignore_unused=ignore_unused, + ignore_misplaced_dev=ignore_misplaced_dev, + ignore_transitive=ignore_transitive, + ) Core( root=root, config=config, no_ansi=no_ansi, - ignore_unused=get_value_for_ignore_unused(ignore_obsolete=ignore_obsolete, ignore_unused=ignore_unused), - ignore_missing=ignore_missing, - ignore_transitive=ignore_transitive, - ignore_misplaced_dev=ignore_misplaced_dev, exclude=exclude or DEFAULT_EXCLUDE, extend_exclude=extend_exclude, using_default_exclude=not exclude, ignore_notebooks=ignore_notebooks, - skip_unused=get_value_for_skip_unused(skip_obsolete=skip_obsolete, skip_unused=skip_unused), - skip_missing=skip_missing, - skip_transitive=skip_transitive, - skip_misplaced_dev=skip_misplaced_dev, + ignore=ignore, + per_rule_ignores=per_rule_ignores, requirements_txt=requirements_txt, requirements_txt_dev=requirements_txt_dev, known_first_party=known_first_party, diff --git a/deptry/core.py b/deptry/core.py index 1509896f..9d454815 100644 --- a/deptry/core.py +++ b/deptry/core.py @@ -19,13 +19,17 @@ from deptry.stdlibs import STDLIBS_PYTHON from deptry.violations import ( DEP001MissingDependenciesFinder, + DEP001MissingDependencyViolation, DEP002UnusedDependenciesFinder, + DEP002UnusedDependencyViolation, DEP003TransitiveDependenciesFinder, + DEP003TransitiveDependencyViolation, + DEP004MisplacedDevDependenciesFinder, + DEP004MisplacedDevDependencyViolation, ) -from deptry.violations.dep004_misplaced_dev.finder import DEP004MisplacedDevDependenciesFinder if TYPE_CHECKING: - from collections.abc import Mapping, Sequence + from collections.abc import Mapping from pathlib import Path from deptry.dependency import Dependency @@ -38,14 +42,8 @@ class Core: root: tuple[Path, ...] config: Path no_ansi: bool - ignore_unused: tuple[str, ...] - ignore_missing: tuple[str, ...] - ignore_transitive: tuple[str, ...] - ignore_misplaced_dev: tuple[str, ...] - skip_unused: bool - skip_missing: bool - skip_transitive: bool - skip_misplaced_dev: bool + per_rule_ignores: Mapping[str, tuple[str, ...]] + ignore: tuple[str, ...] exclude: tuple[str, ...] extend_exclude: tuple[str, ...] using_default_exclude: bool @@ -54,7 +52,7 @@ class Core: requirements_txt_dev: tuple[str, ...] known_first_party: tuple[str, ...] json_output: str - package_module_name_map: Mapping[str, Sequence[str]] + package_module_name_map: Mapping[str, tuple[str, ...]] def run(self) -> None: self._log_config() @@ -103,29 +101,31 @@ def _find_violations( ) -> list[Violation]: violations = [] - if not self.skip_unused: + if DEP001MissingDependencyViolation.error_code not in self.ignore: violations.extend( - DEP002UnusedDependenciesFinder(imported_modules_with_locations, dependencies, self.ignore_unused).find() + DEP001MissingDependenciesFinder( + imported_modules_with_locations, dependencies, self.per_rule_ignores.get("DEP001", ()) + ).find() ) - if not self.skip_missing: + if DEP002UnusedDependencyViolation.error_code not in self.ignore: violations.extend( - DEP001MissingDependenciesFinder( - imported_modules_with_locations, dependencies, self.ignore_missing + DEP002UnusedDependenciesFinder( + imported_modules_with_locations, dependencies, self.per_rule_ignores.get("DEP002", ()) ).find() ) - if not self.skip_transitive: + if DEP003TransitiveDependencyViolation.error_code not in self.ignore: violations.extend( DEP003TransitiveDependenciesFinder( - imported_modules_with_locations, dependencies, self.ignore_transitive + imported_modules_with_locations, dependencies, self.per_rule_ignores.get("DEP003", ()) ).find() ) - if not self.skip_misplaced_dev: + if DEP004MisplacedDevDependencyViolation.error_code not in self.ignore: violations.extend( DEP004MisplacedDevDependenciesFinder( - imported_modules_with_locations, dependencies, self.ignore_misplaced_dev + imported_modules_with_locations, dependencies, self.per_rule_ignores.get("DEP004", ()) ).find() ) diff --git a/deptry/deprecate/ignore_flags.py b/deptry/deprecate/ignore_flags.py new file mode 100644 index 00000000..46d2bf75 --- /dev/null +++ b/deptry/deprecate/ignore_flags.py @@ -0,0 +1,74 @@ +from __future__ import annotations + +import logging +from typing import TYPE_CHECKING + +from deptry.violations import ( + DEP001MissingDependencyViolation, + DEP002UnusedDependencyViolation, + DEP003TransitiveDependencyViolation, + DEP004MisplacedDevDependencyViolation, +) + +if TYPE_CHECKING: + from collections.abc import MutableMapping + + +def generate_deprecation_warning(flag_name: str, issue_code: str, sequence: tuple[str, ...]) -> str: + sequence_as_list_string = "[" + ", ".join(f'"{x}"' for x in sequence) + "]" + return ( + f"Warning: In an upcoming release, support for the `--{flag_name}` command-line option and the" + f" `{flag_name.replace('-','_')}` configuration parameter will be discontinued. Instead, use" + f" `--per-rule-ignores {issue_code}={'|'.join(sequence)}` or add a line `{issue_code} =" + f" {sequence_as_list_string}` to the `[tool.deptry.per_rule_ignores]` section of the configuration file." + ) + + +def get_value_for_per_rule_ignores_argument( + per_rule_ignores: MutableMapping[str, tuple[str, ...]], + ignore_obsolete: tuple[str, ...], + ignore_unused: tuple[str, ...], + ignore_missing: tuple[str, ...], + ignore_transitive: tuple[str, ...], + ignore_misplaced_dev: tuple[str, ...], +) -> MutableMapping[str, tuple[str, ...]]: + """ + This function is designed to help with the transition from deprecated command-line flags to the new `--per-rule-ignores` flag. + The deprecated flags that are replaced by this new flag are: + + - `--ignore-obsolete` + - `--ignore-unused` + - `--ignore-missing` + - `--ignore-transitive` + - `--ignore-misplaced-dev` + + This function accepts the values for the deprecated flags and updates the `per_rule_ignores` mapping accordingly. + + Raise a warning if one of the to-be-deprecated flags is used. + """ + user_values = { + "ignore-missing": ignore_missing, + "ignore-unused": ignore_unused, + "ignore-obsolete": ignore_obsolete, + "ignore-transitive": ignore_transitive, + "ignore-misplaced-dev": ignore_misplaced_dev, + } + + issue_codes = { + "ignore-missing": DEP001MissingDependencyViolation.error_code, + "ignore-unused": DEP002UnusedDependencyViolation.error_code, + "ignore-obsolete": DEP002UnusedDependencyViolation.error_code, + "ignore-transitive": DEP003TransitiveDependencyViolation.error_code, + "ignore-misplaced-dev": DEP004MisplacedDevDependencyViolation.error_code, + } + + for flag, modules_or_dependencies_to_be_ignored in user_values.items(): + if modules_or_dependencies_to_be_ignored: + code = issue_codes[flag] + logging.warning(generate_deprecation_warning(flag, code, modules_or_dependencies_to_be_ignored)) + if code not in per_rule_ignores.keys(): + per_rule_ignores[code] = modules_or_dependencies_to_be_ignored + else: + per_rule_ignores[code] = tuple(set(per_rule_ignores[code]).union(modules_or_dependencies_to_be_ignored)) + + return per_rule_ignores diff --git a/deptry/deprecate/skip_flags.py b/deptry/deprecate/skip_flags.py new file mode 100644 index 00000000..932df660 --- /dev/null +++ b/deptry/deprecate/skip_flags.py @@ -0,0 +1,67 @@ +from __future__ import annotations + +import logging + +from deptry.violations import ( + DEP001MissingDependencyViolation, + DEP002UnusedDependencyViolation, + DEP003TransitiveDependencyViolation, + DEP004MisplacedDevDependencyViolation, +) + + +def generate_deprecation_warning(flag_name: str, issue_code: str) -> str: + return ( + f"Warning: In an upcoming release, support for the `--{flag_name}` command-line option and the" + f" `{flag_name.replace('-','_')}` configuration parameter will be discontinued. Instead, use `--ignore" + f" {issue_code}` or add a line `ignore = ['{issue_code}']` to the `[tool.deptry]` section of the configuration" + " file." + ) + + +def get_value_for_ignore_argument( + ignore: tuple[str, ...], + skip_obsolete: bool, + skip_unused: bool, + skip_missing: bool, + skip_transitive: bool, + skip_misplaced_dev: bool, +) -> tuple[str, ...]: + """ + This function is designed to help with the transition from deprecated command-line flags to the new `--ignore` flag. + The deprecated flags that are replaced by this new flag are: + + - `--skip-obsolete` + - `--skip-unused` + - `--skip-missing` + - `--skip-transitive` + - `--skip-misplaced-dev` + + This function accepts the values for the deprecated flags and updates the `ignore` parameter accordingly. + + Raise a warning if one of the to-be-deprecated flags is used. + """ + user_values = { + "skip-missing": skip_missing, + "skip-unused": skip_unused, + "skip-obsolete": skip_obsolete, + "skip-transitive": skip_transitive, + "skip-misplaced-dev": skip_misplaced_dev, + } + + issue_codes = { + "skip-missing": DEP001MissingDependencyViolation.error_code, + "skip-unused": DEP002UnusedDependencyViolation.error_code, + "skip-obsolete": DEP002UnusedDependencyViolation.error_code, + "skip-transitive": DEP003TransitiveDependencyViolation.error_code, + "skip-misplaced-dev": DEP004MisplacedDevDependencyViolation.error_code, + } + + for flag, should_skip in user_values.items(): + if should_skip: + code = issue_codes[flag] + logging.warning(generate_deprecation_warning(flag, code)) + if code not in ignore: + ignore += (code,) + + return ignore diff --git a/deptry/deprecate_obsolete.py b/deptry/deprecate_obsolete.py deleted file mode 100644 index 3f4dc607..00000000 --- a/deptry/deprecate_obsolete.py +++ /dev/null @@ -1,53 +0,0 @@ -from __future__ import annotations - -import logging - -SKIP_OBSOLETE_WARNING = ( - "Warning: In an upcoming release, support for the `--skip-obsolete` command-line option and the `skip_obsolete`" - " configuration parameter will be discontinued. Instead, use the `--skip-unused` option or the `skip_unused`" - " configuration parameter to achieve the desired behavior." -) -IGNORE_OBSOLETE_WARNING = ( - "Warning: In an upcoming release, support for the `--ignore-obsolete` command-line option and the `ignore_obsolete`" - " configuration parameter will be discontinued. Instead, use the `--ignore-unused` option or the `ignore_unused`" - " configuration parameter to achieve the desired behavior." -) -SKIP_OBSOLETE_AND_SKIP_UNUSED_ERROR_MESSAGE = ( - "Both `skip_obsolete` and `skip_unused` options are set, either in pyproject.toml or through their corresponding" - " CLI arguments. Please use only the `skip_unused` option, as `skip_obsolete` will be deprecated in the future." -) -IGNORE_OBSOLETE_AND_IGNORE_UNUSED_ERROR_MESSAGE = ( - "Both `ignore_obsolete` and `ignore_unused` options are set, either in pyproject.toml or through their" - " corresponding CLI arguments. Please use only the `ignore_unused` option, as `ignore_obsolete` will be deprecated" - " in the future." -) - - -def get_value_for_skip_unused(skip_obsolete: bool, skip_unused: bool) -> bool: - """ - The skip_obsolete argument will be deprecated in the future, users should use skip_unused instead. - If only skip_obsolete is defined, display a warning message. If both skip_obsolete and skip_unused are defined, - raise an Error. - """ - if skip_obsolete: - logging.warning(SKIP_OBSOLETE_WARNING) - if skip_unused: - raise ValueError(SKIP_OBSOLETE_AND_SKIP_UNUSED_ERROR_MESSAGE) - else: - return skip_obsolete - return skip_unused - - -def get_value_for_ignore_unused(ignore_obsolete: tuple[str, ...], ignore_unused: tuple[str, ...]) -> tuple[str, ...]: - """ - The ignore_obsolete argument will be deprecated in the future, users should use ignore_unused instead. - If only ignore_obsolete is defined, display a warning message. If both ignore_obsolete and ignore_unused are defined, - raise an Error. - """ - if ignore_obsolete: - logging.warning(IGNORE_OBSOLETE_WARNING) - if ignore_unused: - raise ValueError(IGNORE_OBSOLETE_AND_IGNORE_UNUSED_ERROR_MESSAGE) - else: - return ignore_obsolete - return ignore_unused diff --git a/docs/violations-detection.md b/docs/rules-violations.md similarity index 75% rename from docs/violations-detection.md rename to docs/rules-violations.md index 0dd8ab14..c965a889 100644 --- a/docs/violations-detection.md +++ b/docs/rules-violations.md @@ -1,22 +1,21 @@ -# Violations detection +# Rules & Violations -_deptry_ looks for violations of the following rules in dependencies: +_deptry_ checks your project against the following rules related to dependencies: -- [Missing dependencies (DEP001)](#missing-dependencies-dep001) -- [Unused dependencies (DEP002)](#unused-dependencies-dep002) -- [Transitive dependencies (DEP003)](#transitive-dependencies-dep003) -- [Misplaced development dependencies (DEP004)](#misplaced-development-dependencies-dep004) +| Code | Description | More information | +|--------|------------------------------------| ----------------------------------------------------| +| DEP001 | Project should not contain missing dependencies | [link](#missing-dependencies-dep001) | +| DEP002 | Project should not contain unused dependencies | [link](#unused-dependencies-dep002) | +| DEP003 | Project should not use transitive dependencies | [link](#transitive-dependencies-dep003) | +| DEP004 | Project should not use development dependencies in non-development code | [link](#misplaced-development-dependencies-dep004) | + +Any of the checks can be disabled with the [`ignore`](usage.md#ignore) flag. Specific dependencies or modules can be +ignored with the [`per-rule-ignores`](usage.md#per-rule-ignores) flag. ## Missing dependencies (DEP001) Python modules that are imported within a project, for which no corresponding packages are found in the dependencies. -### Configuration - -This check can be disabled with [Skip missing](usage.md#skip-missing) option. - -Specific dependencies can be ignored with [Ignore missing](usage.md#ignore-missing) option. - ### Example On a project with the following dependencies: @@ -48,12 +47,6 @@ dependencies = ["httpx==0.23.1"] Dependencies that are required in a project, but are not used within the codebase. -### Configuration - -This check can be disabled with [Skip unused](usage.md#skip-unused) option. - -Specific dependencies can be ignored with [Ignore unused](usage.md#ignore-unused) option. - ### Example On a project with the following dependencies: @@ -90,12 +83,6 @@ dependencies = ["httpx==0.23.1"] Python modules that are imported within a project, where the corresponding dependencies are in the dependency tree, but not as direct dependencies. For example, assume your project has a `.py` file that imports module A. However, A is not in your project's dependencies. Instead, another package (B) is in your list of dependencies, which in turn depends on A. Package A should be explicitly added to your project's list of dependencies. -### Configuration - -This check can be disabled with [Skip transitive](usage.md#skip-transitive) option. - -Specific dependencies can be ignored with [Ignore transitive](usage.md#ignore-transitive) option. - ### Example On a project with the following dependencies: @@ -137,12 +124,6 @@ dependencies = [ Dependencies specified as development ones that should be included as regular dependencies. -### Configuration - -This check can be disabled with [Skip misplaced dev](usage.md#skip-misplaced-dev) option. - -Specific dependencies can be ignored with [Ignore misplaced dev](usage.md#ignore-misplaced-dev) option. - ### Example On a project with the following dependencies: diff --git a/docs/usage.md b/docs/usage.md index 024b10c8..ea9b8aec 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -77,7 +77,7 @@ an example config for your `.pre-commit-config.yaml` file: rev: "" hooks: - id: deptry - args: ["--skip-missing"] + args: ["--ignore", "DEP001"] ``` Replace `` with one of the [tags](https://github.com/fpgmaas/deptry/tags) from the @@ -172,76 +172,41 @@ extend_exclude = ["a_directory", "a_python_file\\.py", "a_pattern/.*"] deptry . --extend-exclude "a_directory|a_python_file\.py|a_pattern/.*" ``` -#### Ignore missing +#### Ignore -List of Python modules to ignore when running the check for [Missing dependencies (DEP001)](violations-detection.md#missing-dependencies-dep001). +A comma-separated list of [rules](rules-violations.md) to ignore. - Type: `List[str]` - Default: `[]` -- `pyproject.toml` option name: `ignore_missing` -- CLI option name: `--ignore-missing` (short: `-im`) +- `pyproject.toml` option name: `ignore` +- CLI option name: `--ignore` (short: `-i`) - `pyproject.toml` example: ```toml [tool.deptry] -ignore_missing = ["pip", "tomllib"] +ignore = ["DEP003", "DEP004"] ``` - CLI example: ```shell -deptry . --ignore-missing "pip,tomllib" +deptry . --ignore DEP003,DEP004 ``` -#### Ignore unused +#### Per check ignores -List of packages to ignore when running the check for [Unused dependencies (DEP002)](violations-detection.md#unused-dependencies-dep002). +A comma-separated mapping of packages or modules to be ignored per [rule](rules-violations.md) . -- Type: `List[str]` -- Default: `[]` -- `pyproject.toml` option name: `ignore_unused` -- CLI option name: `--ignore-unused` (short: `-io`) -- `pyproject.toml` example: -```toml -[tool.deptry] -ignore_unused = ["uvicorn", "uvloop"] -``` -- CLI example: -```shell -deptry . --ignore-unused "uvicorn,uvloop" -``` - -#### Ignore transitive - -List of Python modules to ignore when running the check for [Transitive dependencies (DEP003)](violations-detection.md#transitive-dependencies-dep003). - -- Type: `List[str]` -- Default: `[]` -- `pyproject.toml` option name: `ignore_transitive` -- CLI option name: `--ignore-transitive` (short: `-it`) -- `pyproject.toml` example: -```toml -[tool.deptry] -ignore_transitive = ["httpx", "pip"] -``` -- CLI example: -```shell -deptry . --ignore-transitive "httpx,pip" -``` - -#### Ignore misplaced dev - -List of Python modules to ignore when running the check for [Misplaced development dependencies (DEP004)](violations-detection.md#misplaced-development-dependencies-dep004). - -- Type: `List[str]` -- Default: `[]` -- `pyproject.toml` option name: `ignore_misplaced_dev` -- CLI option name: `--ignore-misplaced-dev` (short: `-id`) +- Type: `dict[str, list[str] | str]` +- Default: `{}` +- `pyproject.toml` option name: `per_rule_ignores` +- CLI option name: `--per-rule-ignores` (short: `-pri`) - `pyproject.toml` example: ```toml -[tool.deptry] -ignore_misplaced_dev = ["black", "isort"] +[tool.deptry.per_rule_ignores] +DEP001 = ["matplotlib"] +DEP002 = ["pandas", "numpy"] ``` - CLI example: ```shell -deptry . --ignore-misplaced-dev "black,isort" +deptry . --per-rule-ignores DEP001=matplotlib,DEP002=pandas|numpy ``` #### Ignore notebooks @@ -262,78 +227,6 @@ ignore_notebooks = true deptry . --ignore-notebooks ``` -#### Skip missing - -Disable the check for [Missing dependencies (DEP001)](violations-detection.md#missing-dependencies-dep001). - -- Type: `bool` -- Default: `False` -- `pyproject.toml` option name: `skip_missing` -- CLI option name: `--skip-missing` -- `pyproject.toml` example: -```toml -[tool.deptry] -skip_missing = true -``` -- CLI example: -```shell -deptry . --skip-missing -``` - -#### Skip unused - -Disable the check for [Unused dependencies (DEP002)](violations-detection.md#unused-dependencies-dep002). - -- Type: `bool` -- Default: `False` -- `pyproject.toml` option name: `skip_unused` -- CLI option name: `--skip-unused` -- `pyproject.toml` example: -```toml -[tool.deptry] -skip_unused = true -``` -- CLI example: -```shell -deptry . --skip-unused -``` - -#### Skip transitive - -Disable the check for [Transitive dependencies (DEP003)](violations-detection.md#transitive-dependencies-dep003). - -- Type: `bool` -- Default: `False` -- `pyproject.toml` option name: `skip_transitive` -- CLI option name: `--skip-transitive` -- `pyproject.toml` example: -```toml -[tool.deptry] -skip_transitive = true -``` -- CLI example: -```shell -deptry . --skip-transitive -``` - -#### Skip misplaced dev - -Disable the check for [Misplaced development dependencies (DEP004)](violations-detection.md#misplaced-development-dependencies-dep004). - -- Type: `bool` -- Default: `False` -- `pyproject.toml` option name: `skip_misplaced_dev` -- CLI option name: `--skip-misplaced-dev` -- `pyproject.toml` example: -```toml -[tool.deptry] -skip_misplaced_dev = true -``` -- CLI example: -```shell -deptry . --skip-misplaced-dev -``` - #### Requirements txt List of [`pip` requirements files](https://pip.pypa.io/en/stable/user_guide/#requirements-files) that contain the source dependencies. @@ -459,7 +352,7 @@ json_output = "deptry_report.txt" deptry . --json-output deptry_report.txt ``` -#### Manually map Package Names to Top Level Module Names +#### Package module name map Deptry will automatically detect top level modules names that belong to a module in two ways. diff --git a/mkdocs.yml b/mkdocs.yml index 79f8926d..21700fa6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -10,7 +10,7 @@ copyright: Maintained by Florian. nav: - Home: index.md - Usage and Configuration: usage.md - - Violations detection: violations-detection.md + - Rules and Violations: rules-violations.md - Changelog: CHANGELOG.md - Contributing: contributing.md diff --git a/pyproject.toml b/pyproject.toml index 538c64d6..f4e46651 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -108,7 +108,9 @@ extend_exclude = [ "tests", "scripts", ] -ignore_missing = ["tomllib"] + +[tool.deptry.per_rule_ignores] +DEP001 = ["tomllib"] [tool.poetry.scripts] deptry = "deptry.cli:deptry" diff --git a/tests/data/example_project/pyproject.toml b/tests/data/example_project/pyproject.toml index b8b00661..2854585f 100644 --- a/tests/data/example_project/pyproject.toml +++ b/tests/data/example_project/pyproject.toml @@ -16,5 +16,5 @@ pkginfo = "^1.8.3" [tool.poetry.dev-dependencies] black = "^22.6.0" -[tool.deptry] -ignore_unused = ["pkginfo"] +[tool.deptry.per_rule_ignores] +DEP002 = ["pkginfo"] diff --git a/tests/data/pep_621_project/pyproject.toml b/tests/data/pep_621_project/pyproject.toml index 34b27e7a..52de6916 100644 --- a/tests/data/pep_621_project/pyproject.toml +++ b/tests/data/pep_621_project/pyproject.toml @@ -24,5 +24,5 @@ test = ["pytest==7.2.0"] requires = ["setuptools>=61.0.0"] build-backend = "setuptools.build_meta" -[tool.deptry] -ignore_unused = ["pkginfo"] +[tool.deptry.per_rule_ignores] +DEP002 = ["pkginfo"] diff --git a/tests/data/project_with_gitignore/pyproject.toml b/tests/data/project_with_gitignore/pyproject.toml index 34b27e7a..52de6916 100644 --- a/tests/data/project_with_gitignore/pyproject.toml +++ b/tests/data/project_with_gitignore/pyproject.toml @@ -24,5 +24,5 @@ test = ["pytest==7.2.0"] requires = ["setuptools>=61.0.0"] build-backend = "setuptools.build_meta" -[tool.deptry] -ignore_unused = ["pkginfo"] +[tool.deptry.per_rule_ignores] +DEP002 = ["pkginfo"] diff --git a/tests/data/project_with_pdm/pyproject.toml b/tests/data/project_with_pdm/pyproject.toml index 340a8755..90302648 100644 --- a/tests/data/project_with_pdm/pyproject.toml +++ b/tests/data/project_with_pdm/pyproject.toml @@ -28,5 +28,5 @@ test = [ "pytest-cov>=4.0.0", ] -[tool.deptry] -ignore_unused = ["pkginfo"] +[tool.deptry.per_rule_ignores] +DEP002 = ["pkginfo"] diff --git a/tests/data/project_with_poetry/pyproject.toml b/tests/data/project_with_poetry/pyproject.toml index ad787461..19d1dd89 100644 --- a/tests/data/project_with_poetry/pyproject.toml +++ b/tests/data/project_with_poetry/pyproject.toml @@ -29,5 +29,5 @@ mypy = "^1.3.0" pytest = "^7.3.0" pytest-cov = "^4.0.0" -[tool.deptry] -ignore_unused = ["pkginfo"] +[tool.deptry.per_rule_ignores] +DEP002 = ["pkginfo"] diff --git a/tests/data/project_with_pyproject_different_directory/a_sub_directory/pyproject.toml b/tests/data/project_with_pyproject_different_directory/a_sub_directory/pyproject.toml index 2ffb7d48..31a66ac4 100644 --- a/tests/data/project_with_pyproject_different_directory/a_sub_directory/pyproject.toml +++ b/tests/data/project_with_pyproject_different_directory/a_sub_directory/pyproject.toml @@ -26,5 +26,5 @@ test = [ requires = ["setuptools>=61.0.0"] build-backend = "setuptools.build_meta" -[tool.deptry] -ignore_unused = ["pkginfo"] +[tool.deptry.per_rule_ignores] +DEP002 = ["pkginfo"] diff --git a/tests/data/project_with_requirements_txt/pyproject.toml b/tests/data/project_with_requirements_txt/pyproject.toml index 4d7d2469..066202ec 100644 --- a/tests/data/project_with_requirements_txt/pyproject.toml +++ b/tests/data/project_with_requirements_txt/pyproject.toml @@ -1,5 +1,5 @@ [tool.black] line-length = 120 -[tool.deptry] -ignore_unused = ["pkginfo"] +[tool.deptry.per_rule_ignores] +DEP002 = ["pkginfo"] diff --git a/tests/data/project_with_src_directory/pyproject.toml b/tests/data/project_with_src_directory/pyproject.toml index 34b27e7a..52de6916 100644 --- a/tests/data/project_with_src_directory/pyproject.toml +++ b/tests/data/project_with_src_directory/pyproject.toml @@ -24,5 +24,5 @@ test = ["pytest==7.2.0"] requires = ["setuptools>=61.0.0"] build-backend = "setuptools.build_meta" -[tool.deptry] -ignore_unused = ["pkginfo"] +[tool.deptry.per_rule_ignores] +DEP002 = ["pkginfo"] diff --git a/tests/functional/cli/test_cli.py b/tests/functional/cli/test_cli.py index 0f6f6ba8..69d992ca 100644 --- a/tests/functional/cli/test_cli.py +++ b/tests/functional/cli/test_cli.py @@ -142,14 +142,14 @@ def test_cli_ignore_notebooks(poetry_project_builder: ToolSpecificProjectBuilder def test_cli_ignore_flags(poetry_project_builder: ToolSpecificProjectBuilder) -> None: with run_within_dir(poetry_project_builder("example_project")): - result = CliRunner().invoke(deptry, ". --ignore-unused isort,pkginfo,requests -im white -id black") + result = CliRunner().invoke(deptry, ". --per-rule-ignores DEP002=isort|pkginfo|requests -im white -id black") assert result.exit_code == 0 -def test_cli_skip_flags(poetry_project_builder: ToolSpecificProjectBuilder) -> None: +def test_cli_ignore_flag(poetry_project_builder: ToolSpecificProjectBuilder) -> None: with run_within_dir(poetry_project_builder("example_project")): - result = CliRunner().invoke(deptry, ". --skip-unused --skip-missing --skip-misplaced-dev --skip-transitive") + result = CliRunner().invoke(deptry, ". --ignore DEP001,DEP002,DEP003,DEP004") assert result.exit_code == 0 diff --git a/tests/functional/cli/test_cli_arg_types.py b/tests/functional/cli/test_cli_arg_types.py index f50176c7..abc1b320 100644 --- a/tests/functional/cli/test_cli_arg_types.py +++ b/tests/functional/cli/test_cli_arg_types.py @@ -10,7 +10,7 @@ from deptry.cli import CommaSeparatedMappingParamType, CommaSeparatedTupleParamType if TYPE_CHECKING: - from collections.abc import Mapping, Sequence + from collections.abc import MutableMapping, Sequence from re import Pattern @@ -133,8 +133,8 @@ def test_comma_separated_tuple_param_type_convert( ], ) def test_comma_separated_mapping_param_type_convert( - value: str | Mapping[str, Sequence[str] | str], - expected: Mapping[str, tuple[str, ...]], + value: str | MutableMapping[str, Sequence[str] | str], + expected: MutableMapping[str, tuple[str, ...]], ) -> None: """Tests all valid conversion paths.""" param = mock.Mock(spec=click.Parameter) @@ -163,7 +163,7 @@ def test_comma_separated_mapping_param_type_convert( ], ) def test_comma_separated_mapping_param_type_convert_err( - value: str | Mapping[str, Sequence[str] | str], + value: str | MutableMapping[str, Sequence[str] | str], err_type: type[Exception], err_msg_matcher: Pattern[str] | str, ) -> None: diff --git a/tests/functional/cli/test_cli_with_future_deprecated_obsolete_argument.py b/tests/functional/cli/test_cli_with_future_deprecated_obsolete_argument.py deleted file mode 100644 index 6091e701..00000000 --- a/tests/functional/cli/test_cli_with_future_deprecated_obsolete_argument.py +++ /dev/null @@ -1,130 +0,0 @@ -from __future__ import annotations - -import shlex -import subprocess -from pathlib import Path -from typing import TYPE_CHECKING - -from deptry.deprecate_obsolete import ( - IGNORE_OBSOLETE_AND_IGNORE_UNUSED_ERROR_MESSAGE, - IGNORE_OBSOLETE_WARNING, - SKIP_OBSOLETE_AND_SKIP_UNUSED_ERROR_MESSAGE, - SKIP_OBSOLETE_WARNING, -) -from tests.utils import get_issues_report, run_within_dir - -if TYPE_CHECKING: - from tests.functional.types import ToolSpecificProjectBuilder - - -def test_cli_uses_both_obsolete_and_unused_flag_from_pyproject_toml( - poetry_project_builder: ToolSpecificProjectBuilder, -) -> None: - with run_within_dir(poetry_project_builder("project_with_future_deprecated_obsolete_argument")): - result = subprocess.run(shlex.split("poetry run deptry . -o report.json"), capture_output=True, text=True) - - assert IGNORE_OBSOLETE_WARNING in result.stderr - assert result.returncode == 1 - assert get_issues_report() == [ - { - "error": { - "code": "DEP002", - "message": "'isort' defined as a dependency but not used in the codebase", - }, - "module": "isort", - "location": { - "file": str(Path("pyproject.toml")), - "line": None, - "column": None, - }, - }, - { - "error": { - "code": "DEP002", - "message": "'requests' defined as a dependency but not used in the codebase", - }, - "module": "requests", - "location": { - "file": str(Path("pyproject.toml")), - "line": None, - "column": None, - }, - }, - { - "error": { - "code": "DEP004", - "message": "'black' imported but declared as a dev dependency", - }, - "module": "black", - "location": { - "file": str(Path("src/main.py")), - "line": 4, - "column": 0, - }, - }, - { - "error": { - "code": "DEP001", - "message": "'white' imported but missing from the dependency definitions", - }, - "module": "white", - "location": { - "file": str(Path("src/main.py")), - "line": 6, - "column": 0, - }, - }, - ] - - -def test_cli_skip_obsolete_argument_still_works(poetry_project_builder: ToolSpecificProjectBuilder) -> None: - with run_within_dir(poetry_project_builder("project_with_future_deprecated_obsolete_argument")): - result = subprocess.run( - shlex.split("poetry run deptry . --skip-obsolete -o report.json"), capture_output=True, text=True - ) - - assert SKIP_OBSOLETE_WARNING in result.stderr - assert IGNORE_OBSOLETE_WARNING in result.stderr - assert result.returncode == 1 - assert get_issues_report() == [ - { - "error": { - "code": "DEP004", - "message": "'black' imported but declared as a dev dependency", - }, - "module": "black", - "location": { - "file": str(Path("src/main.py")), - "line": 4, - "column": 0, - }, - }, - { - "error": { - "code": "DEP001", - "message": "'white' imported but missing from the dependency definitions", - }, - "module": "white", - "location": { - "file": str(Path("src/main.py")), - "line": 6, - "column": 0, - }, - }, - ] - - -def test_cli_raise_error_if_both_skip_options_used(poetry_project_builder: ToolSpecificProjectBuilder) -> None: - with run_within_dir(poetry_project_builder("project_with_future_deprecated_obsolete_argument")): - result = subprocess.run( - shlex.split("poetry run deptry . --skip-obsolete --skip-unused"), capture_output=True, text=True - ) - assert SKIP_OBSOLETE_AND_SKIP_UNUSED_ERROR_MESSAGE in result.stderr - - -def test_cli_raise_error_if_both_ignore_options_used(poetry_project_builder: ToolSpecificProjectBuilder) -> None: - with run_within_dir(poetry_project_builder("project_with_future_deprecated_obsolete_argument")): - result = subprocess.run( - shlex.split("poetry run deptry . --ignore-unused 'a,b'"), capture_output=True, text=True - ) - assert IGNORE_OBSOLETE_AND_IGNORE_UNUSED_ERROR_MESSAGE in result.stderr diff --git a/tests/unit/deprecate/test_ignore_flags.py b/tests/unit/deprecate/test_ignore_flags.py new file mode 100644 index 00000000..131d7242 --- /dev/null +++ b/tests/unit/deprecate/test_ignore_flags.py @@ -0,0 +1,182 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +import pytest + +from deptry.deprecate.ignore_flags import generate_deprecation_warning, get_value_for_per_rule_ignores_argument + +if TYPE_CHECKING: + from collections.abc import MutableMapping + + +def test_generate_deprecation_warning() -> None: + result = generate_deprecation_warning(flag_name="ignore-missing", issue_code="DEP002", sequence=("hi", "bye")) + assert ( + result + == "Warning: In an upcoming release, support for the `--ignore-missing` command-line option and the" + " `ignore_missing` configuration parameter will be discontinued. Instead, use `--per-rule-ignores" + ' DEP002=hi|bye` or add a line `DEP002 = ["hi", "bye"]` to the `[tool.deptry.per_rule_ignores]` section of the' + " configuration file." + ) + + +@pytest.mark.parametrize( + ("ignore_params", "expected_result", "flag_name", "issue_code"), + [ + ( + { + "ignore_obsolete": (), + "ignore_unused": (), + "ignore_missing": ("hello", "goodbye"), + "ignore_transitive": (), + "ignore_misplaced_dev": (), + }, + {"DEP001": ("hello", "goodbye")}, + "ignore-missing", + "DEP001", + ), + ( + { + "ignore_obsolete": ("hello", "goodbye"), + "ignore_unused": (), + "ignore_missing": (), + "ignore_transitive": (), + "ignore_misplaced_dev": (), + }, + {"DEP002": ("hello", "goodbye")}, + "ignore-obsolete", + "DEP002", + ), + ( + { + "ignore_obsolete": (), + "ignore_unused": ("hello", "goodbye"), + "ignore_missing": (), + "ignore_transitive": (), + "ignore_misplaced_dev": (), + }, + {"DEP002": ("hello", "goodbye")}, + "ignore-unused", + "DEP002", + ), + ( + { + "ignore_obsolete": (), + "ignore_unused": (), + "ignore_missing": (), + "ignore_transitive": ("hello", "goodbye"), + "ignore_misplaced_dev": (), + }, + {"DEP003": ("hello", "goodbye")}, + "ignore-transitive", + "DEP003", + ), + ( + { + "ignore_obsolete": (), + "ignore_unused": (), + "ignore_missing": (), + "ignore_transitive": (), + "ignore_misplaced_dev": ("hello", "goodbye"), + }, + {"DEP004": ("hello", "goodbye")}, + "ignore-misplaced-dev", + "DEP004", + ), + ], +) +def test_ignore_param( + caplog: pytest.LogCaptureFixture, + ignore_params: MutableMapping[str, tuple[str, ...]], + expected_result: MutableMapping[str, tuple[str, ...]], + flag_name: str, + issue_code: str, +) -> None: + result = get_value_for_per_rule_ignores_argument(per_rule_ignores={}, **ignore_params) + assert result == expected_result + assert ( + generate_deprecation_warning(flag_name=flag_name, issue_code=issue_code, sequence=("hello", "goodbye")) + in caplog.text + ) + + +@pytest.mark.parametrize( + ("ignore_params", "expected_result", "flag_name", "issue_code"), + [ + ( + { + "ignore_obsolete": (), + "ignore_unused": (), + "ignore_missing": ("hello", "goodbye"), + "ignore_transitive": (), + "ignore_misplaced_dev": (), + }, + {"DEP001": ("goodbye", "hello", "package")}, + "ignore-missing", + "DEP001", + ), + ( + { + "ignore_obsolete": ("hello", "goodbye"), + "ignore_unused": (), + "ignore_missing": (), + "ignore_transitive": (), + "ignore_misplaced_dev": (), + }, + {"DEP002": ("goodbye", "hello", "package")}, + "ignore-obsolete", + "DEP002", + ), + ( + { + "ignore_obsolete": (), + "ignore_unused": ("hello", "goodbye"), + "ignore_missing": (), + "ignore_transitive": (), + "ignore_misplaced_dev": (), + }, + {"DEP002": ("goodbye", "hello", "package")}, + "ignore-unused", + "DEP002", + ), + ( + { + "ignore_obsolete": (), + "ignore_unused": (), + "ignore_missing": (), + "ignore_transitive": ("hello", "goodbye"), + "ignore_misplaced_dev": (), + }, + {"DEP003": ("goodbye", "hello", "package")}, + "ignore-transitive", + "DEP003", + ), + ( + { + "ignore_obsolete": (), + "ignore_unused": (), + "ignore_missing": (), + "ignore_transitive": (), + "ignore_misplaced_dev": ("hello", "goodbye"), + }, + {"DEP004": ("goodbye", "hello", "package")}, + "ignore-misplaced-dev", + "DEP004", + ), + ], +) +def test_ignore_param_append( + caplog: pytest.LogCaptureFixture, + ignore_params: MutableMapping[str, tuple[str, ...]], + expected_result: MutableMapping[str, tuple[str, ...]], + flag_name: str, + issue_code: str, +) -> None: + result = get_value_for_per_rule_ignores_argument(per_rule_ignores={issue_code: ("package",)}, **ignore_params) + # We do not care about the order of the sequences that are in the values of the dict. + assert {k: sorted(v) for k, v in result.items()} == {k: sorted(v) for k, v in expected_result.items()} + assert ( + generate_deprecation_warning(flag_name=flag_name, issue_code=issue_code, sequence=("hello", "goodbye")) + in caplog.text + ) diff --git a/tests/unit/deprecate/test_skip_flags.py b/tests/unit/deprecate/test_skip_flags.py new file mode 100644 index 00000000..c74ee33f --- /dev/null +++ b/tests/unit/deprecate/test_skip_flags.py @@ -0,0 +1,58 @@ +from __future__ import annotations + +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + import pytest + +from deptry.deprecate.skip_flags import generate_deprecation_warning, get_value_for_ignore_argument + + +def test_generate_deprecation_warning() -> None: + result = generate_deprecation_warning(flag_name="skip-unused", issue_code="DEP002") + assert ( + result + == "Warning: In an upcoming release, support for the `--skip-unused` command-line option and the `skip_unused`" + " configuration parameter will be discontinued. Instead, use `--ignore DEP002` or add a line `ignore =" + " ['DEP002']` to the `[tool.deptry]` section of the configuration file." + ) + + +def test_skip_obsolete(caplog: pytest.LogCaptureFixture) -> None: + result = get_value_for_ignore_argument( + ignore=(), + skip_obsolete=True, + skip_unused=False, + skip_missing=False, + skip_transitive=False, + skip_misplaced_dev=False, + ) + assert result == ("DEP002",) + assert generate_deprecation_warning(flag_name="skip-obsolete", issue_code="DEP002") in caplog.text + + +def test_skip_unused(caplog: pytest.LogCaptureFixture) -> None: + result = get_value_for_ignore_argument( + ignore=(), + skip_obsolete=True, + skip_unused=True, + skip_missing=False, + skip_transitive=False, + skip_misplaced_dev=False, + ) + assert result == ("DEP002",) + assert generate_deprecation_warning(flag_name="skip-unused", issue_code="DEP002") in caplog.text + + +def test_skip_transitive_and_missing(caplog: pytest.LogCaptureFixture) -> None: + result = get_value_for_ignore_argument( + ignore=(), + skip_obsolete=False, + skip_unused=False, + skip_missing=True, + skip_transitive=True, + skip_misplaced_dev=False, + ) + assert result == ("DEP001", "DEP003") + assert generate_deprecation_warning(flag_name="skip-missing", issue_code="DEP001") in caplog.text + assert generate_deprecation_warning(flag_name="skip-transitive", issue_code="DEP003") in caplog.text diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index 7ad73243..a22f058d 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -19,15 +19,10 @@ def test_read_configuration_from_pyproject_toml_exists(tmp_path: Path) -> None: default_map={ "exclude": ["bar"], "extend_exclude": ["foo"], - "ignore_notebooks": False, - "ignore_unused": ["baz", "bar"], - "ignore_missing": [], - "ignore_misplaced_dev": [], - "ignore_transitive": [], - "skip_unused": False, - "skip_missing": False, - "skip_transitive": False, - "skip_misplaced_dev": False, + "per_rule_ignores": { + "DEP002": ["baz", "bar"], + }, + "ignore": [], "requirements_txt": "requirements.txt", "requirements_txt_dev": ["requirements-dev.txt"], }, @@ -38,16 +33,15 @@ def test_read_configuration_from_pyproject_toml_exists(tmp_path: Path) -> None: exclude = ["foo", "bar"] extend_exclude = ["bar", "foo"] ignore_notebooks = true - ignore_unused = ["foo"] - ignore_missing = ["baz", "foobar"] - ignore_misplaced_dev = ["barfoo"] - ignore_transitive = ["foobaz"] - skip_unused = true - skip_missing = true - skip_transitive = true - skip_misplaced_dev = true + ignore = ["DEP001", "DEP002", "DEP003", "DEP004"] requirements_txt = "foo.txt" requirements_txt_dev = ["dev.txt", "tests.txt"] + + [tool.deptry.per_rule_ignores] + DEP001 = ["baz", "foobar"] + DEP002 = ["foo"] + DEP003 = ["foobaz"] + DEP004 = ["barfoo"] """ with run_within_dir(tmp_path): @@ -65,14 +59,13 @@ def test_read_configuration_from_pyproject_toml_exists(tmp_path: Path) -> None: "exclude": ["foo", "bar"], "extend_exclude": ["bar", "foo"], "ignore_notebooks": True, - "ignore_unused": ["foo"], - "ignore_missing": ["baz", "foobar"], - "ignore_misplaced_dev": ["barfoo"], - "ignore_transitive": ["foobaz"], - "skip_unused": True, - "skip_missing": True, - "skip_transitive": True, - "skip_misplaced_dev": True, + "per_rule_ignores": { + "DEP001": ["baz", "foobar"], + "DEP002": ["foo"], + "DEP003": ["foobaz"], + "DEP004": ["barfoo"], + }, + "ignore": ["DEP001", "DEP002", "DEP003", "DEP004"], "requirements_txt": "foo.txt", "requirements_txt_dev": ["dev.txt", "tests.txt"], } diff --git a/tests/unit/test_core.py b/tests/unit/test_core.py index 18f0363e..2697b4dd 100644 --- a/tests/unit/test_core.py +++ b/tests/unit/test_core.py @@ -82,14 +82,8 @@ def test__get_local_modules( root=(tmp_path / root_suffix,), config=Path("pyproject.toml"), no_ansi=False, - ignore_unused=(), - ignore_missing=(), - ignore_transitive=(), - ignore_misplaced_dev=(), - skip_unused=False, - skip_missing=False, - skip_transitive=False, - skip_misplaced_dev=False, + per_rule_ignores={}, + ignore=(), exclude=(), extend_exclude=(), using_default_exclude=True, diff --git a/tests/unit/test_deprecate_obsolete.py b/tests/unit/test_deprecate_obsolete.py deleted file mode 100644 index 0a8e5a80..00000000 --- a/tests/unit/test_deprecate_obsolete.py +++ /dev/null @@ -1,44 +0,0 @@ -from __future__ import annotations - -import pytest - -from deptry.deprecate_obsolete import ( - IGNORE_OBSOLETE_AND_IGNORE_UNUSED_ERROR_MESSAGE, - IGNORE_OBSOLETE_WARNING, - SKIP_OBSOLETE_AND_SKIP_UNUSED_ERROR_MESSAGE, - SKIP_OBSOLETE_WARNING, - get_value_for_ignore_unused, - get_value_for_skip_unused, -) - - -def test_skip_obsolete(caplog: pytest.LogCaptureFixture) -> None: - result = get_value_for_skip_unused(skip_obsolete=True, skip_unused=False) - assert result - assert SKIP_OBSOLETE_WARNING in caplog.text - - -def test_skip_unused() -> None: - result = get_value_for_skip_unused(skip_obsolete=False, skip_unused=True) - assert result - - -def test_skip_unused_and_skip_obsolete() -> None: - with pytest.raises(ValueError, match=SKIP_OBSOLETE_AND_SKIP_UNUSED_ERROR_MESSAGE): - get_value_for_skip_unused(skip_obsolete=True, skip_unused=True) - - -def test_ignore_obsolete(caplog: pytest.LogCaptureFixture) -> None: - result = get_value_for_ignore_unused(ignore_obsolete=("a",), ignore_unused=()) - assert result == ("a",) - assert IGNORE_OBSOLETE_WARNING in caplog.text - - -def test_ignore_unused() -> None: - result = get_value_for_ignore_unused(ignore_obsolete=(), ignore_unused=("a",)) - assert result == ("a",) - - -def test_ignore_unused_and_ignore_obsolete() -> None: - with pytest.raises(ValueError, match=IGNORE_OBSOLETE_AND_IGNORE_UNUSED_ERROR_MESSAGE): - get_value_for_ignore_unused(ignore_obsolete=("b",), ignore_unused=("a",)) diff --git a/tests/unit/test_utils.py b/tests/unit/test_utils.py index 4bc90cc6..56c8ce25 100644 --- a/tests/unit/test_utils.py +++ b/tests/unit/test_utils.py @@ -8,7 +8,7 @@ def test_load_pyproject_toml() -> None: assert load_pyproject_toml(Path("tests/data/example_project/pyproject.toml")) == { "tool": { - "deptry": {"ignore_unused": ["pkginfo"]}, + "deptry": {"per_rule_ignores": {"DEP002": ["pkginfo"]}}, "poetry": { "authors": ["test "], "dependencies": {