[!NOTE] Automatische Übersetzung Dieser Artikel wurde automatisch aus der englischen Originalversion übersetzt.
UV unter macOS: Verwaltung von Python-Versionen, Projekten und Tools
Ich habe meinen Python Workflow auf uv umgestellt, da dieses Tool die bisher notwendige Wechselprozedur zwischen pip, virtuellen Umgebungen, pip-tools, pipx sowie Projektverwaltungswerkzeugen ersetzt hat. Ein einziger Ausführbarer erledigt nun den Großteil dieser Aufgaben.
Die Workflows weichen weiterhin voneinander ab. Ein Projekt, ein Script für Inline-Metadaten, eine einmalige CLI sowie eine installierte CLI verfügen jeweils über ihre eigene Umgebung und Lebenszyklusstruktur. Diese Anleitung zeigt die von mir verwendeten Befehle sowie die Abgrenzungen zwischen diesen verschiedenen Konfigurationen.
Schnelle Einrichtung
# 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
Zusammenfassung: Ich verwende uv add, uv lock, uv sync, und uv run innerhalb von Projekten; PEP 723-Metadaten für selbstständige Skripte. uvx für einmalige Tools; und uv tool install für Befehle, die unbedingt erhalten bleiben müssen PATH. In der kontinuierlichen Integration, --locked prüft, ob die Projektmetadaten übereinstimmen uv.lock; --frozen vertraut auf den vorhandenen Lock, ohne die Aktualität zu überprüfen.
uv mit einem Owner installieren
Homebrew ist ein praktischer Installationsweg für macOS:
brew install uv
uv --version
Falls Homebrew uv installiert hat, sollte Homebrew es aktualisieren:
brew upgrade uv
uv self update Dieser Modus ist für die eigenständige Installation über UV vorgesehen und wird bei Installationen über Paketmanager deaktiviert. Lassen Sie nicht zu, dass zwei Installer um dieselbe ausführbare Datei konkurrieren.
Nützliche Identitätskommandos:
command -v uv
uv python dir
uv tool dir
uv cache dir
Gemanagte Python-Installationen, dauerhafte Tools sowie temporäre Cache-Einträge werden in separaten Verzeichnissen abgelegt. Der Cache kann gelöscht und neu erstellt werden; er stellt keine zuverlässige Quelle der Wahrheit dar.
Projekte: Deklarationen, Auflösung und Umgebung
Ein UV-Projekt weist in der Regel drei verschiedene Artefakte auf:
pyproject.tomlgibt die Metadaten des Projekts sowie die direkten Anforderungen an.uv.lockspeichert die plattformübergreifende Auflösung der UVs..venvEs handelt sich um die lokal installierte Umgebung, die als einmalig nutzbar konzipiert ist.
Erstellen Sie eine Anwendung und fügen Sie Runtime sowie die Testanforderungen hinzu:
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
Die aktuellen Vorlagen für die Anwendung von UV-Technologien erzeugen main.py, pyproject.toml, README.md, und .python-version. Standardmäßig wird kein Build-System definiert. Verwenden Sie uv init --lib für eine als Paket bereitgestellte Bibliothek mit einem src Layout und Erstellung Backend.
uv run prüft das Projekt, aktualisiert den Lock bei Bedarf, synchronisiert die erforderlichen Abhängigkeiten und führt den Befehl aus. Die erste Projektoperation erstellt .venv und uv.lock je nach Bedarf; uv init Es erstellt selbst lediglich die Projektdateien.
Committe die Eingaben, nicht die Umgebung
Commitment pyproject.toml, uv.lock, Quelle, sowie ein gezielter .python-version. Ignorieren. .venv sowie die Caches der UVs.
Der Lock speichert eine Lösung für die unterstützten Marker und Plattformen; er sorgt jedoch nicht dafür, dass die nativen Wheels auf macOS, Linux, Intel sowie Apple Silicon identisch sind. Testen Sie jede Deployment-Plattform.
Frische der Sperre: --locked nicht --frozen
Standardmäßig können Projektbefehle aktualisiert werden. uv.lock wenn sich die Deklarationen ändern.
Verwenden --locked um sicherzustellen, dass das Schloss mit den Projektmetadaten synchron ist:
uv lock --check
uv sync --locked
uv run --locked pytest
Wenn pyproject.toml und uv.lock Ich stimme nicht zu – diese Befehle scheitern vielmehr, anstatt ein neues Schloss zu erstellen. Normalerweise handelt es sich dabei um das nützliche CI-Gate.
Verwenden --frozen nur dann, wenn man absichtlich möchte, dass der UV den vorhandenen Lock verwendet, ohne zu prüfen, ob er aktuell ist:
uv sync --frozen
Das kann in einer kontrollierten Build-Phase nützlich sein, in der der Lock bereits überprüft wurde, stellt jedoch keinen Detektor für veraltete Locks dar. uv sync Standardmäßig ist dies exakt und entfernt überflüssige Pakete. uv run verwendet standardmäßig eine ungenaue Synchronisierung, es sei denn --exact es wird angefordert.
Gemanagtes Python: Eine Versionsanfrage – kein universelles Binärdatei
uv kann Python-Distributionen herunterladen und verwalten:
uv python install 3.12 3.13
uv python list --only-installed
uv python pin 3.12
Die von uv verwalteten CPython-Builds stammen aus dem python-build-standalone Projekt. uv kann außerdem Systeme sowie Interpreter wie Homebrew, pyenv, Conda und weitere erkennen.
.python-version Es handelt sich um einen Versionsantrag, der durch UV sowie andere kompatible Tools erkannt wird. requires-python in pyproject.toml es handelt sich um den Kompatibilitätsvertrag des Projekts. Beide Aspekte sollten beibehalten werden:
[project]
requires-python = ">=3.12,<3.14"
Pinning 3.12 Es wird nicht garantiert, dass derselbe Patches-Build dauerhaft verfügbar bleibt oder dass auf jedem Betriebssystem dasselbe Artefakt generiert wird. Beantragen Sie einen exakten Patch nur dann, wenn dies tatsächlich erforderlich ist, und stellen Sie sicher, dass der CI-Prozess explizit den zu verwendenden Interpreter auswählt und meldet.
ein anderer Python-Manager, wenn ein Projekt eine Distribution oder eine Build-Konfiguration benötigt, die von uv nicht bereitgestellt wird. uv kann weiterhin diesen Interpreter über … verwenden. --python oder eine normale Entdeckungsphase.
Wählen Sie aus uv run, uvxsowie die installierten Tools
Projektbezogene Tools: uv run
Falls pytest, mypy, ein Codegenerator oder ein anderes Tool das Projekt importieren oder seine gesperrten Plugins verwenden muss, deklarieren Sie es in einer Abhängigkeitsgruppe:
uv add --group lint ruff
uv run --group lint ruff check .
Durchführung dieses Tools uvx Dies würde es vom Projekt isolieren und die installierten Pakete oder Plugins, die es benötigt, verbergen können.
Ad-hoc-Tools: uvx
uvx ist ein Alias für uv tool run. Es erstellt eine isolierte Umgebung, die im einmaligen UV-Cache gespeichert wird:
uvx ruff@0.12.0 check .
uvx --from jupyterlab jupyter lab
uvx --with mkdocs-material mkdocs --help
Festlegen Sie die Tool-Version in der CI-Pipeline oder in der Dokumentation. Bei einem ersten Aufruf ohne Versionsangabe wird automatisch die aktuellste Version verwendet, wodurch spätere Aufrufe den Cache-Zustand wiederverwenden können.
Persistente Ausführbare Dateien: uv tool install
Installieren Sie ein Tool, wenn Skripte, die nicht unter Ihrer Kontrolle stehen, seinen Befehl benötigen. PATHoder wenn das Machine Manifest es absichtlich besitzt:
uv tool install 'ruff==0.12.0'
uv tool list
uv tool upgrade ruff
uv tool uninstall ruff
Persistente Tools verwenden weiterhin isolierte Umgebungen. Verändern Sie diese Umgebungen nicht manuell mithilfe von pip.
Skripte: Ein einzelnes Datei als Release-Einheit definieren
PEP 723 definiert Metadaten für Inline-Skripte. Ein kompatibler Ausführer kann den Kommentarblock lesen und eine isolierte Umgebung erstellen.
# /// 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)
Metadaten mit uv ausführen und bearbeiten:
uv run fetch.py
uv add --script fetch.py rich
uv remove --script fetch.py rich
einfach python fetch.py Es werden die Kommentar-Metadaten ignoriert. Daher ist das Skript trotz weiterhin gültiger Python-Syntax von einem kompatiblen Ausführer abhängig.
Für ein Skript, das eine bestimmte Auflösung später wiederherstellen muss, erstellen Sie einen benachbarten Lock:
uv lock --script fetch.py
uv run --script fetch.py
Dies schreibt fetch.py.lock. Ein exclude-newer Der Zeitstempel kann die möglichen Veröffentlichungsdaten einschränken, ist jedoch weniger wirksam als eine exakt festgelegte Lösung und garantiert nicht, dass das Artefakt weiterhin verfügbar bleibt.
Verwenden Sie stattdessen ein Projekt, wenn mehrere Dateien gemeinsame Abhängigkeiten haben, der Code als Paket importiert werden kann, die Tests den Projektzustand benötigen oder mehrere Skripte zusammengeführt werden müssen.
Anforderungsdateien: Kompatibilität statt Ausfälle
A requirements.txt Die Datei kann lose übergebene Eingabedaten, präzise Pins, Hash-Werte, Einschränkungen, Indizes, URLs oder eine kompilierte Umgebung enthalten. Ihre Reproduzierbarkeit hängt davon ab, wie sie erstellt und verarbeitet wird; der Dateinamen allein sagt nichts aus.
Verwenden Sie die pip-kompatible Schnittstelle von uv, ohne migrieren zu müssen:
uv venv
uv pip sync requirements.txt
uv run python app.py
uv pip sync stellt sicher, dass die Umgebung mit der Datei übereinstimmt, während uv pip install -r es ist additiv.
Für eine eigene Anwendung kann eine schrittweise Migration nützlich sein:
uv init --bare
uv add -r requirements.in
uv add --group test -r requirements-test.in
uv lock
uv sync --locked
Führen Sie vor dem Löschen der alten Dateien den vollständigen Test sowie den Pfad Deployment aus. Falls ein nachgeschaltetes System weiterhin die pip-Formatierung erwartet, erzeugen Sie diese aus dem validierten uv lock:
uv export --format requirements.txt \
--output-file requirements.txt
Verwahren Sie keine Wartung mehr. uv.lock sowie eine manuell bearbeitete Exportversion mit zwei konkurrierenden Auflösungen.
Cache, Indizes und Grenzen der Lieferkette
Der UV-Cache verbessert wiederholte Installationen, bleibt jedoch verwendbar nur einmalig:
uv cache prune
uv cache clean
Bevorzugen prune zur routinemäßigen Reinigung. clean Löscht alle Cache-Einträge und zwingt zu nachfolgenden Downloads sowie Kompilierungen.
Eine Lockdatei erhöht die Wiederholbarkeit; sie macht Abhängigkeiten jedoch nicht zuverlässiger. Überprüfen Sie die Quellen der Pakete, die Indexkonfiguration, die Git-Revisionen, den Build-Prozess Backends, die Lizenzen sowie die Anmeldeinformationen. Bewahren Sie die authentifizierte Indexkonfiguration außerhalb der kommitionierten Dateien auf, es sei denn, das Repository enthält ausschließlich nicht vertrauliche Verweise auf ein genehmigtes Mechanismus zur Verwaltung von Anmeldeinformationen.
Für native Pakete muss die Deployment-Architektur erfasst sowie die Verfügbarkeit der Test-Wheels überprüft werden. Andernfalls muss ein Resolver auf eine Quellcode-Kompilierung ausweichen, bei der Compiler sowie Systembibliotheken benötigt werden, die im CI-Umfeld oder in der Produktumgebung nicht vorhanden sind.
Eine kompakte Betriebskontrollliste
Für jedes Projekt:
- Definieren
requires-pythonsowie die direkten Abhängigkeiten darinpyproject.toml2. Getrennte Verwaltung von veröffentlichten Zusatzinhalten und lokalen Abhängigkeitsgruppen. - Commit-Vorgang durchführen.
uv.lock; ignorieren.venvund Cache-Zustand. - Führen projektbezogene Tools über die Projektumgebung aus.
- Verwenden
uv lock --checkoder--lockedin der CI-Pipeline. - Testen Sie jede Ziel-OS-Plattform sowie jede Architektur, die durch den Lock definiert wird.
- Exportieren Sie Kompatibilitätsformate ausschließlich für benannte, nachgelagerte Verbraucher.
- Überprüfen Sie die Quellcode- und Zertifizierungsrichtlinien unabhängig von der Lösungsfindung.
uv ist am nützlichsten, wenn diese Eigentumsgrenzen weiterhin sichtbar bleiben. Ein einzelnes Binärprogramm kann sie alle verwalten, ohne sie in ein einziges Umfeld zusammenzuführen. Genau diese Kombination – weniger Tools und gleichzeitig keine Behauptung, dass jeder Workflow identisch sei – ist der Grund, warum ich es weiterhin als meine Standard-Tool für Python-Projekte unter macOS verwende.