CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pipdeptree

Command line utility to show dependency tree of packages.

Pending
Overview
Eval results
Files

validation.mddocs/

Dependency Validation

Validates dependency trees to identify conflicting versions and circular dependencies with detailed reporting and configurable warning levels.

Capabilities

Main Validation Function

Primary validation entry point that checks for conflicts and cycles.

def validate(tree: PackageDAG) -> None:
    """
    Validate the dependency tree for conflicts and circular dependencies.
    
    Prints warnings to stderr if conflicts or cycles are found and warnings are enabled.
    The behavior depends on the current WarningPrinter configuration.
    
    Parameters:
    - tree: PackageDAG to validate
    """

Conflict Detection

Identifies packages with conflicting version requirements.

def conflicting_deps(tree: PackageDAG) -> dict[DistPackage, list[ReqPackage]]:
    """
    Return dependencies which are not present or conflict with requirements.
    
    Finds cases where:
    - A package requires version X but version Y is installed
    - A required package is missing entirely
    
    Parameters:
    - tree: The requirements tree to analyze
    
    Returns:
    Dictionary mapping packages to their conflicting requirements
    """

Cycle Detection

Detects circular dependencies in the dependency graph.

def cyclic_deps(tree: PackageDAG) -> list[list[Package]]:
    """
    Return cyclic dependencies as list of lists.
    
    Each inner list represents one dependency cycle, showing the path
    that creates the circular reference.
    
    Parameters:
    - tree: Package dependency tree to analyze
    
    Returns:
    List of dependency cycles, where each cycle is a list of Package objects
    """

Text Rendering Functions

Functions to format validation results for display.

def render_conflicts_text(conflicts: dict[DistPackage, list[ReqPackage]]) -> None:
    """
    Print conflicts in a human-readable format to stderr.
    
    Output format:
    * package==version
     - conflicting_req [required: >=1.0, installed: 0.9]
    """

def render_cycles_text(cycles: list[list[Package]]) -> None:
    """
    Print circular dependencies in a human-readable format to stderr.
    
    Output format:
    * package_a => package_b => package_c => package_a
    """

Usage Examples

Basic Validation

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

# Create dependency tree and validate
distributions = get_installed_distributions()
tree = PackageDAG.from_pkgs(distributions)

# Validate for conflicts and cycles (prints warnings if found)
validate(tree)

Manual Conflict Checking

from pipdeptree._validate import conflicting_deps, render_conflicts_text

# Check for conflicts manually
conflicts = conflicting_deps(tree)

if conflicts:
    print("Found conflicting dependencies:")
    render_conflicts_text(conflicts)
    
    # Process conflicts programmatically
    for package, conflicting_reqs in conflicts.items():
        print(f"\nPackage {package.project_name} has conflicts:")
        for req in conflicting_reqs:
            print(f"  - {req.project_name}: required {req.version_spec}, "
                  f"installed {req.installed_version}")

Manual Cycle Detection

from pipdeptree._validate import cyclic_deps, render_cycles_text

# Check for circular dependencies
cycles = cyclic_deps(tree)

if cycles:
    print("Found circular dependencies:")
    render_cycles_text(cycles)
    
    # Process cycles programmatically
    for i, cycle in enumerate(cycles, 1):
        cycle_names = [pkg.project_name for pkg in cycle]
        print(f"Cycle {i}: {' -> '.join(cycle_names)}")

Validation with Custom Warning Control

from pipdeptree._warning import get_warning_printer, WarningType
from pipdeptree._validate import validate

# Configure warning behavior
warning_printer = get_warning_printer()
warning_printer.warning_type = WarningType.FAIL  # Exit with error code on warnings

# Validate (will now fail with exit code 1 if issues found)
validate(tree)

# Check if validation failed
if warning_printer.has_warned_with_failure():
    print("Validation failed with conflicts or cycles")

Conflict Types

The validation system detects several types of conflicts:

Version Conflicts

When installed version doesn't satisfy requirement specification:

* Django==3.0.0
 - requests [required: >=2.25.0, installed: 2.20.0]

Missing Dependencies

When a required package is not installed:

* mypackage==1.0.0
 - missing-dep [required: >=1.0, installed: ?]

Invalid Requirements

When package metadata contains malformed requirement strings (logged separately):

Invalid requirement strings found for the following distributions:
mypackage
  Skipping "invalid>=requirement string"

Cycle Detection Algorithm

The cycle detection uses depth-first search to identify circular dependencies:

  1. For each package in the tree, start a DFS traversal
  2. Track visited nodes to detect when we return to a previously seen package
  3. Record the path when a cycle is found
  4. Return all unique cycles found in the dependency graph

Cycles are returned as lists showing the dependency path that creates the circular reference.

Integration with Warning System

Validation integrates with pipdeptree's warning system:

  • WarningType.SILENCE: No validation output, always return 0
  • WarningType.SUPPRESS: Print warnings but return 0
  • WarningType.FAIL: Print warnings and return 1 if any found

The validation results are automatically printed to stderr when warnings are enabled, and the return code is determined by the warning configuration.

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