Dependency Groups & Inline Script Metadata

This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production.

The reference material consulted while preparing these pages is listed in the Python Reference bibliography.

Requirements files are pip’s own format. Two newer standards cover two of their most common uses: development dependencies of a project (PEP 735 dependency groups, in pyproject.toml) and the dependencies of a single script (PEP 723 inline script metadata, in the script itself). pip installs both directly. This page was written against pip 26.2.2 and run on CPython 3.14.6 on 2026-10-22, with the pip flavour of birdtally and the local birdwatch index on localhost:8080.

Dependency groups: --group (pip 25.1)

birdtally declares four groups in pyproject.toml; dev includes two others:

[dependency-groups]
test = ["pytest>=8"]
lint = ["ruff>=0.6"]
docs = ["mkdocs>=1.6"]
dev = [{ include-group = "test" }, { include-group = "lint" }]

The format is described on pyproject.toml. --group <name> installs one group from the pyproject.toml in the current directory, and can be repeated:

cd birdtally
python -m pip install --group test
Collecting pytest>=8
Collecting iniconfig>=1.0.1 (from pytest>=8)
Collecting packaging>=22 (from pytest>=8)
Collecting pluggy<2,>=1.5 (from pytest>=8)
Collecting pygments>=2.7.2 (from pytest>=8)
Installing collected packages: pygments, pluggy, packaging, iniconfig, pytest

Successfully installed iniconfig-2.3.1 packaging-26.3 pluggy-1.7.0 pygments-2.21.0 pytest-9.1.1

(The Using cached … lines are left out.) Three things to notice:

  • The project itself is not installed. A group is a list of requirements, not a requirement on the project; pip list shows no birdtally afterwards. To test the project, install both: pip install -e . --group dev.

  • Includes are expanded. --group dev brings in test and lint.

  • There is no project discovery. pip reads pyproject.toml in the current directory, or the one you name with path/to/pyproject.toml:group; the file name must be pyproject.toml. That makes it possible to install groups of several projects at once (--group ./sub1/pyproject.toml:test --group ./sub2/pyproject.toml:test).

python -m pip install -e . --group dev
python -m pytest -q
Obtaining file://…/pip-flavour/birdtally
…
Successfully built birdtally
Installing collected packages: ruff, birdtally
Successfully installed birdtally-0.1.0 ruff-0.17.1
…
2 passed in 0.01s

The errors are specific:

$ python -m pip install --dry-run --group nope
ERROR: [dependency-groups] resolution failed for 'nope' from 'pyproject.toml': Dependency group 'nope' not found

$ python -m pip install --dry-run --group ../pip-flavour/birdtally:dev
--group error: group paths use 'pyproject.toml' filenames

Run outside a project directory without a path, pip reports ERROR: pyproject.toml not found. Cannot resolve '--group' option. Groups contain only standard dependency specifiers: no -e, -c, --hash or index options, unlike requirements files. --group cannot be combined with --only-deps. The specification recommends against naming a group like an extra, because tools may treat that as an error.

The test, lint and docs tools these groups name are described in Testing, Debugging & Tooling and Docstrings. Poetry reads the same table; see Poetry: Managing Dependencies & Groups.

Inline script metadata: --requirements-from-script (pip 26.0)

A single-file script has no pyproject.toml. PEP 723 lets it carry its metadata in a comment block that starts with # /// script and ends with # ///; the lines in between, with the leading +# + removed, are TOML with requires-python and dependencies. A weekly report for the survey team:

# /// script
# requires-python = ">=3.10"
# dependencies = [
#   "birdtally[pretty]>=0.1.0",
# ]
# ///
"""Print the weekly bird-survey report as a table."""

import sys

from birdtally import read_sightings, tally_by_site
from rich.console import Console
from rich.table import Table

totals = tally_by_site(read_sightings(sys.argv[1]))
table = Table("Site", "Count", title="Sightings per site")
for site, count in totals.items():
    table.add_row(site, str(count))
Console().print(table)
python -m venv .venv
.venv/bin/python -m pip install --index-url http://localhost:8080/simple --requirements-from-script weekly_report.py
.venv/bin/python weekly_report.py survey.csv
Looking in indexes: http://localhost:8080/simple
Collecting birdtally>=0.1.0 (from birdtally[pretty]>=0.1.0)
  Downloading birdtally-0.1.0-py3-none-any.whl (3.7 kB)
Collecting rich>=13 (from birdtally[pretty]>=0.1.0)
Collecting markdown-it-py>=2.2.0 (from rich>=13->birdtally[pretty]>=0.1.0)
Collecting pygments<3.0.0,>=2.13.0 (from rich>=13->birdtally[pretty]>=0.1.0)
Collecting mdurl~=0.1 (from markdown-it-py>=2.2.0->rich>=13->birdtally[pretty]>=0.1.0)
Installing collected packages: pygments, mdurl, birdtally, markdown-it-py, rich

Successfully installed birdtally-0.1.0 markdown-it-py-4.2.0 mdurl-0.1.2 pygments-2.21.0 rich-15.0.0
  Sightings per site
┏━━━━━━━━━━━━━┳━━━━━━━┓
┃ Site        ┃ Count ┃
┡━━━━━━━━━━━━━╇━━━━━━━┩
│ north-marsh │ 6     │
│ east-dunes  │ 3     │
└─────────────┴───────┘

pip checks requires-python against the interpreter it runs with:

ERROR: Script 'future.py' requires a different Python: 3.14 not in '>=3.15'

pip only installs the dependencies; it does not create an environment or run the script. Runners such as uv run, pipx run and Hatch do both, and the specification recommends that such tools pick the newest Python that satisfies requires-python. A script block may also contain a [tool] table for those tools.

Which one to use

Requirements file Dependency group Script metadata

Lives in

requirements*.txt

the project’s pyproject.toml

the script

Standard

No (pip format)

PEP 735

PEP 723

May contain pip options (indexes, hashes, -e)

Yes

No

No

Read by

pip, uv

pip 25.1+, Poetry 2.2+, uv, PDM, Hatch

pip 26.0+, uv, pipx, Hatch

Typical use

Pinned environments, locks

Test, lint and docs tools of a project

One-file tools and reports

Prefer a group for a project’s development tools, because every modern tool reads it and it keeps the dependencies next to the project metadata. Prefer script metadata for a script that is shared on its own. Keep requirements files for what only they can do: index options, hashes and pinned environments.