pdm-pep517
pdm-pep517 is an official plugin for PDM, the Python package manager. It acts as a PEP 517 build backend, enabling PDM projects to be built into distribution packages (sdist, wheel) using PEP 621 metadata defined in `pyproject.toml`. It is currently at version 1.1.4 and is actively maintained, with updates tied to PDM's core development and bug fixes.
Common errors
-
ModuleNotFoundError: No module named 'pdm.pep517.api'
cause The `pdm-pep517` library is not installed in the Python environment where the build process is attempting to run, or it was not listed in `build-system.requires` for an isolated build.fixInstall `pdm-pep517` into your environment (`pip install pdm-pep517`). If using isolated builds (e.g., `python -m build`), ensure `pyproject.toml` has `pdm-pep517` in `build-system.requires`. -
RuntimeError: PDM is not installed or PDM's version is too old. PDM >= 2.0.0 is required.
cause `pdm-pep517` was invoked, but the installed PDM version in the active environment is older than 2.0.0, or PDM is not installed at all.fixUpgrade your PDM installation to version 2.0.0 or newer by running: `pip install --upgrade pdm`. -
pyproject.toml does not contain a [project] table
cause The `pyproject.toml` file is missing the mandatory `[project]` table, which is required by PEP 621 metadata specification that `pdm-pep517` relies on.fixAdd a `[project]` table to your `pyproject.toml` file, including at least `name`, `version`, and `requires-python` fields.
Warnings
- breaking PDM 2.0+ Requirement: `pdm-pep517` explicitly requires PDM 2.0 or later to function correctly. Using an older PDM version will result in a `RuntimeError` during the build process.
- gotcha Build Environment Installation: When building with tools like `pip build` or in isolated CI/CD environments, `pdm-pep517` must be listed in `build-system.requires` in your `pyproject.toml` so the build backend is installed in the isolated environment. PDM's own `pdm build` command handles this automatically for you.
- gotcha Incorrect `build-backend` Specification: The `build-backend` entry in `pyproject.toml` must be precisely `pdm.pep517.api`. Any deviation will prevent the build tool from finding the correct backend.
Install
-
pip install pdm-pep517
Quickstart
import os
import shutil
import subprocess
from pathlib import Path
# --- Setup a temporary project to demonstrate pdm-pep517 ---
project_name = "my_pdm_project_quickstart"
project_path = Path(project_name)
# Clean up previous run if exists
if project_path.exists():
shutil.rmtree(project_path)
project_path.mkdir()
(project_path / project_name).mkdir()
# Create a simple __init__.py
(project_path / project_name / "__init__.py").write_text(
f'__version__ = "0.1.0"\n'
f'def hello():\n'
f' return "Hello from {project_name}"\n'
)
# Create pyproject.toml with pdm-pep517 as build backend
pyproject_toml_content = f"""
[project]
name = "{project_name}"
version = "0.1.0"
description = "A project built with pdm-pep517"
requires-python = ">=3.8"
authors = [
{{ name = "AI Assistant", email = "ai@example.com" }},
]
[build-system]
requires = ["pdm-pep517", "pdm>=2.0.0"]
build-backend = "pdm.pep517.api"
"""
(project_path / "pyproject.toml").write_text(pyproject_toml_content)
print(f"Created project structure in {project_path.resolve()}\n")
# --- Build the project using PDM ---
print("Attempting to build the project with 'pdm build'...")
try:
# Change to the project directory for pdm commands
os.chdir(project_path)
# Ensure pdm is installed and on PATH
pdm_cmd = os.environ.get('PDM_PATH', 'pdm')
result = subprocess.run(
[pdm_cmd, "build"],
capture_output=True,
text=True,
check=True # Raise CalledProcessError for non-zero exit codes
)
print("Build successful!")
print(result.stdout)
print(result.stderr)
# Verify wheel file exists
dist_path = Path("dist")
wheel_files = list(dist_path.glob("*.whl"))
if wheel_files:
print(f"Generated wheel file: {wheel_files[0].name}")
else:
print("No wheel file found in 'dist' directory.")
except FileNotFoundError:
print(f"\nError: '{pdm_cmd}' command not found. Please ensure PDM is installed and on your PATH.")
print("You can install it via: `pip install pdm`")
except subprocess.CalledProcessError as e:
print(f"\nBuild failed with error code {e.returncode}")
print("STDOUT:")
print(e.stdout)
print("STDERR:")
print(e.stderr)
finally:
# Clean up the temporary project
os.chdir("..")
shutil.rmtree(project_path)
print(f"\nCleaned up temporary project directory: {project_path}")