From af6ee55359ac0b8d51c50093153ad0bc68d4f6f8 Mon Sep 17 00:00:00 2001 From: esynr3z Date: Mon, 22 Jan 2024 08:08:01 +0300 Subject: [PATCH] feat: add special named tuple to represent package dependency --- pip_hdl/dependencies.py | 4 ++-- pip_hdl/metainfo.py | 22 ++++++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/pip_hdl/dependencies.py b/pip_hdl/dependencies.py index 8b1f0a1..5978f5b 100644 --- a/pip_hdl/dependencies.py +++ b/pip_hdl/dependencies.py @@ -43,7 +43,7 @@ def __init__(self, packages: List[PackageMetaInfo]) -> None: # link nodes for node in self.nodes.values(): - node.add_upstreams([self.nodes[d.name] for d in node.metainfo.dependencies]) + node.add_upstreams([self.nodes[d.metainfo.name] for d in node.metainfo.dependencies]) def __iter__(self) -> Iterator[Node]: """Iterate through nodes in dependency-aware order.""" @@ -85,7 +85,7 @@ def _packages_to_nodes(self, packages: Iterable[PackageMetaInfo]) -> Iterator[No """Convert packages and all their dependencies to graph nodes recursivelly.""" for pkg in packages: yield Node(pkg) - yield from self._packages_to_nodes(pkg.dependencies) + yield from self._packages_to_nodes([d.metainfo for d in pkg.dependencies]) def render_dag(self, **kwargs: Any) -> Path: """Represent current graph as directed acyclic graph using 'graphviz'. diff --git a/pip_hdl/metainfo.py b/pip_hdl/metainfo.py index cb7470d..bdb336c 100644 --- a/pip_hdl/metainfo.py +++ b/pip_hdl/metainfo.py @@ -3,8 +3,9 @@ from __future__ import annotations import pkgutil -from importlib import metadata, import_module +from importlib import import_module, metadata from pathlib import Path +from types import ModuleType from typing import List, NamedTuple, Optional from packaging.requirements import Requirement @@ -17,6 +18,14 @@ class EnvVar(NamedTuple): value: str +class PackageDependency(NamedTuple): + """Descriptor for a HDL package dependency.""" + + spec: str # packaging.requirements.Requirement friendly specification + module: ModuleType + metainfo: PackageMetaInfo + + class PackageMetaInfo: """HDL package meta information.""" @@ -28,14 +37,14 @@ def __init__(self, py_pkg_name: str) -> None: """Init package meta-information.""" self.name: str = py_pkg_name - self._dependencies: Optional[List[PackageMetaInfo]] = None + self._dependencies: Optional[List[PackageDependency]] = None self._filelist: Optional[Path] = None self._sources_dir: Optional[Path] = None self._sources_var: Optional[EnvVar] = None self._all_sources_vars: Optional[List[EnvVar]] = None @property - def dependencies(self) -> List[PackageMetaInfo]: + def dependencies(self) -> List[PackageDependency]: """Dependencies of the current package. Dependency search is based on the presense of `metainfo` attribute within top-module. @@ -49,8 +58,9 @@ def dependencies(self) -> List[PackageMetaInfo]: try: module = import_module(Requirement(spec).name) if isinstance(module.metainfo, PackageMetaInfo): - self._dependencies.append(module.metainfo) - except (ImportError, AttributeError) as _: + dependency = PackageDependency(spec=spec, module=module, metainfo=module.metainfo) + self._dependencies.append(dependency) + except (ImportError, AttributeError) as _: # noqa pass return self._dependencies @@ -94,6 +104,6 @@ def all_sources_vars(self) -> List[EnvVar]: if self._all_sources_vars is None: self._all_sources_vars = [] for d in self.dependencies: - self._all_sources_vars.extend(d.all_sources_vars) + self._all_sources_vars.extend(d.metainfo.all_sources_vars) self._all_sources_vars.append(self.sources_var) return self._all_sources_vars