[!NOTE] Automatische vertaling Dit artikel is automatisch vertaald vanuit de oorspronkelijke Engelse versie.
pyproject.toml Gids: Python-pakkettering, afhankelijkheden en configuratie van tools
Oudere Python-projecten verspreiden vaak de configuratie over verschillende bestanden. setup.py, setup.cfg, vereistenbestanden, MANIFEST.inen aparte bestanden voor ontwikkelingshulpmiddelen. pyproject.toml het biedt deze zorgen een gemeenschappelijke plek, hoewel het geen enkel projectbestand vervangt of elke sectie onderdeel maakt van één standaard.
Deze gids neemt u mee door het bestand, van de bouwkonfiguratie tot de projectmetadata en de instellingen van de hulpprogramma’s. De eenvoudigste manier om dit overzichtelijk te houden, is door vier verantwoordelijken aan te wijzen: wie het project bouwt, wat het project publiceert, wat bijdragers lokaal nodig hebben, en welke individuele hulpprogramma’s de configuraties bepalen.
TL;DR. Gebruik
[build-system]voor de backend die een distributie bouwt,[project]voor gepubliceerde metadata en de vereisten van runtime.[dependency-groups]voor ongepubliceerde ontwikkelomgevingen, en[tool.*]Alleen waar de documentatie van dat hulpprogramma dat aangeeft. Een afhankelijkheidsverklaring is geen lockfile.
Eén bestand, vier eigenaren
Drie verpakkingsstandaarden vormden de kernstructuur:
- PEP 518 Bepaalt de vereisten voor het bouwsysteem. PEP 621 definieert de projectmetadata. PEP 735 Definieert ongepubliceerde afhankelijkheidsgroepen.
Toolontwikkelaars kunnen ook een namespace hieronder claimen. [tool]. Dat gebied is conventioneel, niet universeel: elke tool definieert zijn eigen sleutels en gedrag.
Hier is een kleine geïmpakte bibliotheek:
[build-system]
requires = ["hatchling>=1.26"]
build-backend = "hatchling.build"
[project]
name = "weather-client"
version = "0.1.0"
description = "A small weather API client"
readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"httpx>=0.27",
]
[project.optional-dependencies]
cli = ["rich>=13"]
[project.scripts]
weather = "weather_client.cli:main"
[dependency-groups]
test = ["pytest>=8", "pytest-cov>=5"]
lint = ["ruff>=0.12"]
[tool.pytest.ini_options]
testpaths = ["tests"]
[tool.ruff]
line-length = 100
target-version = "py311"
Elke lijst met afhankelijkheden beantwoordt een andere vraag. Die onderscheiding vormt het kernpunt van het bestand.
[build-system]: hoe een bronbestand wordt omgezet in een distributie
Een build frontend zoals python -m buildpip of uv roept een build backend aan. De backend bepaalt hoe de bronboom wordt omgezet in een sdist of wheel en welke bestanden in die artefacten terechtkomen.
[build-system]
requires = ["hatchling>=1.26"]
build-backend = "hatchling.build"
requires Het bevat afhankelijkheden die nodig zijn om de backend uit te voeren in zijn geïsoleerde bouwomgeving. Dit maakt het niet deel uit van de runtime-lijst met afhankelijkheden voor uw pakket.
declareer een bouwsysteem wanneer het project een distributie genereert of zijn eigen code als pakket moet worden geïnstalleerd. Een niet-pakketproject kan dit nog steeds gebruiken pyproject.toml; PEP 735 staat zelfs toe dat een bestand uitsluitend afhankelijkheidsgroepen bevat. Omgevingsbeheerders hanteren verschillende methoden voor projecten zonder bouwsysteem, dus neem deze keuze bewust.
Kies de backend uit de bouwvereisten:
- Layout en bestandsselectie die uitsluitend in pure Python worden uitgevoerd
- Gecompileerde extensies of externe bouwsystemen
- Vereisten met betrekking tot dynamische versies of gegenereerde bestanden
- Gedrag bij een editable-installatie
- backend volwassenheid van de release pipeline
Kopieer de huidig aanbevolen tabel van backend uit diens documentatie. Voeg niets toe. wheel Om op basis van gewoonte specificaties op te stellen; de backend geeft aan wat er nodig is.
[project]: door metadata-consumenten ontvangen
De [project] De tabel beschrijft de distributie: de naam, versie, compatibiliteit met Python, de runtime-afhankelijkheden, invoerpunten en andere indexmetagegevens.
[project]
name = "weather-client"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = ["httpx>=0.27"]
De specificaties voor afhankelijkheden vormen beperkingen voor een resolver, en geen snapshot van een bepaalde omgeving. Ze maken deel uit van de metadata van wheel- en sdist-bestanden, zodat installatieprogramma’s ze kunnen combineren met vereisten uit andere pakketten.
Extra’s vormen een publieke installatieinterface.
[project.optional-dependencies] definieert extra’s die consumenten kunnen aanvragen:
[project.optional-dependencies]
cli = ["rich>=13"]
postgres = ["psycopg[binary]>=3.2"]
Een consument kan een agent installeren weather-client[cli]. Aangezien er extra namen en vereisten worden gepubliceerd, moet u deze beschouwen als productfuncties. Gebruik geen extra genoemde elementen. dev Uitsluitend om alle hulpprogramma’s voor bijdragers te bevatten.
Entrypunten verbinden geïnstalleerde commando’s met Python
[project.scripts]
weather = "weather_client.cli:main"
Na installatie van de distributie maakt de omgeving deze beschikbaar. weather, dat importeert en oproept weather_client.cli:main. Testeer de opdracht met een gebuild te distribueren distributiebestand (wheel), en niet alleen vanuit de wortelpath van het repository; dit is immers wat gebruikers daadwerkelijk ontvangen.
[dependency-groups]: lokale, ongepubliceerde omgevingen
PEP 735‑afhankelijkheidsgroepen beschrijven ontwikkelomgevingen of niet‑pakketomgevingen zonder deze te publiceren als pakketmetadata.
[dependency-groups]
test = ["pytest>=8", "pytest-cov>=5"]
lint = ["ruff>=0.12"]
dev = [
{ include-group = "test" },
{ include-group = "lint" },
]
Dit vormt de juiste grens voor tests, linters, documentatiegeneratoren en soortgelijke hulpprogramma’s voor bijdragers. Het is ook nuttig voor applicaties of notebooks die geen distributie genereren.
Afhankelijkheidsgroepen zijn gestandaardiseerde gegevens, maar de installatieinterfaces verschillen nog steeds. Controleer hoe de geselecteerde omgevingsbeheerder deze groepen installeert, blokkeert en oplost. PEP 735 definieert geen universele command-line-interface.
[tool.*]: configuratie die eigendom is van één tool
Tooltabellen delen geen schema:
[tool.pytest.ini_options]
addopts = "-ra"
testpaths = ["tests"]
[tool.ruff]
line-length = 100
Gebruik een [tool.*] Een tabel wordt alleen weergegeven als het hulpprogramma dit documenteert. Sommige instellingen blijven in hun eigen bestanden omdat ze door een ander ecosysteem worden gebruikt, omdat het bestand een andere formatvereiste heeft, of omdat de configuratie op die manier duidelijker is. pyproject.toml Het is een coördinatiepunt, geen verplichting om alles te centraliseren.
Verklaringen, locks en vereistenbestanden lossen verschillende problemen op
De meest voorkomende oorzaak van verwarring is wanneer elke afhankelijkheidsartefact wordt beschouwd als een concurrerende bron van waarheid.
| Artifact | Primair doel | Typische inhoud |
|---|---|---|
[project.dependencies] | Gepubliceerde runtime-contract | Directe vereisten en compatibele bereiken |
[project.optional-dependencies] | Gepubliceerde opt-in-functionaliteiten | Extra’s voor consumenten |
[dependency-groups] | Nog niet gepubliceerde lokale omgevingen | Test-, lint-, documentatie- of applicatiegroepen |
| Een opgelost omgeving reproduceren | Exacte versies, bronnen en resolutiemetadata | |
requirements.txt | Invoer voor een pip-compatibele installatie | Eisen samen met pip-specifieke opties, beperkingen, URL’s of hashes |
Een bibliotheek publiceert doorgaans compatibele beperkingen en tests met betrekking tot een bepaald bereik. Een applicatie slaat meestal het lockfile van de omgevingsbeheerder op. Precise pinwaarden horen thuis in het geresolveerde artefact deployment, en niet zomaar in de publieke metadata van een bibliotheek.
Bewaar een requirementsbestand wanneer een integratie de format of functies van pip vereist. Als een door uv beheerd project er eentje nodig heeft, exporteer het dan uit het lock-bestand in plaats van twee afzonderlijke dependentiemengsels bij te houden:
uv export --format requirements.txt --output-file requirements.txt
De export is een compatibiliteitsoutput die is afgeleid van de oorspronkelijke bron. De lock blijft de geresolveerde bron voor dat workflow.
Een migratie die het gedrag behoudt
Begin niet met het verwijderen. setup.py of requirements.txt.Eerst classificeren wat elke bestaande bestand doet.
- Logica voor het opbouwen van inventarissen, metadata, vereisten van runtime, extra elementen, ontwikkelaarsomgevingen, instellingen van tools, pakketgegevens en invoerpunten.
- Kies een backend die de huidige bestandsinclusies, gecompileerde artefacten en bewerkbare installaties kan reproduceren.
- Verplaats statische, gepubliceerde metadata naar
[project]; houd echt dynamische velden expliciet. - Verplaats vereisten die alleen voor bijdragers gelden naar
[dependency-groups], geen publieke extra’s. - Verplaats de instellingen van het hulpprogramma alleen wanneer het hulpprogramma dezelfde semantiek ondersteunt.
- Maak zowel een sdist als een wheel aan, controleer hun inhoud en installeer de wheel in een schone omgeving.
- Voer de entry points, tests, importcontroles en de daadwerkelijke deployment-paden uit.
- Verwijder de oude configuratie pas nadat de artefacten en het gedrag overeenkomen.
MANIFEST.in kan nog steeds nodig zijn bij sommige setups van setuptools, en een klein setup.py Het kan geldig blijven voor een programmatisch bouwproces. Modernisering betekent een verschuiving in eigendom, en niet een wedstrijd om bestanden te verwijderen.
Een actuele uv workflow
UV onderscheidt applicaties van bibliotheken bij het maken van een project:
# Non-library application template
uv init weather-app
# Packaged library with a src layout and build system
uv init --lib weather-client
uv init maakt projectbestanden aan. De eerste actie met het project, zoals uv run, uv sync, of uv lock maakt het lockbestand en de persistente gegevens aan .venv indien nodig.
cd weather-client
uv add httpx
uv add --group test pytest pytest-cov
uv run pytest
uv build
UV plaatst momenteel lokale ontwikkelingsvereisten in gestandaardiseerde afhankelijkheidsgroepen. Zijn geïntegreerde functionaliteit uv_build backend is een optie voor projecten die uitsluitend in Python zijn geschreven; gecompileerde extensies vereisen een geschikte alternatief zoals maturin of scikit-build-core.
Conclusie
pyproject.toml Het is duidelijk wanneer elke tabel één doelgroep heeft. Het implementeren van isolatie valt onder deze categorie. [build-system]. Het gepubliceerde gedrag behoort tot [project]. De omgevingen voor bijdragers behoren toe aan [dependency-groups]. Toolswitches behoren tot het hulpmiddel dat ze definieert.
Zodra die grenzen stabiel zijn, wordt het gemakkelijker om het bestand te controleren—en migraties voorkomen dat pakketmetagegevens verward raken met de opgeloste omgeving van één specifiek apparaat.