Skip to content

Commit

Permalink
chore: add more Ruff rules (#379)
Browse files Browse the repository at this point in the history
* chore(ruff): enable `flake8-logging-format`

* chore: comply with `flake8-logging-format`

* chore(ruff): enable `flake8-pytest-style`

* chore(ruff): enable `flake8-use-pathlib`

* chore: comply with `flake8-use-pathlib`

* test: use `touch` to create files

* chore(ruff): enable `flake8-blind-except`

* chore(ruff): enable `pep8-naming`
  • Loading branch information
mkniewallner authored May 9, 2023
1 parent b5102b1 commit 18dad91
Show file tree
Hide file tree
Showing 28 changed files with 180 additions and 136 deletions.
2 changes: 1 addition & 1 deletion deptry/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ def _get_stdlib_modules() -> frozenset[str]:
def _log_config(self) -> None:
logging.debug("Running with the following configuration:")
for key, value in vars(self).items():
logging.debug(f"{key}: {value}")
logging.debug("%s: %s", key, value)
logging.debug("")

@staticmethod
Expand Down
8 changes: 6 additions & 2 deletions deptry/dependency.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,12 @@ def _get_top_levels(
# we'll guess the name.
module_name = name.replace("-", "_").lower()
logging.warning(
f"Assuming the corresponding module name of package {self.name!r} is {module_name!r}. Install the package"
" or configure a package_module_name_map entry to override this behaviour."
(
"Assuming the corresponding module name of package %r is %r. Install the package or configure a"
" package_module_name_map entry to override this behaviour."
),
self.name,
module_name,
)
return {module_name}

Expand Down
6 changes: 4 additions & 2 deletions deptry/dependency_getter/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ def get(self) -> DependenciesExtract:

@staticmethod
def _log_dependencies(dependencies: list[Dependency], is_dev: bool = False) -> None:
logging.debug(f"The project contains the following {'dev ' if is_dev else ''}dependencies:")
logging.debug("The project contains the following %s:", "dev dependencies" if is_dev else "dependencies")

for dependency in dependencies:
logging.debug(str(dependency))
logging.debug(dependency)

logging.debug("")
12 changes: 7 additions & 5 deletions deptry/dependency_getter/requirements_txt.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,20 @@ def _scan_for_dev_requirements_files(self) -> list[str]:
"""
dev_requirements_files = [file_name for file_name in self.requirements_txt_dev if file_name in os.listdir()]
if dev_requirements_files:
logging.debug(f"Found files with development requirements! {dev_requirements_files}")
logging.debug("Found files with development requirements! %s", dev_requirements_files)
return dev_requirements_files

def _get_dependencies_from_requirements_file(self, file_name: str, is_dev: bool = False) -> list[Dependency]:
logging.debug(f"Scanning {file_name} for {'dev ' if is_dev else ''}dependencies")
logging.debug("Scanning %s for %s", file_name, "dev dependencies" if is_dev else "dependencies")
dependencies = []

with open(file_name) as f:
file_path = Path(file_name)

with file_path.open() as f:
data = f.readlines()

for line in data:
dependency = self._extract_dependency_from_line(line, Path(file_name))
dependency = self._extract_dependency_from_line(line, file_path)
if dependency:
dependencies.append(dependency)

Expand Down Expand Up @@ -132,5 +134,5 @@ def _extract_name_from_url(line: str) -> str | None:
if match:
return match.group(1)

logging.warning(f"Could not parse dependency name from url {line}")
logging.warning("Could not parse dependency name from url %s", line)
return None
12 changes: 4 additions & 8 deletions deptry/dependency_specification_detector.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
from __future__ import annotations

import logging
import os
from enum import Enum
from typing import TYPE_CHECKING
from pathlib import Path

from deptry.exceptions import DependencySpecificationNotFoundError
from deptry.utils import load_pyproject_toml

if TYPE_CHECKING:
from pathlib import Path


class DependencyManagementFormat(Enum):
PDM = "pdm"
Expand Down Expand Up @@ -105,10 +101,10 @@ def _project_uses_pep_621(self) -> bool:
return True

def _project_uses_requirements_txt(self) -> bool:
check = any(os.path.isfile(requirements_txt) for requirements_txt in self.requirements_txt)
check = any(Path(requirements_txt).is_file() for requirements_txt in self.requirements_txt)
if check:
logging.debug(
f"Dependency specification found in '{', '.join(self.requirements_txt)}'. Will use this to determine"
" the project's dependencies.\n"
"Dependency specification found in '%s'. Will use this to determine the project's dependencies.\n",
", ".join(self.requirements_txt),
)
return check
7 changes: 6 additions & 1 deletion deptry/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
from pathlib import Path


class DependencySpecificationNotFoundError(FileNotFoundError):
def __init__(self, requirements_txt: tuple[str, ...]) -> None:
Expand All @@ -15,7 +20,7 @@ def __init__(self) -> None:


class PyprojectFileNotFoundError(FileNotFoundError):
def __init__(self, directory: str) -> None:
def __init__(self, directory: Path) -> None:
super().__init__(f"No file `pyproject.toml` found in directory {directory}")


Expand Down
8 changes: 4 additions & 4 deletions deptry/imports/extract.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@


def get_imported_modules_for_list_of_files(list_of_files: list[Path]) -> dict[str, list[Location]]:
logging.info(f"Scanning {len(list_of_files)} file{'s' if len(list_of_files)>1 else ''}...")
logging.info("Scanning %d %s...", len(list_of_files), "files" if len(list_of_files) > 1 else "file")

modules: dict[str, list[Location]] = defaultdict(list)

Expand All @@ -23,17 +23,17 @@ def get_imported_modules_for_list_of_files(list_of_files: list[Path]) -> dict[st
for location in locations:
modules[module].append(location)

logging.debug(f"All imported modules: {modules}\n")
logging.debug("All imported modules: %s\n", modules)

return modules


def get_imported_modules_from_file(path_to_file: Path) -> dict[str, list[Location]]:
logging.debug(f"Scanning {path_to_file}...")
logging.debug("Scanning %s...", path_to_file)

modules = _get_extractor_class(path_to_file)(path_to_file).extract_imports()

logging.debug(f"Found the following imports in {str(path_to_file)}: {modules}")
logging.debug("Found the following imports in %s: %s", path_to_file, modules)

return modules

Expand Down
2 changes: 1 addition & 1 deletion deptry/imports/extractors/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ def _extract_imports_from_ast(self, tree: ast.AST) -> dict[str, list[Location]]:

@staticmethod
def _get_file_encoding(file: Path) -> str:
with open(file, "rb") as f:
with file.open("rb") as f:
return chardet.detect(f.read())["encoding"]
6 changes: 3 additions & 3 deletions deptry/imports/extractors/notebook_import_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ def extract_imports(self) -> dict[str, list[Location]]:
@classmethod
def _read_ipynb_file(cls, path_to_ipynb: Path) -> dict[str, Any] | None:
try:
with open(path_to_ipynb) as ipynb_file:
with path_to_ipynb.open() as ipynb_file:
notebook: dict[str, Any] = json.load(ipynb_file)
except (UnicodeDecodeError, ValueError):
try:
with open(path_to_ipynb, encoding=cls._get_file_encoding(path_to_ipynb)) as ipynb_file:
with path_to_ipynb.open(encoding=cls._get_file_encoding(path_to_ipynb)) as ipynb_file:
notebook = json.load(ipynb_file, strict=False)
except UnicodeDecodeError:
logging.warning(f"Warning: File {path_to_ipynb} could not be decoded. Skipping...")
logging.warning("Warning: File %s could not be decoded. Skipping...", path_to_ipynb)
return None
return notebook

Expand Down
6 changes: 3 additions & 3 deletions deptry/imports/extractors/python_import_extractor.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ class PythonImportExtractor(ImportExtractor):
def extract_imports(self) -> dict[str, list[Location]]:
"""Extract all imported top-level modules from the Python file."""
try:
with open(self.file) as python_file:
with self.file.open() as python_file:
tree = ast.parse(python_file.read(), str(self.file))
except (UnicodeDecodeError, ValueError):
try:
with open(self.file, encoding=self._get_file_encoding(self.file)) as python_file:
with self.file.open(encoding=self._get_file_encoding(self.file)) as python_file:
tree = ast.parse(python_file.read(), str(self.file))
except UnicodeDecodeError:
logging.warning(f"Warning: File {self.file} could not be decoded. Skipping...")
logging.warning("Warning: File %s could not be decoded. Skipping...", self.file)
return {}

return self._extract_imports_from_ast(tree)
15 changes: 8 additions & 7 deletions deptry/issues_finder/misplaced_dev.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def find(self) -> list[Violation]:
for module_with_locations in self.imported_modules_with_locations:
module = module_with_locations.module

logging.debug(f"Scanning module {module.name}...")
logging.debug("Scanning module %s...", module.name)
corresponding_package_name = self._get_package_name(module)

if corresponding_package_name and self._is_development_dependency(module, corresponding_package_name):
Expand All @@ -50,12 +50,12 @@ def _is_development_dependency(self, module: Module, corresponding_package_name:

if module.name in self.ignored_modules:
logging.debug(
f"Dependency '{corresponding_package_name}' found to be a misplaced development dependency, but"
" ignoring."
"Dependency '%s' found to be a misplaced development dependency, but ignoring.",
corresponding_package_name,
)
return False

logging.debug(f"Dependency '{corresponding_package_name}' marked as a misplaced development dependency.")
logging.debug("Dependency '%s' marked as a misplaced development dependency.", corresponding_package_name)
return True

def _get_package_name(self, module: Module) -> str | None:
Expand All @@ -64,12 +64,13 @@ def _get_package_name(self, module: Module) -> str | None:
if module.dev_top_levels:
if len(module.dev_top_levels) > 1:
logging.debug(
f"Module {module.name} is found in the top-level module names of multiple development dependencies."
" Skipping."
"Module %s is found in the top-level module names of multiple development dependencies. Skipping.",
module.name,
)
elif len(module.dev_top_levels) == 0:
logging.debug(
f"Module {module.name} has no metadata and it is not found in any top-level module names. Skipping."
"Module %s has no metadata and it is not found in any top-level module names. Skipping.",
module.name,
)
else:
return module.dev_top_levels[0]
Expand Down
6 changes: 3 additions & 3 deletions deptry/issues_finder/missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def find(self) -> list[Violation]:
for module_with_locations in self.imported_modules_with_locations:
module = module_with_locations.module

logging.debug(f"Scanning module {module.name}...")
logging.debug("Scanning module %s...", module.name)

if self._is_missing(module):
for location in module_with_locations.locations:
Expand All @@ -45,8 +45,8 @@ def _is_missing(self, module: Module) -> bool:
return False

if module.name in self.ignored_modules:
logging.debug(f"Identified module '{module.name}' as a missing dependency, but ignoring.")
logging.debug("Identified module '%s' as a missing dependency, but ignoring.", module.name)
return False

logging.debug(f"No package found to import module '{module.name}' from. Marked as a missing dependency.")
logging.debug("No package found to import module '%s' from. Marked as a missing dependency.", module.name)
return True
6 changes: 3 additions & 3 deletions deptry/issues_finder/obsolete.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def find(self) -> list[Violation]:
obsolete_dependencies: list[Violation] = []

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

if self._is_obsolete(dependency):
obsolete_dependencies.append(
Expand All @@ -46,10 +46,10 @@ def _is_obsolete(self, dependency: Dependency) -> bool:
return False

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

logging.debug(f"Dependency '{dependency.name}' does not seem to be used.")
logging.debug("Dependency '%s' does not seem to be used.", dependency.name)
return True

def _dependency_found_in_imported_modules(self, dependency: Dependency) -> bool:
Expand Down
6 changes: 3 additions & 3 deletions deptry/issues_finder/transitive.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def find(self) -> list[Violation]:
for module_with_locations in self.imported_modules_with_locations:
module = module_with_locations.module

logging.debug(f"Scanning module {module.name}...")
logging.debug("Scanning module %s...", module.name)

if self._is_transitive(module):
# `self._is_transitive` only returns `True` if the package is not None.
Expand All @@ -53,8 +53,8 @@ def _is_transitive(self, module: Module) -> bool:
return False

if module.name in self.ignored_modules:
logging.debug(f"Dependency '{module.package}' found to be a transitive dependency, but ignoring.")
logging.debug("Dependency '%s' found to be a transitive dependency, but ignoring.", module.package)
return False

logging.debug(f"Dependency '{module.package}' marked as a transitive dependency.")
logging.debug("Dependency '%s' marked as a transitive dependency.", module.package)
return True
3 changes: 2 additions & 1 deletion deptry/reporters/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import json
from dataclasses import dataclass
from pathlib import Path
from typing import TYPE_CHECKING

from deptry.reporters.base import Reporter
Expand Down Expand Up @@ -33,5 +34,5 @@ def report(self) -> None:
},
)

with open(self.json_output, "w", encoding="utf-8") as f:
with Path(self.json_output).open("w", encoding="utf-8") as f:
json.dump(output, f, ensure_ascii=False, indent=4)
5 changes: 2 additions & 3 deletions deptry/utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
from __future__ import annotations

import os
import sys
from pathlib import Path
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from pathlib import Path
from typing import Any


Expand All @@ -22,4 +21,4 @@ def load_pyproject_toml(config: Path) -> dict[str, Any]:
with config.open("rb") as pyproject_file:
return tomllib.load(pyproject_file)
except FileNotFoundError:
raise PyprojectFileNotFoundError(os.getcwd()) from None
raise PyprojectFileNotFoundError(Path.cwd()) from None
10 changes: 10 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ select = [
"YTT",
# flake8-bandit
"S",
# flake8-blind-except
"BLE",
# flake8-bugbear
"B",
# flake8-builtins
Expand All @@ -134,16 +136,24 @@ select = [
"C4",
# flake8-debugger
"T10",
# flake8-logging-format
"G",
# flake8-print
"T20",
# flake8-pytest-style
"PT",
# flake8-simplify
"SIM",
# flake8-type-checking
"TCH",
# flake8-use-pathlib
"PTH",
# isort
"I",
# mccabe
"C90",
# pep8-naming
"N",
# pycodestyle
"E", "W",
# pyflakes
Expand Down
3 changes: 1 addition & 2 deletions tests/functional/cli/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import os
import shlex
import subprocess
from pathlib import Path
Expand Down Expand Up @@ -480,7 +479,7 @@ def test_cli_with_no_ansi(project_builder: ToolSpecificProjectBuilder) -> None:
def test_cli_with_not_json_output(project_builder: ToolSpecificProjectBuilder) -> None:
with run_within_dir(project_builder("example_project", "poetry install --no-interaction --no-root")):
# Remove previously generated `report.json`.
os.remove("report.json")
Path("report.json").unlink()

result = subprocess.run(shlex.split("poetry run deptry ."), capture_output=True, text=True)

Expand Down
4 changes: 2 additions & 2 deletions tests/unit/dependency_getter/test_pdm.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def test_dependency_getter(tmp_path: Path) -> None:
"""

with run_within_dir(tmp_path):
with open("pyproject.toml", "w") as f:
with Path("pyproject.toml").open("w") as f:
f.write(fake_pyproject_toml)

getter = PDMDependencyGetter(
Expand Down Expand Up @@ -80,7 +80,7 @@ def test_dev_dependency_getter(tmp_path: Path) -> None:
"""

with run_within_dir(tmp_path):
with open("pyproject.toml", "w") as f:
with Path("pyproject.toml").open("w") as f:
f.write(fake_pyproject_toml)

dev_dependencies = PDMDependencyGetter(Path("pyproject.toml")).get().dev_dependencies
Expand Down
Loading

0 comments on commit 18dad91

Please sign in to comment.