Skip to content

Commit

Permalink
Replace the word obsolete with unused (#373)
Browse files Browse the repository at this point in the history
* Replace the word `obsolete` with `unused`
* add future depreciation warning
* Raise error if both skip_obsolete and skip_unused, or ignore_obsolete and ignore_unused are used
  • Loading branch information
fpgmaas authored May 10, 2023
1 parent c85681c commit 133a9cc
Show file tree
Hide file tree
Showing 37 changed files with 451 additions and 93 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
- id: deptry
name: deptry
description: deptry is a command line tool to check for issues with dependencies in a Python project, such as obsolete or missing dependencies.
description: deptry is a command line tool to check for issues with dependencies in a Python project, such as unused or missing dependencies.
entry: deptry .
language: system
always_run: true
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ check: ## Run code quality tools.
@poetry run pre-commit run -a
@echo "🚀 Static type checking: Running mypy"
@poetry run mypy
@echo "🚀 Checking for obsolete dependencies: Running deptry"
@echo "🚀 Checking for dependency issues: Running deptry"
@poetry run deptry .

.PHONY: test
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
[![PyPI - Downloads](https://img.shields.io/pypi/dm/deptry)](https://pypistats.org/packages/deptry)
[![License](https://img.shields.io/github/license/fpgmaas/deptry)](https://img.shields.io/github/license/fpgmaas/deptry)

_deptry_ is a command line tool to check for issues with dependencies in a Python project, such as obsolete or missing dependencies. It supports the following types of projects:
_deptry_ is a command line tool to check for issues with dependencies in a Python project, such as unused or missing dependencies. It supports the following types of projects:

- Projects that use [Poetry](https://python-poetry.org/) and a corresponding _pyproject.toml_ file
- Projects that use [PDM](https://pdm.fming.dev/latest/) and a corresponding _pyproject.toml_ file
Expand Down
21 changes: 13 additions & 8 deletions deptry/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

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

if TYPE_CHECKING:
from collections.abc import Mapping, Sequence
Expand Down Expand Up @@ -130,10 +131,11 @@ def display_deptry_version(ctx: click.Context, _param: click.Parameter, value: b
is_flag=True,
help="Disable ANSI characters in terminal output.",
)
@click.option("--skip-obsolete", is_flag=True, hidden=True)
@click.option(
"--skip-obsolete",
"--skip-unused",
is_flag=True,
help="Boolean flag to specify if deptry should skip scanning the project for obsolete dependencies.",
help="Boolean flag to specify if deptry should skip scanning the project for unused dependencies.",
)
@click.option(
"--skip-missing",
Expand All @@ -153,13 +155,14 @@ def display_deptry_version(ctx: click.Context, _param: click.Parameter, value: b
" regular dependencies."
),
)
@click.option("--ignore-obsolete", "-io", type=COMMA_SEPARATED_TUPLE, default=(), hidden=True)
@click.option(
"--ignore-obsolete",
"-io",
"--ignore-unused",
"-iu",
type=COMMA_SEPARATED_TUPLE,
help="""
Comma-separated list of dependencies that should never be marked as obsolete, even if they are not imported in any of the files scanned.
For example; `deptry . --ignore-obsolete foo,bar`.
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`.
""",
default=(),
)
Expand Down Expand Up @@ -271,10 +274,12 @@ def deptry(
root: tuple[Path, ...],
config: Path,
no_ansi: bool,
ignore_unused: tuple[str, ...],
ignore_obsolete: tuple[str, ...],
ignore_missing: tuple[str, ...],
ignore_transitive: tuple[str, ...],
ignore_misplaced_dev: tuple[str, ...],
skip_unused: bool,
skip_obsolete: bool,
skip_missing: bool,
skip_transitive: bool,
Expand Down Expand Up @@ -306,15 +311,15 @@ def deptry(
root=root,
config=config,
no_ansi=no_ansi,
ignore_obsolete=ignore_obsolete,
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_obsolete=skip_obsolete,
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,
Expand Down
10 changes: 5 additions & 5 deletions deptry/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
from deptry.imports.extract import get_imported_modules_for_list_of_files
from deptry.issues_finder.misplaced_dev import MisplacedDevDependenciesFinder
from deptry.issues_finder.missing import MissingDependenciesFinder
from deptry.issues_finder.obsolete import ObsoleteDependenciesFinder
from deptry.issues_finder.transitive import TransitiveDependenciesFinder
from deptry.issues_finder.unused import UnusedDependenciesFinder
from deptry.module import ModuleBuilder, ModuleLocations
from deptry.python_file_finder import PythonFileFinder
from deptry.reporters import JSONReporter, TextReporter
Expand All @@ -36,11 +36,11 @@ class Core:
root: tuple[Path, ...]
config: Path
no_ansi: bool
ignore_obsolete: tuple[str, ...]
ignore_unused: tuple[str, ...]
ignore_missing: tuple[str, ...]
ignore_transitive: tuple[str, ...]
ignore_misplaced_dev: tuple[str, ...]
skip_obsolete: bool
skip_unused: bool
skip_missing: bool
skip_transitive: bool
skip_misplaced_dev: bool
Expand Down Expand Up @@ -101,9 +101,9 @@ def _find_violations(
) -> list[Violation]:
violations = []

if not self.skip_obsolete:
if not self.skip_unused:
violations.extend(
ObsoleteDependenciesFinder(imported_modules_with_locations, dependencies, self.ignore_obsolete).find()
UnusedDependenciesFinder(imported_modules_with_locations, dependencies, self.ignore_unused).find()
)

if not self.skip_missing:
Expand Down
53 changes: 53 additions & 0 deletions deptry/deprecate_obsolete.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
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
26 changes: 12 additions & 14 deletions deptry/issues_finder/obsolete.py → deptry/issues_finder/unused.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,45 @@

from deptry.imports.location import Location
from deptry.issues_finder.base import IssuesFinder
from deptry.violations import ObsoleteDependencyViolation
from deptry.violations import UnusedDependencyViolation

if TYPE_CHECKING:
from deptry.dependency import Dependency
from deptry.violations import Violation


@dataclass
class ObsoleteDependenciesFinder(IssuesFinder):
class UnusedDependenciesFinder(IssuesFinder):
"""
Finds obsolete dependencies by comparing a list of imported modules to a list of project dependencies.
Finds unused dependencies by comparing a list of imported modules to a list of project dependencies.
A dependency is considered obsolete if none of the following conditions hold:
A dependency is considered unused if none of the following conditions hold:
- A module with the exact name of the dependency is imported.
- Any of the top-level modules of the dependency are imported.
For example, 'matplotlib' has top-levels ['matplotlib', 'mpl_toolkits', 'pylab']. `mpl_toolkits` does not have
any associated metadata, but if this is imported the associated dependency `matplotlib` is not obsolete,
any associated metadata, but if this is imported the associated dependency `matplotlib` is not unused,
even if `matplotlib` itself is not imported anywhere.
"""

def find(self) -> list[Violation]:
logging.debug("\nScanning for obsolete dependencies...")
obsolete_dependencies: list[Violation] = []
logging.debug("\nScanning for unused dependencies...")
unused_dependencies: list[Violation] = []

for dependency in self.dependencies:
logging.debug("Scanning module %s...", dependency.name)

if self._is_obsolete(dependency):
obsolete_dependencies.append(
ObsoleteDependencyViolation(dependency, Location(dependency.definition_file))
)
if self._is_unused(dependency):
unused_dependencies.append(UnusedDependencyViolation(dependency, Location(dependency.definition_file)))

return obsolete_dependencies
return unused_dependencies

def _is_obsolete(self, dependency: Dependency) -> bool:
def _is_unused(self, dependency: Dependency) -> bool:
if self._dependency_found_in_imported_modules(dependency) or self._any_of_the_top_levels_imported(dependency):
return False

if dependency.name in self.ignored_modules:
logging.debug("Dependency '%s' found to be obsolete, but ignoring.", dependency.name)
logging.debug("Dependency '%s' found to be unused, but ignoring.", dependency.name)
return False

logging.debug("Dependency '%s' does not seem to be used.", dependency.name)
Expand Down
4 changes: 2 additions & 2 deletions deptry/violations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
from deptry.violations.base import Violation
from deptry.violations.misplaced_dev import MisplacedDevDependencyViolation
from deptry.violations.missing import MissingDependencyViolation
from deptry.violations.obsolete import ObsoleteDependencyViolation
from deptry.violations.transitive import TransitiveDependencyViolation
from deptry.violations.unused import UnusedDependencyViolation

__all__ = (
"MisplacedDevDependencyViolation",
"MissingDependencyViolation",
"ObsoleteDependencyViolation",
"UnusedDependencyViolation",
"TransitiveDependencyViolation",
"Violation",
)
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@


@dataclass
class ObsoleteDependencyViolation(Violation):
class UnusedDependencyViolation(Violation):
error_code: ClassVar[str] = "DEP002"
error_template: ClassVar[str] = "'{name}' defined as a dependency but not used in the codebase"
issue: Dependency
Expand Down
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
[![PyPI - Downloads](https://img.shields.io/pypi/dm/deptry)](https://pypistats.org/packages/deptry)
[![License](https://img.shields.io/github/license/fpgmaas/deptry)](https://img.shields.io/github/license/fpgmaas/deptry)

_deptry_ is a command line tool to check for issues with dependencies in a Python project, such as obsolete or missing dependencies. It supports the following types of projects:
_deptry_ is a command line tool to check for issues with dependencies in a Python project, such as unused or missing dependencies. It supports the following types of projects:

- Projects that use [Poetry](https://python-poetry.org/) and a corresponding `pyproject.toml` file
- Projects that use [PDM](https://pdm.fming.dev/latest/) and a corresponding `pyproject.toml` file
Expand Down
10 changes: 5 additions & 5 deletions docs/issues-detection.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
_deptry_ looks for the following issues in dependencies:

- [Missing dependencies (DEP001)](#missing-dependencies-dep001)
- [Obsolete dependencies (DEP002)](#obsolete-dependencies-dep002)
- [Unused dependencies (DEP002)](#unused-dependencies-dep002)
- [Transitive dependencies (DEP003)](#transitive-dependencies-dep003)
- [Misplaced development dependencies (DEP004)](#misplaced-development-dependencies-dep004)

Expand Down Expand Up @@ -44,15 +44,15 @@ To fix the issue, `httpx` should be added to `[project.dependencies]`:
dependencies = ["httpx==0.23.1"]
```

## Obsolete dependencies (DEP002)
## Unused dependencies (DEP002)

Dependencies that are required in a project, but are not used within the codebase.

### Configuration

This check can be disabled with [Skip obsolete](usage.md#skip-obsolete) option.
This check can be disabled with [Skip unused](usage.md#skip-unused) option.

Specific dependencies can be ignored with [Ignore obsolete](usage.md#ignore-obsolete) option.
Specific dependencies can be ignored with [Ignore unused](usage.md#ignore-unused) option.

### Example

Expand All @@ -76,7 +76,7 @@ def make_http_request():
return httpx.get("https://example.com")
```

_deptry_ will report `requests` as an obsolete dependency because it is not used in the project.
_deptry_ will report `requests` as an unused dependency because it is not used in the project.

To fix the issue, `requests` should be removed from `[project.dependencies]`:

Expand Down
26 changes: 13 additions & 13 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,22 +190,22 @@ ignore_missing = ["pip", "tomllib"]
deptry . --ignore-missing "pip,tomllib"
```

#### Ignore obsolete
#### Ignore unused

List of packages to ignore when running the check for [Obsolete dependencies (DEP002)](issues-detection.md#obsolete-dependencies-dep002).
List of packages to ignore when running the check for [Unused dependencies (DEP002)](issues-detection.md#unused-dependencies-dep002).

- Type: `List[str]`
- Default: `[]`
- `pyproject.toml` option name: `ignore_obsolete`
- CLI option name: `--ignore-obsolete` (short: `-io`)
- `pyproject.toml` option name: `ignore_unused`
- CLI option name: `--ignore-unused` (short: `-io`)
- `pyproject.toml` example:
```toml
[tool.deptry]
ignore_obsolete = ["uvicorn", "uvloop"]
ignore_unused = ["uvicorn", "uvloop"]
```
- CLI example:
```shell
deptry . --ignore-obsolete "uvicorn,uvloop"
deptry . --ignore-unused "uvicorn,uvloop"
```

#### Ignore transitive
Expand Down Expand Up @@ -280,22 +280,22 @@ skip_missing = true
deptry . --skip-missing
```

#### Skip obsolete
#### Skip unused

Disable the check for [Obsolete dependencies (DEP002)](issues-detection.md#obsolete-dependencies-dep002).
Disable the check for [Unused dependencies (DEP002)](issues-detection.md#unused-dependencies-dep002).

- Type: `bool`
- Default: `False`
- `pyproject.toml` option name: `skip_obsolete`
- CLI option name: `--skip-obsolete`
- `pyproject.toml` option name: `skip_unused`
- CLI option name: `--skip-unused`
- `pyproject.toml` example:
```toml
[tool.deptry]
skip_obsolete = true
skip_unused = true
```
- CLI example:
```shell
deptry . --skip-obsolete
deptry . --skip-unused
```

#### Skip transitive
Expand Down Expand Up @@ -471,7 +471,7 @@ This however is not always sufficient. A situation may occur where a package is
not installed because it is optional and unused in the current installation.
Then when the package name doesn't directly translate to the top level module
name, or there are more top level modules names, Deptry may report both
obsolete packages, and missing packages. A concrete example is deptry reporting obsolete (optional) dependency
unused packages, and missing packages. A concrete example is deptry reporting unused (optional) dependency
`foo-python`, and missing package `foo`, while package `foo-python` would
install top level module `foo`, if it were installed.

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[tool.poetry]
name = "deptry"
version = "0.0.1"
description = "A command line utility to check for obsolete, missing and transitive dependencies in a Python project."
description = "A command line utility to check for unused, missing and transitive dependencies in a Python project."
authors = ["Florian Maas <fpgmaas@gmail.com>"]
maintainers = ["Mathieu Kniewallner <mathieu.kniewallner@gmail.com>"]
repository = "https://github.com/fpgmaas/deptry"
Expand Down
Loading

0 comments on commit 133a9cc

Please sign in to comment.