コンテンツにスキップ

PDM Cheat Sheet

Overview

PDM (Python Development Master) is a modern Python package and dependency manager that strictly follows PEP standards. It supports PEP 621 project metadata, PEP 517 build backends, and offers a lockfile mechanism similar to npm and Cargo for reproducible builds. PDM can work with virtual environments or PEP 582 local package directories.

PDM provides fast dependency resolution, a flexible plugin system, build and publish capabilities, and script management. It uses pyproject.toml as the single source of configuration and generates a pdm.lock file for deterministic installations.

Installation

# Via pipx (recommended)
pipx install pdm

# Via pip
pip install --user pdm

# macOS
brew install pdm

# Linux (installer script)
curl -sSL https://pdm-project.org/install-pdm.py | python3 -

# Verify
pdm --version

Core Commands

CommandDescription
pdm initInitialize a new project
pdm add <pkg>Add a dependency
pdm remove <pkg>Remove a dependency
pdm installInstall all dependencies
pdm updateUpdate dependencies
pdm lockGenerate/update lockfile
pdm run <cmd>Run command in project environment
pdm listList installed packages
pdm buildBuild distribution packages
pdm publishPublish to PyPI
pdm search <term>Search for packages
pdm self updateUpdate PDM itself

Project Setup

# Initialize new project
pdm init

# Initialize with minimal prompts
pdm init --python 3.12 --backend pdm-backend

# Initialize in non-interactive mode
pdm init --non-interactive -n

pyproject.toml

[project]
name = "my-project"
version = "0.1.0"
description = "My Python project"
requires-python = ">=3.10"
readme = "README.md"
license = {text = "MIT"}
authors = [
    {name = "Your Name", email = "you@example.com"},
]
dependencies = [
    "requests>=2.28",
    "click>=8.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=7.0",
    "ruff>=0.3",
]

[project.scripts]
mycli = "my_project.cli:main"

[build-system]
requires = ["pdm-backend"]
build-backend = "pdm.backend"

[tool.pdm]
distribution = true

[tool.pdm.dev-dependencies]
test = [
    "pytest>=7.0",
    "pytest-cov",
]
lint = [
    "ruff",
    "mypy",
]

Dependency Management

# Add production dependency
pdm add requests flask sqlalchemy

# Add with version constraint
pdm add "requests>=2.28,<3.0"
pdm add "django~=4.2"

# Add dev dependency
pdm add -dG test pytest pytest-cov
pdm add -dG lint ruff mypy

# Add optional dependency group
pdm add -G docs mkdocs mkdocs-material

# Remove dependency
pdm remove requests

# Update all dependencies
pdm update

# Update specific package
pdm update requests

# Update dev dependencies only
pdm update -dG test

# Install from lockfile (exact versions)
pdm install

# Install with specific groups
pdm install -G docs
pdm install -dG test,lint

# Show dependency tree
pdm list --tree

# Show outdated packages
pdm update --dry-run

Scripts and Tasks

# pyproject.toml
[tool.pdm.scripts]
start = "python -m my_project"
test = "pytest tests/ -v"
lint = "ruff check src/"
format = "ruff format src/ tests/"
typecheck = "mypy src/"

# Composite script
check = {composite = ["lint", "typecheck", "test"]}

# Script with environment variables
dev = {cmd = "uvicorn my_project.app:app --reload", env = {DEBUG = "1"}}

# Shell script
migrate = {shell = "python manage.py migrate && echo 'Done'"}

# Pre/post hooks
pre_test = "echo 'Setting up tests...'"
post_test = "echo 'Tests complete!'"
pdm run start
pdm run test
pdm run check
pdm run dev

Configuration

PDM Config

# Show config
pdm config

# Set Python interpreter
pdm use 3.12
pdm use /usr/bin/python3.12

# Configure venv backend
pdm config venv.backend virtualenv
pdm config venv.in_project true

# Configure PyPI index
pdm config pypi.url https://pypi.org/simple/

# Private index
pdm config pypi.extra.url https://private.pypi.org/simple/
pdm config pypi.extra.username myuser
pdm config pypi.extra.password mypass

Virtual Environment

# Create venv (automatic with pdm install)
pdm venv create 3.12

# List venvs
pdm venv list

# Activate venv
eval $(pdm venv activate)

# Remove venv
pdm venv remove my-project-3.12

# Use in-project .venv
pdm config venv.in_project true

Lock Strategies

# Generate lockfile
pdm lock

# Cross-platform lock
pdm lock --strategy cross_platform

# Lock without hashes
pdm lock --no-hashes

# Export to requirements.txt
pdm export -f requirements -o requirements.txt

# Export with dev deps
pdm export -f requirements --dev -o requirements-dev.txt

Advanced Usage

Build and Publish

# Build sdist and wheel
pdm build

# Publish to PyPI
pdm publish

# Publish to Test PyPI
pdm publish --repository testpypi

# Publish with credentials
pdm publish --username __token__ --password pypi-xxx

Plugins

# Install PDM plugin
pdm self add pdm-bump
pdm self add pdm-autoexport

# List installed plugins
pdm self list

# Remove plugin
pdm self remove pdm-bump

Monorepo Support

# Root pyproject.toml
[tool.pdm.dev-dependencies]
dev = ["-e file:///${PROJECT_ROOT}/packages/shared"]

# Or path dependency
[project]
dependencies = [
    "shared @ file:///${PROJECT_ROOT}/packages/shared",
]

CI/CD Integration

# GitHub Actions
- uses: pdm-project/setup-pdm@v4
  with:
    python-version: '3.12'
    cache: true

- run: pdm install
- run: pdm run test

Troubleshooting

IssueSolution
Resolution conflictRun pdm update --unconstrained to find issues
Lock file outdatedRun pdm lock --update-reuse
Wrong Python versionRun pdm use <version> to select interpreter
Package not foundCheck index configuration with pdm config pypi.url
Import error after installEnsure pdm install completed; check pdm list
Slow resolutionUse pdm lock --strategy no_cross_platform
# Verbose output
pdm install -v

# Check project health
pdm check

# Show dependency tree
pdm list --tree --reverse

# Clear cache
pdm cache clear

# Debug resolution
pdm lock -v