Skip to content

Commit

Permalink
398 ignore flag (#402)
Browse files Browse the repository at this point in the history
* added ignore and per-rule-ignores flags

---------

Co-authored-by: Mathieu Kniewallner <mathieu.kniewallner@gmail.com>
  • Loading branch information
fpgmaas and mkniewallner authored Jun 18, 2023
1 parent 11aabee commit e29c29a
Show file tree
Hide file tree
Showing 26 changed files with 537 additions and 495 deletions.
93 changes: 59 additions & 34 deletions deptry/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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, ...]]:
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -284,14 +298,16 @@ 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,
requirements_txt: tuple[str, ...],
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.
Expand All @@ -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,
Expand Down
40 changes: 20 additions & 20 deletions deptry/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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()
Expand Down Expand Up @@ -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()
)

Expand Down
74 changes: 74 additions & 0 deletions deptry/deprecate/ignore_flags.py
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit e29c29a

Please sign in to comment.