CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pipdeptree

Command line utility to show dependency tree of packages.

Pending
Overview
Eval results
Files

data-models.mddocs/

Data Models

Core classes for representing packages, requirements, and dependency relationships in a hierarchical dependency tree structure.

Capabilities

Package Base Class

Abstract base class for all package wrapper objects.

class Package(ABC):
    """Abstract class for wrappers around objects that pip returns."""
    
    UNKNOWN_LICENSE_STR = "(Unknown license)"
    
    def __init__(self, project_name: str) -> None: ...
    
    def licenses(self) -> str:
        """
        Get license information for the package.
        
        Returns:
        License string in format "(license1, license2)" or "(Unknown license)"
        """
    
    @abstractmethod
    def render_as_root(self, *, frozen: bool) -> str: ...
    
    @abstractmethod
    def render_as_branch(self, *, frozen: bool) -> str: ...
    
    @abstractmethod
    def as_dict(self) -> dict[str, str]: ...
    
    def render(
        self,
        parent: DistPackage | ReqPackage | None = None,
        *,
        frozen: bool = False,
    ) -> str: ...

DistPackage Class

Wrapper for installed distribution packages with full metadata access.

class DistPackage(Package):
    """
    Wrapper class for importlib.metadata.Distribution instances.
    
    Parameters:
    - obj: importlib.metadata.Distribution to wrap over
    - req: optional ReqPackage object for reverse tree display
    """
    
    def __init__(self, obj: Distribution, req: ReqPackage | None = None) -> None: ...
    
    def requires(self) -> Iterator[Requirement]:
        """
        Return an iterator of the distribution's required dependencies.
        
        Yields:
        Requirement objects for dependencies that apply to current environment
        
        Raises:
        InvalidRequirementError: If metadata contains invalid requirement strings
        """
    
    @property
    def version(self) -> str:
        """The installed version of the package."""
    
    def unwrap(self) -> Distribution:
        """Exposes the internal importlib.metadata.Distribution object."""
    
    def as_requirement(self) -> ReqPackage:
        """Return a ReqPackage representation of this DistPackage."""
    
    def as_parent_of(self, req: ReqPackage | None) -> DistPackage:
        """
        Return a DistPackage instance associated to a requirement.
        
        This association is necessary for reversing the PackageDAG.
        """
    
    def as_dict(self) -> dict[str, str]:
        """
        Returns:
        Dictionary with keys: key, package_name, installed_version
        """

ReqPackage Class

Wrapper for requirement packages with version constraint information.

class ReqPackage(Package):
    """
    Wrapper class for Requirement instance.
    
    Parameters:
    - obj: The Requirement instance to wrap over
    - dist: optional importlib.metadata.Distribution instance for this requirement
    """
    
    UNKNOWN_VERSION = "?"
    
    def __init__(self, obj: Requirement, dist: DistPackage | None = None) -> None: ...
    
    @property
    def version_spec(self) -> str | None:
        """
        Version specification string from requirement.
        
        Returns:
        Comma-joined version specifiers (e.g., ">=1.0,<2.0") or None
        """
    
    @property
    def installed_version(self) -> str:
        """
        Currently installed version of the package.
        
        Returns:
        Version string or "?" if unknown/missing
        """
    
    def is_conflicting(self) -> bool:
        """
        Check if installed version conflicts with required version.
        
        Returns:
        True if installed version doesn't satisfy requirement or is missing
        """
    
    @property
    def is_missing(self) -> bool:
        """Check if package is missing (installed_version == "?")."""
    
    def as_dict(self) -> dict[str, str]:
        """
        Returns:
        Dictionary with keys: key, package_name, installed_version, required_version
        """

PackageDAG Class

Directed acyclic graph representing package dependencies using a mapping structure.

class PackageDAG(Mapping[DistPackage, list[ReqPackage]]):
    """
    Representation of Package dependencies as directed acyclic graph.
    
    The internal structure maps each package to its list of requirements:
    {package_a: [req_b, req_c],
     package_b: [req_d],
     package_c: [req_d, req_e],
     package_d: [req_e],
     package_e: []}
    """
    
    @classmethod
    def from_pkgs(cls, pkgs: list[Distribution]) -> PackageDAG:
        """
        Create PackageDAG from list of Distribution objects.
        
        Parameters:
        - pkgs: List of importlib.metadata.Distribution objects
        
        Returns:
        PackageDAG instance with dependency relationships mapped
        """
    
    def __init__(self, m: dict[DistPackage, list[ReqPackage]]) -> None: ...
    
    def filter_nodes(
        self,
        include: list[str] | None,
        exclude: set[str] | None,
        exclude_deps: bool = False
    ):
        """
        Filter the dependency tree to include/exclude specific packages.
        
        Parameters:
        - include: List of package patterns to include (supports wildcards)
        - exclude: Set of package patterns to exclude (supports wildcards)
        - exclude_deps: Whether to also exclude dependencies of excluded packages
        
        Returns:
        Filtered PackageDAG
        
        Raises:
        IncludeExcludeOverlapError: If include and exclude sets overlap
        IncludePatternNotFoundError: If include patterns not found
        """
    
    def reverse(self) -> ReversedPackageDAG:
        """
        Create reversed view showing which packages depend on each package.
        
        Returns:
        ReversedPackageDAG with inverted dependency relationships
        """
    
    def get_node_as_parent(self, key: str) -> DistPackage | None:
        """Get a package node by its canonical key."""
    
    # Standard Mapping interface methods
    def __getitem__(self, key: DistPackage) -> list[ReqPackage]: ...
    def __iter__(self) -> Iterator[DistPackage]: ...
    def __len__(self) -> int: ...

ReversedPackageDAG Class

Inverted view of the dependency graph showing reverse dependencies.

class ReversedPackageDAG(Mapping[ReqPackage, list[DistPackage]]):
    """
    Reversed representation where each requirement maps to packages that depend on it.
    """

Usage Examples

Creating and Working with PackageDAG

from pipdeptree._discovery import get_installed_distributions
from pipdeptree._models import PackageDAG

# Get installed packages and create dependency tree
distributions = get_installed_distributions()
tree = PackageDAG.from_pkgs(distributions)

# Filter to show only specific packages
filtered_tree = tree.filter_nodes(
    include=['django', 'requests*'],
    exclude=None
)

# Create reverse dependency view
reverse_tree = tree.reverse()

# Iterate through dependencies
for package, requirements in tree.items():
    print(f"{package.project_name}=={package.version}")
    for req in requirements:
        print(f"  requires {req.project_name} {req.version_spec}")

Working with Individual Packages

from pipdeptree._models import DistPackage, ReqPackage

# Access package information
for package, requirements in tree.items():
    # Get package metadata
    print(f"Package: {package.project_name}")
    print(f"Version: {package.version}")
    print(f"License: {package.licenses()}")
    
    # Check requirements
    for req in requirements:
        if req.is_conflicting():
            print(f"CONFLICT: {req.project_name}")
            print(f"  Required: {req.version_spec}")
            print(f"  Installed: {req.installed_version}")

Exceptions

class InvalidRequirementError(ValueError):
    """
    An invalid requirement string was found.
    
    When raising an exception, this should provide just the problem requirement string.
    """

class IncludeExcludeOverlapError(Exception):
    """Include and exclude sets passed as input violate mutual exclusivity requirement."""

class IncludePatternNotFoundError(Exception):
    """Include patterns weren't found when filtering a PackageDAG."""

Type Definitions

# Common type aliases used in the models
from importlib.metadata import Distribution, Requirement
from collections.abc import Iterator, Mapping
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from collections.abc import Iterator
    from importlib.metadata import Distribution

Install with Tessl CLI

npx tessl i tessl/pypi-pipdeptree

docs

cli-interface.md

data-models.md

environment-detection.md

index.md

output-rendering.md

package-discovery.md

validation.md

warning-system.md

tile.json