Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

398 ignore flag #402

Merged
merged 14 commits into from
Jun 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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