[!NOTE] Automatische vertaling Dit artikel is automatisch vertaald vanuit de oorspronkelijke Engelse versie.
UV op macOS: Beheer van Python-versies, projecten en tools
Ik ben overgestapt van mijn Python workflow naar uv, omdat dit hulpmiddel de vervanging is voor de verschillende tools die ik eerder gebruikte om te wisselen tussen pip, virtuele omgevingen, pip-tools, pipx en projectbeheersoftware. Nu kan één enkel uitvoerbaar bestand het grootste deel van deze taken uitvoeren.
De workflows verschillen nog steeds van elkaar. Een project, een script voor inline-metadata, eenmalige CLI-tools en geïnstalleerde CLI-tools hebben elk hun eigen omgeving en levenscyclus. Deze gids laat de commando’s zien die ik gebruik, evenals de grenzen die tussen deze componenten bestaan.
Snel starten
# Install uv with Homebrew
brew install uv
# Start a project
uv init example-app
cd example-app
uv add httpx
uv run python main.py
# Run an isolated CLI without installing it permanently
uvx ruff check .
# Run a script that declares PEP 723 dependencies
uv run fetch.py
TL;DR. Ik gebruik
uv add,uv lock,uv sync, enuv runbinnen projecten; PEP 723-metadata voor zelfstandige scripts;uvxvoor eenmalige tools; enuv tool installvoor commando’s die op hun plek moeten blijvenPATH. In CI,--lockedverifieert of de projectmetadata overeenkomt metuv.lock;--frozenVertrouwt op het bestaande slot zonder de versheid te controleren.
uv installeren met één eigenaar
Homebrew is een handige installatiemethode voor macOS:
brew install uv
uv --version
Als Homebrew uv heeft geïnstalleerd, moet Homebrew deze upgraden:
brew upgrade uv
uv self update Dit is bedoeld voor de standaardinstallatiemethode van UV’s en is uitgeschakeld bij installaties via een package-manager. Laat twee installers niet concurreren om hetzelfde uitvoerbare bestand.
Handige identiteitscommando’s:
command -v uv
uv python dir
uv tool dir
uv cache dir
Gemanageerde Python-installaties, permanente hulpprogramma’s en tijdelijke cache-entiteiten hebben afzonderlijke mappen. De cache kan worden verwijderd en opnieuw aangemaakt; het vormt geen bron van waarheid.
Projecten: declaraties, resolutie en omgeving
Een UV-project bevat doorgaans drie verschillende artefacten:
pyproject.tomlDe projectmetadata en de directe vereisten worden hier gedefinieerd.uv.lockSlaat de cross-platform resolutie van UV’s op..venvDit is de lokaal geïnstalleerde omgeving en dient als tijdelijk gebruik te dienen.
Maak een applicatie aan en voeg runtime en de testvereisten toe:
uv init forecast-app
cd forecast-app
uv add httpx
uv add --group test pytest
uv run python main.py
uv run --group test pytest
De huidige sjablonen voor UV-toepassingen genereren main.py, pyproject.toml, README.md, en .python-version. Ze definiëren standaard geen build-systeem. Gebruik uv init --lib Voor een geïmpakte bibliotheek met een src het opmaken en de compilatie van backend.
uv run controleert het project, bijwerkt het lock wanneer nodig, synchroniseert de benodigde afhankelijkheden en voert de opdracht uit. De eerste projectoperatie genereert .venv en uv.lock indien nodig; uv init Het creëert zelf uitsluitend de projectbestanden.
Voer de commits in, niet de omgeving
Committen pyproject.toml, uv.lockbron, en een opzettelijke .python-version. Ignoreren. .venv en de caches van de UV’s.
Het slot slaat een oplossing op voor alle ondersteunde markers en platforms; het zorgt er echter niet voor dat de native modules identiek zijn op macOS, Linux, Intel en Apple Silicon. Test elke deployment-platform.
Versheid beveiligen: --locked is niet --frozen
Als standaard kunnen projectcommando’s worden bijgewerkt uv.lock wanneer de declaraties veranderen.
Gebruik --locked om te vereisen dat het slot is bijgewerkt met de projectmetadata:
uv lock --check
uv sync --locked
uv run --locked pytest
Als pyproject.toml en uv.lock Ik ben het niet met je eens: deze commando’s falen in plaats van een nieuwe lock op te lossen. Dit zou normaal gesproken de nuttige CI-gate moeten zijn.
Gebruik --frozen Alleen wanneer je opzettelijk wilt dat de UV de bestaande lock gebruikt, zonder te controleren of deze actueel is:
uv sync --frozen
Dat kan nuttig zijn in een gecontroleerde bouwfase waarin de lock al is geverifieerd, maar het is geen detector voor verouderde locks. uv sync De standaardwaarde is ‘exact’, waardoor onnodige pakketten worden verwijderd. uv run gebruikt standaard een onnauwkeurige synchronisatie, tenzij --exact Er wordt om gevraagd.
Gemanaged Python: een versieverzoek, geen universele binary
uv kan Python-distributies downloaden en beheren:
uv python install 3.12 3.13
uv python list --only-installed
uv python pin 3.12
De door UV’s beheerde CPython-builds komen van de python-build-standalone project. UV kan ook systemen, Homebrew, pyenv, Conda en andere interpreters ontdekken.
.python-version Het is een versienummerverzoek dat wordt gedetecteerd door UV en andere compatibele hulpprogramma’s. requires-python in pyproject.toml Dit vormt het compatibiliteitscontract van het project. Houd beide aspecten bewust in overweging:
[project]
requires-python = ">=3.12,<3.14"
Pinnen 3.12 Het garandeert niet dat dezelfde patch-build voor altijd beschikbaar blijft, noch dat hetzelfde artefact op elke besturingssysteem wordt geleverd. Vraag om een exacte patch wanneer dit daadwerkelijk noodzakelijk is, en zorg ervoor dat de CI-exploitant expliciet de juiste interpreter selecteert en rapporteert.
Gebruik een andere Python-manager wanneer een project een distributie of bouwconfiguratie nodig heeft die uv niet biedt. uv kan die interpreter nog steeds gebruiken via --python of normale ontdekking.
Kies uit uv run, uvxen geïnstalleerde hulpprogramma’s
Projectgerelateerde hulpmiddelen: uv run
Als pytest, mypy, een codegenerator of een ander hulpprogramma het project moet importeren of zijn gegrendelde plugins moet gebruiken, declareer dit dan in een afhankelijkheidsgroep:
uv add --group lint ruff
uv run --group lint ruff check .
Het uitvoeren van die tool uvx Dit zal het agentobject isoleren van het project en kan de geïnstalleerde pakketten of plugins die het nodig heeft verbergen.
Ad-hoc hulpmiddelen: uvx
uvx is een alias voor uv tool run. Het creëert een geïsoleerd omgeving die wordt opgeslagen in de wegwerpcache voor UV:
uvx ruff@0.12.0 check .
uvx --from jupyterlab jupyter lab
uvx --with mkdocs-material mkdocs --help
Pin de toolversie in CI of de documentatie. Een eerste oproep zonder versienummer kiest een huidige release, zodat latere oproepen de cache-toestand kunnen hergebruiken.
Persistente uitvoerbare bestanden: uv tool install
Installeer een hulpprogramma wanneer scripts die niet onder uw controle vallen zijn commando daarvan nodig hebben. PATH, of wanneer het machine-manifest het opzettelijk bezit:
uv tool install 'ruff==0.12.0'
uv tool list
uv tool upgrade ruff
uv tool uninstall ruff
Persistente hulpprogramma’s maken nog steeds gebruik van geïsoleerde omgevingen. Mutatie van deze omgevingen via pip is niet toegestaan.
Scripts: maak één bestand tot de release-eenheid
PEP 723 definieert metadata voor inline-scripts. Een compatibele uitvoerder kan de commentaarblokken lezen om een geïsoleerde omgeving op te zetten.
# /// script
# requires-python = ">=3.12"
# dependencies = [
# "httpx>=0.27,<1",
# ]
# ///
import httpx
response = httpx.get("https://example.com", timeout=10)
response.raise_for_status()
print(response.status_code)
Voer metadata uit en bewerk deze met uv:
uv run fetch.py
uv add --script fetch.py rich
uv remove --script fetch.py rich
Eenvoudig python fetch.py Het negeert de commentaar-metadata. Daarom is het script afhankelijk van een compatibele runner, ook al blijft de Python-syntaxis geldig.
Voor een script dat later een resolutie moet reproduceren, maak dan een aangrenzende lock aan:
uv lock --script fetch.py
uv run --script fetch.py
Dit schrijft. fetch.py.lock. Een exclude-newer Een tijdstempel kan de mogelijke distributiedata van artefacten beperken, maar het is zwakker dan een exact vastgesteld resolutietijdpunt en garandeert niet dat het artefact nog steeds beschikbaar blijft.
Gebruik in plaats daarvan een project wanneer meerdere bestanden afhankelijkheden delen, de code als pakket kan worden geïmporteerd, tests toegang hebben moeten tot de projecttoestand, of meerdere scripts samen moeten worden verplaatst.
Vereistenbestanden: compatibiliteit, geen fouten
A requirements.txt Een bestand kan losse invoergegevens, exacte pinwaarden, hashes, beperkingen, indexen, URL’s of een gecompileerde omgeving bevatten. De reproduceerbaarheid ervan hangt af van de manier waarop het is gegenereerd en verwerkt; alleen de bestandsnaam zegt niets over de inhoud.
Gebruik de pip-compatibele interface van uv zonder migratie:
uv venv
uv pip sync requirements.txt
uv run python app.py
uv pip sync zorgt ervoor dat de omgeving overeenkomt met het bestand, terwijl uv pip install -r Het is additief.
Voor een eigen applicatie kan een gefaseerde migratie nuttig zijn:
uv init --bare
uv add -r requirements.in
uv add --group test -r requirements-test.in
uv lock
uv sync --locked
Voer eerst de volledige test uit en het pad deployment voordat je oude bestanden verwijdert. Mocht een downstream-systeem nog steeds een pip-formaat verwachten, kan dit worden afgeleid uit de geverifieerde uv lock:
uv export --format requirements.txt \
--output-file requirements.txt
Verzorg geen onderhoud. uv.lock en een handmatig bewerkte export als twee concurrerende resoluties.
Cache, indexen en grenzen van de toeleveringsketen
De UV-cache verbetert herhaalde installaties, maar blijft tijdelijk van aard:
uv cache prune
uv cache clean
Geef de voorkeur aan prune voor routinematige opruiming. clean Het verwijdert alle cache-entrieën en zorgt erop dat latere downloads en builds opnieuw uitgevoerd worden.
Een lockfile bevordert de herhaalbaarheid; het maakt afhankelijkheden echter niet betrouwbaarder. Controleer de bronnen van pakketten, de configuratie van de index, Git-revisies, de backends-processen, licenties en aanmeldgegevens. Houd de geauthenticeerde indexconfiguratie buiten de gecommitteerde bestanden, tenzij de repository alleen niet-vertrouwelijke referenties naar een goedgekeurd mechanisme voor aanmeldgegevens bevat.
Voor native pakketten dient u de deployment architectuur vast te leggen en te controleren of er beschikbare testversies zijn. Anders kan een resolver terugvallen op een bronbouw die compilers en systeembibliotheken vereist die afwezig zijn in de CI-omgeving of in productie.
Een compacte controlelijst voor het opstarten
Voor elk project:
- Definieer
requires-pythonen directe afhankelijkheden daarinpyproject.toml2. Zorg ervoor dat gepubliceerde extra’s gescheiden zijn van lokale afhankelijkheidsgroepen. - Voer een commit uit.
uv.lock; negeren.venven cache-toestand. - Voer projectgerelateerde hulpprogramma’s uit via de projectomgeving.
- Gebruik
uv lock --checkof--lockedin de CI-pipeline. - Test elke doelbesturingssysteem en architectuur die door het lock-file wordt weergegeven.
- Exporteer compatibiliteitsformaten uitsluitend voor genoemde downstream-consumenten.
- Beoordeel de broncode- en credentialbeleidsregels los van het resolutieproces.
UV is het meest nuttig wanneer deze eigendomsgrenzen zichtbaar blijven. Eén binary kan ze allemaal beheren zonder ze om te zetten in één enkel omgeving. Die combinatie – minder tools, zonder te doen alsof elke workflow identiek is – is de reden waarom ik het nog steeds gebruik als mijn standaardhulpprogramma voor Python-projecten op macOS.