Skip to content

What is PEP 508?

PEP 508: Dependency specification for Python Software Packages defines the standard format for declaring dependencies on Python packages. Every pyproject.toml dependency list and every pip requirement string uses PEP 508 syntax, and so does every Poetry dependency.

How a requirement string is built

A PEP 508 requirement string specifies a package name, optional version constraint, optional extras, and optional environment markers:

package-name>=1.0,<2.0; extra == 'dev' and python_version >= '3.9'

The components are:

  1. Package name: requests, django, numpy
  2. Version specifier (optional): >=1.0, ==2.3.4, ~=1.2.3 (see PEP 440 for syntax)
  3. Extras (optional): [dev,test] to request optional feature bundles
  4. Environment markers (optional): ; followed by conditions like python_version >= '3.9' or sys_platform == 'win32'

Examples

Requirement string What it installs
numpy Any version, any platform
requests>=2.25.0,<3.0 requests 2.x only
flask[async] flask with async extras
pandas[excel,plot] pandas with multiple extras
pywin32; sys_platform == 'win32' Windows only
numpy>=1.20; python_version >= '3.9' Version and platform combined

Environment markers

Markers allow conditional dependencies based on the installation environment:

  • python_version: active Python version, e.g. '3.9', '3.10'
  • sys_platform: 'linux', 'darwin' (macOS), 'win32', etc.
  • platform_machine: CPU architecture, e.g. 'x86_64', 'arm64'
  • platform_system: OS name, 'Linux', 'Darwin', or 'Windows'
  • implementation_name: Python implementation, 'cpython', 'pypy', etc.
  • extra: the optional-dependency group being installed

PEP 508 also defines os_name, python_full_version, platform_release, and platform_version.

Where PEP 508 appears

In pyproject.toml dependencies:

[project]
dependencies = [
    "requests>=2.25",
    "dataclasses-json; python_version < '3.7'",
    "typing-extensions; python_version < '3.8'",
]

[project.optional-dependencies]
dev = [
    "pytest>=6.0",
    "mypy; python_version >= '3.8'",
]

In requirements.txt files:

requests>=2.25
numpy>=1.20; python_version >= '3.9'

In pip and uv commands:

pip install 'requests>=2.25,<3.0'
uv add 'numpy>=1.20; python_version >= "3.9"'

Version specifier vs. environment marker

Both constrain a dependency, but they operate differently:

  • Version specifier (>=1.0,<2.0): filters which package versions are acceptable
  • Environment marker (; python_version >= '3.9'): controls whether to install the dependency at all

numpy>=1.20; python_version >= '3.9' means “install numpy 1.20 or later, but only on Python 3.9+.”

Why one syntax works across tools

PEP 508 standardizes the format so pip, uv, Poetry, and Hatch all parse the same dependency strings. A project can switch tools without rewriting its dependency list.

Learn More

Last updated on