A modern Python package and dependency manager supporting the latest PEP standards
npx @tessl/cli install tessl/pypi-pdm@2.25.0A modern Python package and dependency manager supporting the latest PEP standards. PDM provides fast dependency resolution, flexible project management, and comprehensive Python environment handling with support for PEP 517 (build backend), PEP 621 (project metadata), and lockfiles for reproducible builds.
pip install pdm or via installer scriptpdm and Python APIimport pdm
from pdm.core import Core
from pdm.project import ProjectCommon imports for CLI commands:
from pdm.cli.commands.base import BaseCommand
from pdm.cli.actions import do_lock, do_sync# Initialize a new project
pdm init
# Add dependencies
pdm add requests
pdm add pytest --group dev
# Install dependencies
pdm install
# Update lockfile
pdm lock
# Sync environment with lockfile
pdm sync
# Run commands in project environment
pdm run python script.pyfrom pdm.core import Core
from pdm.project import Project
# Create core manager
core = Core()
# Create or load project
project = core.create_project(".")
# Lock dependencies
from pdm.cli.actions import do_lock
do_lock(project)
# Sync environment with lockfile
from pdm.cli.actions import do_sync
do_sync(project)PDM follows a modular architecture with clear separation of concerns:
pdm.core.Core)pdm.project.Project)This design enables extensibility through plugins while maintaining backwards compatibility and supporting the latest Python packaging standards.
Central coordination system managing projects, plugins, and global configuration. Provides the main entry point for both CLI and programmatic usage.
class Core:
def create_project(
self,
root_path: str | Path | None = None,
is_global: bool = False,
global_config: str | None = None,
) -> Project: ...
def register_command(self, command: type[BaseCommand], name: str | None = None) -> None: ...
def add_config(self, name: str, config_item: ConfigItem) -> None: ...
def load_plugins(self) -> None: ...
def main(args: list[str] | None = None) -> None: ...Project configuration, metadata handling, and dependency management. Manages pyproject.toml files, dependency specifications, and project environments.
class Project:
@property
def lockfile(self) -> Lockfile: ...
@property
def environment(self) -> BaseEnvironment: ...
@property
def python(self) -> PythonInfo: ...
@property
def name(self) -> str: ...
@property
def all_dependencies(self) -> dict[str, Sequence[Requirement]]: ...
@property
def sources(self) -> list[RepositoryConfig]: ...
def add_dependencies(
self,
requirements: Iterable[str | Requirement],
to_group: str = "default",
dev: bool = False,
show_message: bool = True,
write: bool = True,
) -> list[Requirement]: ...
class Config:
def __getitem__(self, key: str) -> Any: ...
def __setitem__(self, key: str, value: Any) -> None: ...Python environment abstraction supporting virtual environments, system Python, and containerized environments with package management capabilities.
class BaseEnvironment:
def get_paths(self) -> dict[str, str]: ...
def get_python_executable(self) -> Path: ...
class PythonEnvironment(BaseEnvironment):
def install(self, requirements: list[str]) -> None: ...
def uninstall(self, packages: list[str]) -> None: ...Advanced dependency resolution supporting both ResolveLib and UV backends with conflict resolution, constraint handling, and performance optimization.
class Resolver:
def resolve(self, requirements: list[Requirement]) -> dict[str, Candidate]: ...
class RLResolver(Resolver): ...
class UvResolver(Resolver): ...Package installation management with support for wheels, source distributions, editable installs, and environment synchronization.
def do_lock(
project: Project,
strategy: str = "all",
tracked_names: Iterable[str] | None = None,
requirements: list[Requirement] | None = None,
dry_run: bool = False,
refresh: bool = False,
groups: list[str] | None = None,
strategy_change: list[str] | None = None,
hooks: HookManager | None = None,
env_spec: EnvSpec | None = None,
append: bool = False,
) -> dict[str, list[Candidate]]: ...
def do_sync(
project: Project,
*,
selection: GroupSelection,
dry_run: bool = False,
clean: bool = False,
quiet: bool = False,
requirements: list[Requirement] | None = None,
tracked_names: Collection[str] | None = None,
no_editable: bool | Collection[str] = False,
no_self: bool = False,
reinstall: bool = False,
only_keep: bool = False,
fail_fast: bool = False,
hooks: HookManager | None = None,
) -> None: ...Installation & Synchronization
Comprehensive lockfile management supporting cross-platform compatibility, reproducible builds, and dependency metadata preservation.
class Lockfile:
def write(self, content: dict) -> None: ...
def read(self) -> dict: ...
class PDMLock(Lockfile): ...
def load_lockfile(path: Path) -> Lockfile: ...Extensible command-line interface supporting custom commands, argument parsing, and integration with the plugin system.
class BaseCommand:
name: str | None = None
description: str | None = None
arguments: Sequence[Option] = (verbose_option, global_option, project_option)
@classmethod
def register_to(cls, subparsers: _SubParsersAction, name: str | None = None, **kwargs: Any) -> None: ...
def add_arguments(self, parser: ArgumentParser) -> None: ...
def handle(self, project: Project, options: Namespace) -> None: ...PDM provides comprehensive virtual environment management with support for multiple Python versions and backends.
# CLI commands available:
# pdm venv create [python] [--name] [--with-pip]
# pdm venv list
# pdm venv remove <key>
# pdm venv activate <key>
# pdm venv purge
# pdm python install <versions>
# pdm python list [--all]Main command classes:
from pdm.cli.commands.venv import Command as VenvCommand
from pdm.cli.commands.python import Command as PythonCommandImport and export functionality supporting multiple package manager formats including Poetry, Pipfile, requirements.txt, and setup.py.
def convert_from(source_format: str, project: Project) -> None: ...
def export_to(target_format: str, project: Project) -> str: ...from typing import TypedDict, NamedTuple, Protocol
from pathlib import Path
class RepositoryConfig(TypedDict):
url: str
username: str | None
access_token: str | None
class SearchResult(NamedTuple):
name: str
version: str
summary: str
SearchResults = list[SearchResult]
RequirementDict = dict[str, str | dict[str, str]]
class FileHash(TypedDict):
algorithm: str
hash: str
class HiddenText:
def __init__(self, value: str) -> None: ...
def __str__(self) -> str: ...
class NotSetType:
def __bool__(self) -> bool: ...
NotSet = NotSetType()class Comparable(Protocol):
def __lt__(self, other) -> bool: ...
def __le__(self, other) -> bool: ...
def __gt__(self, other) -> bool: ...
def __ge__(self, other) -> bool: ...
class Spinner(Protocol):
def start(self, text: str) -> None: ...
def stop(self) -> None: ...
def update(self, text: str) -> None: ...PDM provides a comprehensive exception hierarchy for different error scenarios:
class PdmException(Exception):
"""Base exception for all PDM errors"""
class ResolutionError(PdmException):
"""Dependency resolution failures"""
class PdmUsageError(PdmException):
"""Usage and configuration errors"""
class RequirementError(PdmUsageError):
"""Invalid requirement specifications"""
class ProjectError(PdmUsageError):
"""Project configuration/structure errors"""
class InstallationError(PdmException):
"""Package installation failures"""
class BuildError(PdmException):
"""Package building failures"""