Zum Inhalt springen

cat posts/uv-python-paketmanager.md

uv: pip und venv in schnell

uv bündelt Paketinstallation, virtuelle Umgebungen, Projektverwaltung, Python-Versionen und isolierte Tools – schnell, reproduzierbar und mit modernen Workflows für pyproject.toml und uv.lock.

In Teil 10 der Python-Serie haben wir venv und pip kennengelernt:

python -m venv .venv
source .venv/bin/activate
python -m pip install rich

Das ist der klassische Weg, Python-Projekte mit eigenen Abhängigkeiten zu verwalten. Er funktioniert und ist wichtig zu verstehen.

Im Alltag stößt dieser Werkzeugkasten aber schnell an Grenzen:

  • venv legt die Umgebung an.
  • pip installiert Pakete.
  • pip-tools oder ähnliche Werkzeuge erzeugen reproduzierbare Lockfiles.
  • pipx installiert Kommandozeilen-Tools isoliert.
  • pyenv oder andere Tools verwalten Python-Versionen.
  • In der CI muss alles wieder korrekt zusammengesetzt werden.

uv bündelt viele dieser Aufgaben in einem einzigen Werkzeug.

Es ist ein eigenständiges, in Rust geschriebenes Programm von Astral, den Leuten hinter Ruff. uv ist sehr schnell, arbeitet mit pyproject.toml, erzeugt eine Lockdatei und kann auf Wunsch auch Python-Versionen und isolierte Tools verwalten.

Was uv ist

uv ist ein moderner Python-Paket- und Projektmanager.

Es kann unter anderem:

  • virtuelle Umgebungen anlegen,
  • Pakete installieren,
  • Projekte über pyproject.toml verwalten,
  • eine reproduzierbare uv.lock erzeugen,
  • Abhängigkeiten synchronisieren,
  • Python-Versionen installieren und pinnen,
  • Tools isoliert ausführen,
  • einzelne Skripte mit eigenen Abhängigkeiten starten.

Dabei ersetzt uv nicht die Python-Sprache, nicht die Standardbibliothek und nicht Dein Verständnis von venv und pip.

Besser formuliert:

uv übernimmt viele Aufgaben, für die man klassisch pip, venv, pipx, pip-tools und teilweise pyenv kombiniert hat.

Du solltest die alten Begriffe trotzdem kennen, weil sie in Dokumentationen, Fehlermeldungen und bestehenden Projekten weiterhin häufig auftauchen.

Warum uv so schnell ist

uv ist in Rust geschrieben und darauf ausgelegt, viele Schritte zu parallelisieren und zu cachen.

Das betrifft unter anderem:

  • Auflösen von Abhängigkeiten,
  • Herunterladen von Paketen,
  • Wiederverwenden bereits geladener Wheels,
  • Erstellen und Synchronisieren von Umgebungen.

Für kleine Lernprojekte ist der Unterschied nett. Für größere Projekte, CI-Pipelines oder häufig neu erzeugte Umgebungen kann er deutlich spürbar sein.

Der wichtigste Vorteil ist aber nicht nur Geschwindigkeit.

uv bringt mehrere bisher getrennte Arbeitsschritte in einen konsistenten Workflow:

uv add rich
uv run python main.py
uv sync

Du musst eine virtuelle Umgebung oft nicht mehr manuell aktivieren, weil uv run das passende Projekt-Environment automatisch verwendet.

uv installieren

uv ist ein eigenständiges Programm. Es wird nicht zuerst in eine bestehende virtuelle Umgebung installiert.

Die offizielle Installationsmethode unter Linux und macOS ist beispielsweise:

curl -LsSf https://astral.sh/uv/install.sh | sh

Unter Windows PowerShell:

irm https://astral.sh/uv/install.ps1 | iex

Je nach Betriebssystem kannst Du uv auch über Paketmanager installieren.

Prüfe danach die Installation:

uv --version

Die Ausgabe sieht ungefähr so aus:

uv 0.x.y

Die genaue Versionsnummer hängt davon ab, wann Du uv installiert oder aktualisiert hast.

Zwei Arbeitsweisen

uv kann in zwei verschiedenen Stilen verwendet werden.

1. Der pip-kompatible Stil

Wenn Du schon einen klassischen venv- und pip-Workflow kennst, kannst Du mit uv ähnlich arbeiten:

uv venv
uv pip install rich

Das legt eine virtuelle Umgebung an und installiert rich.

Diese Kommandos sind besonders nützlich, wenn Du ein bestehendes Projekt mit requirements.txt hast oder uv zunächst als schnellen Ersatz für einzelne pip-Befehle verwenden möchtest.

2. Der Projektstil

Der modernere uv-Workflow verwendet ein Projekt mit:

  • pyproject.toml
  • .venv
  • uv.lock

Typische Kommandos sind dann:

uv init
uv add rich
uv run python main.py
uv sync

Dieser Artikel konzentriert sich vor allem auf den Projektstil, weil er die Stärken von uv am besten zeigt.

Ein neues Projekt anlegen

Lege ein neues Projekt an:

uv init mein-projekt

Wechsle in den Ordner:

cd mein-projekt

uv erzeugt eine einfache Projektstruktur, unter anderem mit einer pyproject.toml.

Je nach uv-Version und gewählter Vorlage kann die Struktur leicht variieren. Typisch ist aber ein Startpunkt wie:

mein-projekt/
├── README.md
├── main.py
└── pyproject.toml

In der pyproject.toml stehen Projektmetadaten und Abhängigkeiten.

Ein stark vereinfachtes Beispiel:

[project]
name = "mein-projekt"
version = "0.1.0"
description = "Ein kleines Python-Projekt"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []

Ein Paket hinzufügen

Installiere rich als Abhängigkeit:

uv add rich

uv erledigt dabei mehrere Dinge:

  1. Es trägt rich in die pyproject.toml ein.
  2. Es erzeugt oder aktualisiert die Lockdatei uv.lock.
  3. Es erstellt bei Bedarf eine .venv.
  4. Es installiert die Abhängigkeiten in diese Umgebung.

Danach enthält die pyproject.toml ungefähr:

[project]
dependencies = [
    "rich>=14.0.0",
]

Die genaue Versionsangabe kann anders aussehen, abhängig vom aktuellen Paketstand.

Code im Projekt ausführen

In main.py kannst Du rich verwenden:

from rich import print

print("[bold green]Willkommen im Dungeon![/bold green]")

Starte das Programm mit:

uv run python main.py

Oder kurz:

uv run main.py

Wenn main.py eine Python-Datei ist, behandelt uv sie als Skript und startet sie mit dem passenden Python.

Der wichtige Punkt:

uv run führt den Code in der passenden Projektumgebung aus.

Du musst die .venv nicht vorher manuell aktivieren.

Warum nicht einfach python main.py?

Wenn Du direkt ausführst:

python main.py

verwendest Du das Python, das gerade in Deiner Shell aktiv ist.

Das kann funktionieren, wenn die .venv aktiviert ist. Es kann aber auch das falsche Python sein, zum Beispiel das System-Python oder eine andere Umgebung.

Mit uv ist der sichere Standard:

uv run python main.py

Oder bei einfachen Skripten:

uv run main.py

So stellt uv sicher, dass die Abhängigkeiten aus dem Projekt verwendet werden.

uv.lock: reproduzierbare Abhängigkeiten

Die pyproject.toml beschreibt, was Dein Projekt direkt benötigt:

dependencies = [
    "rich>=14.0.0",
]

Das ist noch nicht der vollständige exakte Zustand.

rich kann selbst weitere Pakete benötigen. Diese transitiven Abhängigkeiten haben eigene Versionen.

uv schreibt den aufgelösten Zustand in die Datei:

uv.lock

Diese Lockdatei enthält die exakten Versionen, die zusammen installiert werden sollen.

Deshalb gilt:

  • pyproject.toml beschreibt die direkten Anforderungen.
  • uv.lock beschreibt den konkret aufgelösten, reproduzierbaren Stand.

Die uv.lock gehört normalerweise ins Git.

Die .venv gehört dagegen nicht ins Git.

Umgebung synchronisieren

Auf einem anderen Rechner reicht dann:

uv sync

uv liest die pyproject.toml und die uv.lock, erstellt bei Bedarf die virtuelle Umgebung und installiert den gelockten Stand.

Das ist ideal für:

  • neue Entwickler im Projekt,
  • CI-Pipelines,
  • reproduzierbare Builds,
  • saubere Neuinstallationen.

Wenn Du ein Projekt aus Git klonst, ist der typische Ablauf:

git clone <repo>
cd <repo>
uv sync
uv run python main.py

Abhängigkeiten entfernen

Ein Paket entfernst Du mit:

uv remove rich

uv entfernt die Abhängigkeit aus der pyproject.toml, aktualisiert die Lockdatei und synchronisiert die Umgebung.

Das ist besser, als die Datei manuell zu bearbeiten und anschließend zu hoffen, dass die Umgebung noch passt.

Development Dependencies

Nicht jede Abhängigkeit wird zur Laufzeit des Programms gebraucht.

Ruff ist zum Beispiel ein Entwicklungswerkzeug. Dein Programm importiert Ruff nicht, aber Du nutzt es beim Entwickeln.

Solche Pakete kannst Du in eine Dependency Group legen:

uv add --dev ruff

Danach kannst Du Ruff über uv ausführen:

uv run ruff check .
uv run ruff format .

So ist klar:

  • rich wäre eine normale Projektabhängigkeit,
  • ruff ist ein Entwicklungswerkzeug.

In der pyproject.toml werden diese Gruppen getrennt dokumentiert.

Projektbefehle mit uv run

Alles, was in der Projektumgebung verfügbar ist, kannst Du über uv run ausführen:

uv run python main.py
uv run ruff check .
uv run ruff format .

uv run sorgt vor dem Start dafür, dass Lockdatei und Environment zueinander passen.

Das macht den Workflow sehr angenehm: Du musst nicht ständig überlegen, ob die richtige virtuelle Umgebung aktiv ist.

Der klassische Modus: uv venv und uv pip

uv kann auch ohne pyproject.toml wie ein schneller Ersatz für venv und pip verwendet werden.

Eine virtuelle Umgebung anlegen:

uv venv

Das erzeugt standardmäßig .venv.

Aktivieren kannst Du sie wie gewohnt.

Linux und macOS:

source .venv/bin/activate

Windows PowerShell:

.venv\Scripts\Activate.ps1

Dann ein Paket installieren:

uv pip install rich

Oder aus einer requirements.txt:

uv pip install -r requirements.txt

Dieser Modus ist praktisch für bestehende Projekte, die noch nicht auf pyproject.toml und uv.lock umgestellt werden sollen.

Für neue Projekte ist der Projektmodus meist angenehmer.

Python-Versionen verwalten

uv kann auch Python-Versionen installieren:

uv python install 3.13

Für ein Projekt kannst Du eine Version pinnen:

uv python pin 3.13

Dabei entsteht eine Datei wie:

.python-version

uv verwendet diese Information, um für das Projekt die passende Python-Version zu finden oder bei Bedarf zu installieren.

Daneben gibt es in pyproject.toml die Angabe:

requires-python = ">=3.12"

Diese beiden Dinge erfüllen unterschiedliche Aufgaben:

  • requires-python beschreibt, welche Python-Versionen das Projekt unterstützt.
  • .python-version beschreibt, welche Python-Version uv lokal für dieses Projekt verwenden soll.

Beispiel:

requires-python = ">=3.12"

bedeutet: Das Projekt soll mit Python 3.12 oder neuer laufen.

.python-version

mit dem Inhalt

3.13

bedeutet: uv soll in diesem Checkout Python 3.13 verwenden.

Das ist nicht zwingend ein Widerspruch. Python 3.13 erfüllt schließlich >=3.12.

Ein Projekt mit bestimmter Python-Version starten

Du kannst beim Initialisieren oder Ausführen auch direkt eine Python-Version angeben:

uv run --python 3.13 python --version

Oder für ein bestehendes Projekt:

uv python pin 3.13
uv sync

Damit ist der gewünschte Interpreter im Projekt klar dokumentiert.

Gerade in Teams und CI ist das hilfreich, weil nicht jeder Entwickler zufällig dieselbe lokal installierte Python-Version hat.

Tools ausführen mit uvx

Ein weiteres praktisches Feature ist uvx.

uvx ist eine Kurzform für:

uv tool run

Damit führst Du Kommandozeilen-Tools in einer isolierten, temporären Umgebung aus.

Beispiel:

uvx ruff check .

uv lädt Ruff bei Bedarf herunter, cached es und führt es aus, ohne dass Du Ruff dauerhaft global installieren musst.

Weitere Beispiele:

uvx pycowsay "Hallo Dungeon"
uvx httpie --version

Das ist ähnlich zur Idee von pipx run, aber in uv integriert.

Tools dauerhaft installieren

Manche Tools möchtest Du regelmäßig verwenden, aber nicht als Abhängigkeit eines bestimmten Projekts eintragen.

Dafür gibt es:

uv tool install ruff

Danach steht ruff als Kommando zur Verfügung, wird aber isoliert von Deinen Projekten verwaltet.

Aktualisieren:

uv tool upgrade ruff

Entfernen:

uv tool uninstall ruff

Für projektbezogene Werkzeuge wie Ruff ist oft uv add --dev ruff sinnvoller, damit alle im Projekt dieselbe Version verwenden.

Für persönliche Tools, die Du überall nutzen möchtest, passt uv tool install.

Single-File-Skripte mit Abhängigkeiten

uv kann auch einzelne Python-Skripte mit eigenen Abhängigkeiten ausführen.

Dafür gibt es Inline-Metadaten nach PEP 723:

# /// script
# requires-python = ">=3.12"
# dependencies = [
#   "rich",
# ]
# ///

from rich import print

print("[bold green]Läuft ohne manuelles venv.[/bold green]")

Speichere die Datei als skript.py und starte sie:

uv run skript.py

uv liest die Metadaten, richtet eine passende Umgebung ein und führt das Skript aus.

Das ist sehr praktisch für kleine Tools, die Du weitergeben möchtest, ohne ein vollständiges Projekt anzulegen.

Abhängigkeiten zu einem Skript hinzufügen

Du musst den Metadatenblock nicht immer von Hand schreiben.

uv kann eine Abhängigkeit zu einem Skript hinzufügen:

uv add --script skript.py rich

Danach enthält die Datei den passenden Metadatenblock.

Das Skript kann anschließend weiterhin gestartet werden mit:

uv run skript.py

Für größere Projekte ist pyproject.toml besser. Für ein einzelnes Tool ist PEP 723 sehr elegant.

Ein Blick auf pyproject.toml

Nach einigen uv-Kommandos könnte eine pyproject.toml ungefähr so aussehen:

[project]
name = "mein-projekt"
version = "0.1.0"
description = "Ein kleines Python-Projekt"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
    "rich>=14.0.0",
]

[dependency-groups]
dev = [
    "ruff>=0.15.0",
]

Die genauen Versionsnummern hängen vom Zeitpunkt ab.

Wichtig ist die Trennung:

  • [project] enthält Projektmetadaten und normale Abhängigkeiten.
  • [dependency-groups] kann Entwicklungsabhängigkeiten enthalten.
  • uv.lock enthält die vollständig aufgelösten Versionen.

uv im Dungeon-Projekt

Unser Dungeon aus Teil 10 kommt vollständig mit der Standardbibliothek aus.

Er braucht also eigentlich keine externen Pakete.

Trotzdem könnten wir das Projekt mit uv verwalten:

cd dungeon-projekt
uv init

Wenn bereits Dateien existieren, solltest Du prüfen, was uv erzeugt oder ergänzt.

Danach kannst Du das Spiel starten:

uv run python spiel.py

Oder, wenn spiel.py direkt als Skript behandelt wird:

uv run spiel.py

Für Ruff als Entwicklungswerkzeug:

uv add --dev ruff
uv run ruff check .
uv run ruff format .

Damit ist die Ruff-Version Teil des Projekts und nicht nur zufällig lokal installiert.

uv in der CI

In einer CI-Pipeline ist uv besonders praktisch, weil der Ablauf kurz und reproduzierbar ist.

Typisch:

uv sync --locked
uv run ruff check .
uv run ruff format --check .
uv run python spiel.py

--locked sorgt dafür, dass uv die Lockdatei nicht verändert. Wenn pyproject.toml und uv.lock nicht zusammenpassen, schlägt der Schritt fehl.

Das ist in CI sinnvoll: Die Pipeline soll nicht still neue Abhängigkeiten auflösen, sondern prüfen, ob der eingecheckte Stand konsistent ist.

Für Anwendungen mit Tests käme später zum Beispiel hinzu:

uv run pytest

uv.lock und Git

Die Lockdatei gehört normalerweise ins Repository:

uv.lock

Sie sorgt dafür, dass andere Entwickler und die CI denselben aufgelösten Abhängigkeitsstand verwenden.

Nicht ins Git gehören dagegen:

.venv/

und üblicherweise auch Cache-Verzeichnisse.

Eine .gitignore könnte enthalten:

.venv/
__pycache__/
*.pyc

Falls Dein Projekt lokale Spielstände erzeugt:

spielstand.json

requirements.txt mit uv

Viele bestehende Umgebungen erwarten weiterhin eine requirements.txt.

uv kann Abhängigkeiten in andere Formate exportieren. Für einfache Fälle ist das nützlich, wenn ein anderer Dienst noch nicht direkt mit uv.lock arbeitet.

Beispiel:

uv export --format requirements-txt > requirements.txt

Ob Du das brauchst, hängt vom Projekt ab.

Für ein reines uv-Projekt ist normalerweise uv.lock die maßgebliche Datei. requirements.txt ist dann eher ein Export für andere Werkzeuge.

Wann ist uv sinnvoll?

uv lohnt sich besonders, wenn Du:

  • neue Python-Projekte startest,
  • reproduzierbare Abhängigkeiten möchtest,
  • häufig Umgebungen neu aufbaust,
  • CI-Zeiten reduzieren möchtest,
  • Entwicklungswerkzeuge sauber pro Projekt verwalten willst,
  • mehrere Python-Versionen verwendest,
  • kleine Skripte mit Abhängigkeiten weitergeben möchtest.

Auch für Anfänger ist uv angenehm, weil viele Schritte einfacher werden.

Trotzdem ist es gut, venv und pip verstanden zu haben. uv abstrahiert diese Themen nicht vollständig weg, sondern baut auf denselben Konzepten auf: Umgebungen, Interpreter, Abhängigkeiten und Paketversionen.

Wann reicht klassisches venv und pip?

Für sehr kleine Beispiele reicht weiterhin:

python -m venv .venv
python -m pip install paket

Das gilt besonders, wenn Du einem Tutorial folgst, das ausdrücklich diesen Weg verwendet.

Auch in älteren Projekten kann es sinnvoll sein, nicht sofort alles umzustellen.

uv ist ein Werkzeug, kein Muss.

Wenn ein Projekt gut mit pip, venv, requirements.txt oder Poetry funktioniert, sollte eine Migration bewusst passieren und nicht nur wegen eines neuen Tools.

Migration vorsichtig angehen

Ein bestehendes Projekt solltest Du nicht blind umstellen.

Sinnvoller Ablauf:

  1. Aktuellen Stand committen.
  2. Prüfen, wie Abhängigkeiten bisher verwaltet werden.
  3. uv testweise in einem Branch einführen.
  4. pyproject.toml und Lockdatei prüfen.
  5. CI anpassen.
  6. Dokumentation aktualisieren.
  7. Erst danach alte Konfigurationsdateien entfernen.

Besonders bei Projekten mit Poetry, Hatch, PDM, privaten Paketquellen oder komplexen Extras lohnt sich ein genauer Blick.

uv kann sehr viel, aber jedes Projekt hat eigene Gewohnheiten und Anforderungen.

Stolperfallen

  • uv run vergessen: Wer direkt python skript.py ausführt, verwendet möglicherweise nicht die Projektumgebung.

  • .venv ins Git einchecken: Die virtuelle Umgebung ist lokal. Ins Git gehört die uv.lock, nicht die .venv.

  • uv.lock ignorieren: Ohne Lockdatei verlierst Du einen wichtigen Vorteil von uv: reproduzierbare Installationen.

  • pyproject.toml und uv.lock verwechseln: Die pyproject.toml beschreibt Anforderungen, die Lockdatei den konkret aufgelösten Stand.

  • uv add mit uv pip install vermischen: uv add verwaltet Projektabhängigkeiten. uv pip install installiert in eine Umgebung, ohne automatisch die Projektmetadaten zu pflegen.

  • Entwicklungswerkzeuge global installieren, obwohl sie projektabhängig sind: Für Ruff, pytest oder mypy ist oft uv add --dev ... besser als eine globale Installation.

  • uvx für projektfeste Tools verwenden: uvx ruff ist praktisch zum schnellen Ausprobieren. Für ein Projekt sollte die Tool-Version besser in der Projektkonfiguration stehen.

  • requires-python und .python-version verwechseln: Das eine beschreibt unterstützte Versionen, das andere pinnt die lokal gewünschte Version für uv.

  • PEP-723-Skripte mit normalen Projekten verwechseln: Inline-Abhängigkeiten sind ideal für einzelne Skripte. Größere Projekte gehören in eine pyproject.toml.

  • Migration ohne sauberen Git-Stand: uv kann mehrere Dateien ändern. Vorher committen, danach Diffs prüfen.

  • uv als Python-Ersatz verstehen: uv verwaltet Python-Versionen und Pakete. Es ersetzt nicht die Sprache, die Standardbibliothek oder Tests.

Kompakte Übersicht

Aufgabe Klassisch Mit uv
venv anlegen python -m venv .venv uv venv
Paket installieren python -m pip install rich uv add rich im Projekt oder uv pip install rich
Paket entfernen manuell / pip uninstall uv remove rich
Projekt ausführen venv aktivieren, dann python ... uv run python ...
Umgebung synchronisieren pip install -r requirements.txt uv sync
Lockdatei nutzen Zusatztool nötig uv.lock
Python installieren externes Tool uv python install 3.13
Python fürs Projekt pinnen oft pyenv uv python pin 3.13
Tool einmalig ausführen pipx run ... uvx ...
Tool isoliert installieren pipx install ... uv tool install ...
Skript mit Abhängigkeiten manuelles venv uv run skript.py mit PEP 723

Übungen

1. Ein neues uv-Projekt anlegen

Lege ein neues Projekt an, installiere rich und starte das Beispielprogramm.

Lösung
uv init mein-projekt
cd mein-projekt
uv add rich
In `main.py`:
from rich import print

print("[bold green]Hallo uv![/bold green]")
Start:
uv run python main.py

2. Ruff als Development Dependency hinzufügen

Füge Ruff als Entwicklungsabhängigkeit hinzu und führe den Linter aus.

Lösung
uv add --dev ruff
uv run ruff check .
uv run ruff format .
Ruff steht damit in der Projektumgebung zur Verfügung und ist nicht nur global auf Deinem Rechner installiert.

3. Eine Python-Version pinnen

Installiere Python 3.13 mit uv und pinne das Projekt darauf.

Lösung
uv python install 3.13
uv python pin 3.13
uv run python --version
Die Datei `.python-version` dokumentiert die gewünschte Version für das Projekt.

4. Ein Tool mit uvx ausführen

Führe Ruff einmalig über uvx aus, ohne es dem Projekt hinzuzufügen.

Lösung
uvx ruff check .
Das ist praktisch zum schnellen Ausprobieren. Für ein dauerhaftes Projekt ist `uv add --dev ruff` meist besser.

5. Ein PEP-723-Skript schreiben

Lege ein einzelnes Skript mit eigener Abhängigkeit an und starte es mit uv.

Lösung `skript.py`:
# /// script
# requires-python = ">=3.12"
# dependencies = [
#   "rich",
# ]
# ///

from rich import print

print("[bold cyan]Single-File-Skript mit Abhängigkeit[/bold cyan]")
Start:
uv run skript.py

Vertiefung

Das Schwestertool von Astral für Linting und Formatierung:

Ruff: Linter und Formatter in einem

Der klassische Einstieg, auf dem uv aufbaut:

Python lernen, Teil 10: Module und Projektstruktur

Fazit

uv macht Python-Projektverwaltung deutlich angenehmer.

Für neue Projekte ist der typische Workflow kurz:

uv init
uv add rich
uv run python main.py

Für reproduzierbare Umgebungen:

uv sync

Für Entwicklungswerkzeuge:

uv add --dev ruff
uv run ruff check .

Für einzelne Tools:

uvx ruff check .

Und für Skripte mit Inline-Abhängigkeiten:

uv run skript.py

Der wichtigste Unterschied zum klassischen Workflow ist nicht nur die Geschwindigkeit. uv verbindet Umgebung, Abhängigkeiten, Lockdatei, Python-Versionen und Tool-Ausführung zu einem einheitlichen Modell.

Trotzdem bleibt das Grundverständnis aus venv und pip wichtig. uv macht diese Konzepte bequemer, aber nicht magisch.

Weiterlesen

0 Kommentare

Noch keine Kommentare. Sei der/die Erste!