Python dependency management and packaging made easy.
—
Dependency resolution, lock file management, and repository handling. Provides complete control over project dependencies, package sources, and lock file operations for reproducible builds.
Poetry's lock file system ensures reproducible builds by recording exact versions and hashes of all dependencies.
class Locker:
"""
Lock file management for reproducible dependency resolution.
Handles poetry.lock file operations including reading locked packages,
updating lock data, and validating lock file freshness.
"""
def is_locked(self) -> bool:
"""
Check if project has a lock file.
Returns:
True if poetry.lock exists and is valid
"""
def is_fresh(self) -> bool:
"""
Check if lock file is up-to-date with pyproject.toml.
Returns:
True if lock file matches current dependencies
"""
def locked_repository(self) -> Repository:
"""
Get repository containing all locked packages.
Returns:
Repository with locked package versions
"""
def locked_packages(self) -> list:
"""
Get list of locked packages with metadata.
Returns:
List of locked packages with versions and hashes
"""
def set_lock_data(self, root, packages) -> None:
"""
Update lock file with new dependency data.
Args:
root: Root package information
packages: List of resolved packages
"""
def set_pyproject_data(self, data: dict) -> None:
"""
Set pyproject.toml data for lock file validation.
Args:
data: Pyproject configuration data
"""from poetry.factory import Factory
# Create Poetry instance
poetry = Factory().create_poetry()
locker = poetry.locker
# Check lock file status
if locker.is_locked():
print("Project has lock file")
if locker.is_fresh():
print("Lock file is up to date")
else:
print("Lock file needs updating")
# Get locked packages
locked_packages = locker.locked_packages()
for package in locked_packages:
print(f"{package.name}: {package.version}")
# Get locked repository
locked_repo = locker.locked_repository()
print(f"Locked repository has {len(locked_repo.packages)} packages")
else:
print("No lock file found")Manages multiple package repositories with priority handling and source resolution.
class Repository:
"""
Base repository class for package sources.
Provides interface for package discovery, metadata retrieval,
and dependency resolution from various sources.
"""
def find_packages(self, dependency) -> list:
"""
Find packages matching dependency specification.
Args:
dependency: Dependency specification
Returns:
List of matching packages
"""
def package(self, name: str, version: str):
"""
Get specific package by name and version.
Args:
name: Package name
version: Package version
Returns:
Package instance or None
"""
class RepositoryPool:
"""
Manages multiple package repositories with priority handling.
Coordinates package discovery across multiple sources with
configurable priority levels and fallback behavior.
"""
PRIMARY = "primary" # Primary repository priority
SUPPLEMENTAL = "supplemental" # Supplemental repository priority
EXPLICIT = "explicit" # Explicit repository priority
def add_repository(self, repository, priority: str = "supplemental") -> None:
"""
Add repository to pool with specified priority.
Args:
repository: Repository instance
priority: Repository priority level
"""
def has_primary_repositories(self) -> bool:
"""
Check if pool has primary repositories configured.
Returns:
True if primary repositories exist
"""
def find_packages(self, dependency) -> list:
"""
Find packages across all repositories in priority order.
Args:
dependency: Dependency specification
Returns:
List of packages from all sources
"""
class HTTPRepository(Repository):
"""
HTTP-based package repository (PyPI, private indexes).
Handles package discovery and metadata retrieval from
HTTP-based package indexes with authentication support.
"""
def __init__(self, name: str, url: str, config = None,
disable_cache: bool = False):
"""
Initialize HTTP repository.
Args:
name: Repository name
url: Repository URL
config: Configuration instance
disable_cache: Whether to disable caching
"""
class InstalledRepository(Repository):
"""
Repository representing currently installed packages.
Provides access to packages installed in the current
environment for dependency resolution and conflict detection.
"""
@classmethod
def load(cls, env, with_dependencies: bool = True):
"""
Load installed packages from environment.
Args:
env: Environment instance
with_dependencies: Whether to include dependencies
Returns:
Repository with installed packages
"""from poetry.factory import Factory
from poetry.repositories.http_repository import HTTPRepository
from poetry.repositories.installed_repository import InstalledRepository
# Create Poetry instance
poetry = Factory().create_poetry()
pool = poetry.pool
# Add custom repository
custom_repo = HTTPRepository(
name="custom",
url="https://my-repo.com/simple/",
config=poetry.config
)
pool.add_repository(custom_repo, priority="supplemental")
# Check repository configuration
if pool.has_primary_repositories():
print("Primary repositories configured")
# Get installed packages
env_manager = EnvManager(poetry.file.parent)
env = env_manager.get_system_env()
installed_repo = InstalledRepository.load(env)
print(f"Installed packages: {len(installed_repo.packages)}")Utilities for managing collections of packages with dependency analysis.
class PackageCollection:
"""
Collection of packages with dependency analysis utilities.
Provides methods for package organization, dependency traversal,
and conflict detection across package sets.
"""
def __init__(self, packages: list = None):
"""
Initialize package collection.
Args:
packages: Initial list of packages
"""
def add(self, package) -> None:
"""
Add package to collection.
Args:
package: Package to add
"""
def remove(self, package) -> None:
"""
Remove package from collection.
Args:
package: Package to remove
"""
def find_dependencies(self, package) -> list:
"""
Find dependencies of package within collection.
Args:
package: Package to analyze
Returns:
List of dependency packages
"""
def find_dependents(self, package) -> list:
"""
Find packages that depend on given package.
Args:
package: Package to analyze
Returns:
List of dependent packages
"""
class DependencyPackage:
"""
Package representation for dependency management.
Enhanced package class with dependency-specific metadata
and resolution information.
"""
def __init__(self, package, dependency):
"""
Initialize dependency package.
Args:
package: Base package instance
dependency: Dependency specification
"""
@property
def constraint(self) -> str:
"""Version constraint for this dependency."""
@property
def extras(self) -> list:
"""Optional extras for this dependency."""
@property
def marker(self) -> str:
"""Environment marker for conditional dependencies."""from poetry.packages.package_collection import PackageCollection
from poetry.factory import Factory
# Create Poetry instance and get dependencies
poetry = Factory().create_poetry()
dependencies = poetry.package.all_requires
# Create package collection
collection = PackageCollection()
# Add packages to collection
for dep in dependencies:
# Resolve dependency to actual package
packages = poetry.pool.find_packages(dep)
if packages:
collection.add(packages[0])
# Analyze dependencies
for package in collection:
deps = collection.find_dependencies(package)
dependents = collection.find_dependents(package)
print(f"{package.name}:")
print(f" Dependencies: {[d.name for d in deps]}")
print(f" Dependents: {[d.name for d in dependents]}")Utilities for parsing and formatting dependency specifications.
def parse_dependency_specification(spec: str) -> dict:
"""
Parse dependency specification string.
Args:
spec: Dependency specification (e.g., "requests>=2.25.0,<3.0")
Returns:
Dictionary with parsed dependency information
"""
def format_dependency_specification(name: str, constraint: str,
extras: list = None,
markers: str = None) -> str:
"""
Format dependency specification string.
Args:
name: Package name
constraint: Version constraint
extras: Optional extras
markers: Environment markers
Returns:
Formatted dependency specification
"""
class DependencySpec:
"""
Structured dependency specification.
Provides parsing and formatting utilities for dependency
specifications with support for version constraints, extras,
and environment markers.
"""
def __init__(self, name: str, constraint: str = "*"):
"""
Initialize dependency specification.
Args:
name: Package name
constraint: Version constraint
"""
@property
def name(self) -> str:
"""Package name."""
@property
def constraint(self) -> str:
"""Version constraint."""
@classmethod
def from_string(cls, spec: str) -> "DependencySpec":
"""
Parse dependency specification from string.
Args:
spec: Dependency specification string
Returns:
DependencySpec instance
"""
def to_string(self) -> str:
"""
Convert to dependency specification string.
Returns:
Formatted dependency specification
"""from poetry.utils.dependency_specification import DependencySpec
# Parse dependency specifications
spec1 = DependencySpec.from_string("requests>=2.25.0,<3.0")
spec2 = DependencySpec.from_string("pytest[dev]>=6.0")
print(f"Package: {spec1.name}")
print(f"Constraint: {spec1.constraint}")
# Format dependency specification
formatted = DependencySpec("django", ">=3.2,<4.0").to_string()
print(f"Formatted: {formatted}")from poetry.factory import Factory
from poetry.puzzle.solver import Solver
def resolve_dependencies(poetry_instance):
"""Resolve project dependencies."""
solver = Solver(
poetry_instance.package,
poetry_instance.pool,
poetry_instance.config
)
# Resolve dependencies
operations = solver.solve()
return operationsfrom poetry.factory import Factory
def update_lock_file(project_path, groups=None):
"""Update project lock file."""
poetry = Factory().create_poetry(cwd=project_path)
# Get current dependencies
dependencies = poetry.package.all_requires
# Resolve dependencies
solver = Solver(poetry.package, poetry.pool, poetry.config)
packages = solver.solve()
# Update lock file
poetry.locker.set_lock_data(poetry.package, packages)
print(f"Updated lock file with {len(packages)} packages")Package management exceptions and error conditions:
class PackageNotFoundError(PoetryError):
"""Package not found in any repository."""
class VersionConflictError(PoetryError):
"""Version constraint conflicts in dependency resolution."""
class LockFileError(PoetryError):
"""Lock file operation errors."""
class RepositoryError(PoetryError):
"""Repository access or configuration errors."""Common package management errors:
Install with Tessl CLI
npx tessl i tessl/pypi-poetry