A modern Python package and dependency manager supporting the latest PEP standards
—
Project configuration, metadata handling, and dependency management for PDM projects. This module manages pyproject.toml files, dependency specifications, and project-level operations.
Core project management class that provides comprehensive project operations and metadata handling.
class Project:
"""
Primary project management class for PDM projects.
Manages project configuration, dependencies, environments, and metadata
from pyproject.toml files following PEP 621 standards.
"""
@property
def root(self) -> Path:
"""Project root directory path"""
@property
def pyproject(self) -> dict:
"""
Project metadata and configuration from pyproject.toml.
Returns:
Dictionary containing pyproject.toml content
"""
@property
def pyproject_file(self) -> Path:
"""Path to pyproject.toml file"""
@property
def lockfile(self) -> Lockfile:
"""
Project lockfile instance.
Returns:
Lockfile object for reading/writing lock data
"""
@property
def lockfile_file(self) -> Path:
"""Path to pdm.lock file"""
@property
def environment(self) -> BaseEnvironment:
"""
Project environment instance.
Returns:
Environment object for package management
"""
@property
def python(self) -> PythonInfo:
"""
Python interpreter information.
Returns:
Python interpreter details and capabilities
"""
def add_dependencies(
self,
requirements: list[str],
group: str = "default",
dev: bool = False
) -> None:
"""
Add dependencies to project configuration.
Args:
requirements: List of requirement specifications
group: Dependency group name (default: "default")
dev: Add to development dependencies (deprecated, use group)
"""
def remove_dependencies(
self,
requirements: list[str],
group: str = "default",
dev: bool = False
) -> None:
"""
Remove dependencies from project configuration.
Args:
requirements: List of package names to remove
group: Dependency group name (default: "default")
dev: Remove from development dependencies (deprecated, use group)
"""
def get_dependencies(self, group: str = "default") -> dict[str, Requirement]:
"""
Get dependencies for a specific group.
Args:
group: Dependency group name
Returns:
Dictionary mapping package names to Requirement objects
"""
def iter_groups(self) -> Iterator[str]:
"""
Iterate over all dependency groups in the project.
Yields:
Group names including "default" and any optional-dependencies
"""
def write_pyproject(self) -> None:
"""
Write current project configuration to pyproject.toml file.
"""
def reload_pyproject(self) -> None:
"""
Reload project configuration from pyproject.toml file.
"""Project-level configuration management supporting both global and project-specific settings.
class Config:
"""
Configuration management system for PDM projects.
Handles configuration loading, validation, and hierarchical settings
from global, user, and project-specific sources.
"""
def add_config(self, name: str, config_item: ConfigItem) -> None:
"""
Add a configuration option definition.
Args:
name: Configuration option name
config_item: Configuration item specification
"""
def get_config(self, name: str) -> Any:
"""
Get configuration value by name.
Args:
name: Configuration option name
Returns:
Configuration value with proper type conversion
"""
def set_config(self, name: str, value: Any) -> None:
"""
Set configuration value.
Args:
name: Configuration option name
value: Configuration value to set
"""
@property
def config_file(self) -> Path:
"""Path to project configuration file"""
class ConfigItem:
"""
Individual configuration item definition.
Defines configuration schema, validation, and default values.
"""
def __init__(
self,
description: str,
config_type: str,
default: Any = None,
choices: list[str] | None = None,
env_var: str | None = None
):
"""
Initialize configuration item.
Args:
description: Human-readable description
config_type: Type specification ("string", "boolean", "integer", etc.)
default: Default value if not set
choices: Valid choices for the option
env_var: Environment variable name override
"""Project creation utilities and initialization functions.
def create_project(
project_dir: Path | str,
name: str | None = None,
version: str = "0.1.0",
description: str = "",
author: str | None = None,
license: str | None = None,
python_requires: str = ">=3.8"
) -> Project:
"""
Create a new PDM project with initial configuration.
Args:
project_dir: Directory for new project
name: Project name (default: directory name)
version: Initial version
description: Project description
author: Author name and email
license: License specification
python_requires: Python version requirement
Returns:
New Project instance
"""
def find_project_root(path: Path | str = ".") -> Path:
"""
Find project root by searching for pyproject.toml or pdm.lock.
Args:
path: Starting search path
Returns:
Path to project root directory
Raises:
ProjectError: No project root found
"""Management of dependency groups including optional dependencies and development dependencies.
class DependencyGroup:
"""
Represents a dependency group within a project.
"""
def __init__(self, name: str, dependencies: dict[str, Requirement]):
"""
Initialize dependency group.
Args:
name: Group name
dependencies: Mapping of package names to requirements
"""
@property
def name(self) -> str:
"""Group name"""
@property
def dependencies(self) -> dict[str, Requirement]:
"""Dependencies in this group"""
def add_requirement(self, requirement: Requirement) -> None:
"""Add requirement to group"""
def remove_requirement(self, name: str) -> None:
"""Remove requirement from group"""from pdm.project import Project, create_project
# Create new project
project = create_project(
project_dir="./my-app",
name="my-app",
version="1.0.0",
description="My Python application",
python_requires=">=3.9"
)
# Load existing project
project = Project.find_project_root(".")
# Add dependencies
project.add_dependencies([
"requests>=2.25.0",
"click>=8.0.0"
])
# Add development dependencies
project.add_dependencies([
"pytest>=6.0.0",
"black",
"mypy"
], group="dev")
# Write changes
project.write_pyproject()from pdm.project import Project
project = Project()
# Create custom dependency groups
project.add_dependencies([
"pytest>=6.0",
"pytest-cov"
], group="test")
project.add_dependencies([
"sphinx",
"sphinx-rtd-theme"
], group="docs")
# List all groups
for group_name in project.iter_groups():
deps = project.get_dependencies(group_name)
print(f"{group_name}: {list(deps.keys())}")
# Remove dependency from specific group
project.remove_dependencies(["pytest-cov"], group="test")from pdm.project import Project
from pdm.project.config import ConfigItem
project = Project()
# Get configuration values
cache_dir = project.config.get_config("cache_dir")
python_path = project.config.get_config("python.path")
# Set project-specific configuration
project.config.set_config("install.parallel", True)
project.config.set_config("repository.url", "https://private.pypi.org")
# Add custom configuration option
project.config.add_config("custom.setting", ConfigItem(
"My custom project setting",
"string",
default="default_value"
))from pdm.project import Project
project = Project()
# Update project metadata
project.pyproject["project"]["description"] = "Updated description"
project.pyproject["project"]["keywords"] = ["python", "tool"]
# Add build system configuration
project.pyproject["build-system"] = {
"requires": ["pdm-backend"],
"build-backend": "pdm.backend"
}
# Add tool configuration
project.pyproject.setdefault("tool", {})["pdm"] = {
"version": {"source": "scm"},
"build": {
"includes": ["src/"],
"excludes": ["tests/"]
}
}
# Save changes
project.write_pyproject()Install with Tessl CLI
npx tessl i tessl/pypi-pdm