From 6ddf92c34fcb34bdd9ef5ff8c28577395fa12a27 Mon Sep 17 00:00:00 2001 From: Mathieu Kniewallner Date: Sat, 14 Sep 2024 11:33:30 +0200 Subject: [PATCH] Revert "feat(module): use `packages_distributions`" This reverts commit 4d229ae3511dd2d4240acceef8442b35ed7aa263. --- python/deptry/module.py | 41 +++++++++---------- .../violations/dep001_missing/finder.py | 2 +- .../deptry/violations/dep002_unused/finder.py | 10 ++--- .../violations/dep003_transitive/finder.py | 6 +-- .../violations/dep004_misplaced_dev/finder.py | 18 ++++---- 5 files changed, 37 insertions(+), 40 deletions(-) diff --git a/python/deptry/module.py b/python/deptry/module.py index d438627c..e4221a67 100644 --- a/python/deptry/module.py +++ b/python/deptry/module.py @@ -20,7 +20,7 @@ class Module: name: The name of the imported module. standard_library: Whether the module is part of the Python standard library. local_module: Whether the module is a local module. - packages: The names of the packages that contain the module. + package: The name of the package that contains the module. top_levels: A list of dependencies that contain this module in their top-level module names. This can be multiple, e.g. `google-cloud-api` and `google-cloud-bigquery` both have `google` in their top-level module names. @@ -33,7 +33,7 @@ class Module: name: str standard_library: bool = False local_module: bool = False - packages: list[str] | None = None + package: str | None = None top_levels: list[str] | None = None dev_top_levels: list[str] | None = None is_provided_by_dependency: bool | None = None @@ -97,24 +97,31 @@ def build(self) -> Module: if self._is_local_module(): return Module(self.name, local_module=True) - packages = self._get_package_names_from_metadata() + package = self._get_package_name_from_metadata() top_levels = self._get_corresponding_top_levels_from(self.dependencies) dev_top_levels = self._get_corresponding_top_levels_from(self.dev_dependencies) - is_provided_by_dependency = self._has_matching_dependency(packages, top_levels) - is_provided_by_dev_dependency = self._has_matching_dev_dependency(packages, dev_top_levels) - + is_provided_by_dependency = self._has_matching_dependency(package, top_levels) + is_provided_by_dev_dependency = self._has_matching_dev_dependency(package, dev_top_levels) return Module( self.name, - packages=packages, + package=package, top_levels=top_levels, dev_top_levels=dev_top_levels, is_provided_by_dependency=is_provided_by_dependency, is_provided_by_dev_dependency=is_provided_by_dev_dependency, ) - def _get_package_names_from_metadata(self) -> list[str] | None: - return importlib_metadata.packages_distributions().get(self.name) + def _get_package_name_from_metadata(self) -> str | None: + """ + Most packages simply have a field called "Name" in their metadata. This method extracts that field. + """ + try: + name: str = importlib_metadata.metadata(self.name)["Name"] + except importlib_metadata.PackageNotFoundError: + return None + else: + return name def _get_corresponding_top_levels_from(self, dependencies: list[Dependency]) -> list[str]: """ @@ -139,23 +146,15 @@ def _is_local_module(self) -> bool: """ return self.name in self.local_modules - def _has_matching_dependency(self, packages: list[str] | None, top_levels: list[str]) -> bool: + def _has_matching_dependency(self, package: str | None, top_levels: list[str]) -> bool: """ Check if this module is provided by a listed dependency. This is the case if either the package name that was found in the metadata is listed as a dependency, or if we found a top-level module name match earlier. """ - if not packages: - return False + return package and (package in [dep.name for dep in self.dependencies]) or len(top_levels) > 0 - return any(package in [dep.name for dep in self.dependencies] or len(top_levels) > 0 for package in packages) - - def _has_matching_dev_dependency(self, packages: list[str] | None, dev_top_levels: list[str]) -> bool: + def _has_matching_dev_dependency(self, package: str | None, dev_top_levels: list[str]) -> bool: """ Same as _has_matching_dependency, but for development dependencies. """ - if not packages: - return False - - return any( - package in [dep.name for dep in self.dev_dependencies] or len(dev_top_levels) > 0 for package in packages - ) + return package and (package in [dep.name for dep in self.dev_dependencies]) or len(dev_top_levels) > 0 diff --git a/python/deptry/violations/dep001_missing/finder.py b/python/deptry/violations/dep001_missing/finder.py index 64dfaa66..893b801a 100644 --- a/python/deptry/violations/dep001_missing/finder.py +++ b/python/deptry/violations/dep001_missing/finder.py @@ -40,7 +40,7 @@ def find(self) -> list[Violation]: def _is_missing(self, module: Module) -> bool: if any([ - module.packages is not None, + module.package is not None, module.is_provided_by_dependency, module.is_provided_by_dev_dependency, module.local_module, diff --git a/python/deptry/violations/dep002_unused/finder.py b/python/deptry/violations/dep002_unused/finder.py index 0dc3a01d..f364e39a 100644 --- a/python/deptry/violations/dep002_unused/finder.py +++ b/python/deptry/violations/dep002_unused/finder.py @@ -53,12 +53,10 @@ def _is_unused(self, dependency: Dependency) -> bool: return True def _dependency_found_in_imported_modules(self, dependency: Dependency) -> bool: - for module_with_locations in self.imported_modules_with_locations: - if module_with_locations.module.packages: - for package in module_with_locations.module.packages: - if package == dependency.name: - return True - return False + return any( + module_with_locations.module.package == dependency.name + for module_with_locations in self.imported_modules_with_locations + ) def _any_of_the_top_levels_imported(self, dependency: Dependency) -> bool: if not dependency.top_levels: diff --git a/python/deptry/violations/dep003_transitive/finder.py b/python/deptry/violations/dep003_transitive/finder.py index 1a1d1109..d103a102 100644 --- a/python/deptry/violations/dep003_transitive/finder.py +++ b/python/deptry/violations/dep003_transitive/finder.py @@ -48,7 +48,7 @@ def find(self) -> list[Violation]: def _is_transitive(self, module: Module) -> bool: if any([ - module.packages is None, + module.package is None, module.is_provided_by_dependency, module.is_provided_by_dev_dependency, module.local_module, @@ -56,8 +56,8 @@ def _is_transitive(self, module: Module) -> bool: return False if module.name in self.ignored_modules: - logging.debug("Dependency '%s' found to be a transitive dependency, but ignoring.", module.packages) + logging.debug("Dependency '%s' found to be a transitive dependency, but ignoring.", module.package) return False - logging.debug("Dependency '%s' marked as a transitive dependency.", module.packages) + logging.debug("Dependency '%s' marked as a transitive dependency.", module.package) return True diff --git a/python/deptry/violations/dep004_misplaced_dev/finder.py b/python/deptry/violations/dep004_misplaced_dev/finder.py index a1a2c2a5..62af53d3 100644 --- a/python/deptry/violations/dep004_misplaced_dev/finder.py +++ b/python/deptry/violations/dep004_misplaced_dev/finder.py @@ -40,15 +40,15 @@ def find(self) -> list[Violation]: continue logging.debug("Scanning module %s...", module.name) - corresponding_package_names = self._get_package_names(module) + corresponding_package_name = self._get_package_name(module) - if corresponding_package_names and self._is_development_dependency(module, corresponding_package_names): + if corresponding_package_name and self._is_development_dependency(module, corresponding_package_name): for location in module_with_locations.locations: misplaced_dev_dependencies.append(self.violation(module, location)) return misplaced_dev_dependencies - def _is_development_dependency(self, module: Module, corresponding_package_names: list[str]) -> bool: + def _is_development_dependency(self, module: Module, corresponding_package_name: str) -> bool: # Module can be provided both by a regular and by a development dependency. # Only continue if module is ONLY provided by a dev dependency. if not module.is_provided_by_dev_dependency or module.is_provided_by_dependency: @@ -57,16 +57,16 @@ def _is_development_dependency(self, module: Module, corresponding_package_names if module.name in self.ignored_modules: logging.debug( "Dependency '%s' found to be a misplaced development dependency, but ignoring.", - corresponding_package_names, + corresponding_package_name, ) return False - logging.debug("Dependency '%s' marked as a misplaced development dependency.", corresponding_package_names) + logging.debug("Dependency '%s' marked as a misplaced development dependency.", corresponding_package_name) return True - def _get_package_names(self, module: Module) -> list[str] | None: - if module.packages: - return module.packages + def _get_package_name(self, module: Module) -> str | None: + if module.package: + return module.package if module.dev_top_levels: if len(module.dev_top_levels) > 1: logging.debug( @@ -79,5 +79,5 @@ def _get_package_names(self, module: Module) -> list[str] | None: module.name, ) else: - return module.dev_top_levels + return module.dev_top_levels[0] return None