Saltar a contenido

uv

Esta página es la referencia completa de uv. Si es tu primer contacto con el proyecto, empieza por la guía rápida de entorno.

uv es una herramienta para gestionar proyectos, versiones de Python, dependencias y entornos virtuales. La desarrolla Astral, el mismo equipo que mantiene ruff. En este curso usamos su modo proyecto: las dependencias se declaran en un archivo, se resuelven de forma reproducible y se ejecutan dentro de un entorno aislado.

El flujo normal se realiza dentro de VS Code: abre la carpeta del proyecto, selecciona el intérprete de .venv y ejecuta los comandos en Terminal → Nueva terminal. uv gestiona el entorno; VS Code es el lugar principal para editar, ejecutar y depurar.

Qué aprenderás

Al terminar esta referencia podrás:

  • distinguir la declaración, la resolución y la instalación de una dependencia;
  • crear o preparar un proyecto sin instalar paquetes globalmente;
  • añadir, quitar y actualizar dependencias de ejecución y de desarrollo;
  • ejecutar scripts, módulos, cuadernos marimo y herramientas con el intérprete correcto;
  • diagnosticar los problemas habituales de ruta, intérprete y lockfile.

La idea central: cuatro piezas

En un proyecto gestionado por uv, cada archivo responde a una pregunta distinta:

Pieza Qué contiene Se versiona
pyproject.toml Nombre del proyecto, versión compatible de Python y dependencias directas Sí
uv.lock Una resolución concreta: versiones y dependencias transitivas compatibles Sí
.python-version Versión de Python que se prefiere al trabajar en el proyecto Sí
.venv Entorno virtual local donde se instalan Python y los paquetes No

La relación entre ellas es:

pyproject.toml --uv lock--> uv.lock --uv sync--> .venv --uv run--> programa

pyproject.toml expresa la intención del proyecto. Por ejemplo, puede pedir pandas>=3. uv.lock guarda la solución concreta que satisface esa restricción, junto con las dependencias que pandas necesita. .venv es la instalación local de esa solución. uv run ejecuta un comando usando ese entorno.

Por eso no se debe editar uv.lock a mano ni confiar en un python global: las decisiones del proyecto deben pasar por uv.

Tres acciones que conviene separar

  • Declarar: uv add pandas escribe la dependencia directa en pyproject.toml.
  • Resolver: uv lock calcula versiones compatibles y actualiza uv.lock.
  • Sincronizar: uv sync instala en .venv lo que indica el lockfile.

uv add realiza las tres acciones habitualmente. Separarlas resulta útil para entender qué ha cambiado y para diagnosticar un problema.

Antes de ejecutar un comando

Sitúate en la carpeta que contiene pyproject.toml. Puedes comprobarlo desde la terminal integrada de VS Code:

pwd
ls pyproject.toml

En Windows PowerShell, el equivalente de la segunda línea es:

Get-ChildItem pyproject.toml

Si uv muestra No pyproject.toml found, normalmente no falta ninguna dependencia: estás en otra carpeta. Entra en la raíz del proyecto con cd y repite el comando.

Flujo básico

Crear un proyecto

Para empezar un proyecto desde cero:

Terminal integrada de VS Code
mkdir mi_proyecto
cd mi_proyecto
uv init --python 3.14
uv add marimo numpy pandas matplotlib seaborn scikit-learn

uv init crea la configuración inicial y pyproject.toml. La opción --python 3.14 declara la versión de Python que necesita el proyecto y genera .python-version con 3.14. Finalmente, uv add declara las librerías, resuelve sus versiones y prepara .venv.

No hace falta ejecutar uv python pin 3.14 después de uv init --python 3.14: en este flujo sería redundante. Usa uv python pin cuando el proyecto ya existe y quieras crear o cambiar .python-version sin volver a inicializarlo. Ese cambio no modifica automáticamente el requisito requires-python de pyproject.toml.

Efecto observable: al terminar aparecen o se actualizan pyproject.toml, .python-version, uv.lock y .venv. El número de paquetes resueltos puede variar cuando se actualiza el lockfile, pero las dependencias directas quedan registradas en pyproject.toml.

No ejecutes este bloque dentro de un proyecto que ya tiene su propio pyproject.toml: en ese caso usa el flujo de proyecto existente.

Preparar un proyecto existente

Después de clonar un repositorio o cambiar de equipo:

Terminal integrada de VS Code
cd mi_proyecto
uv sync --locked
uv run python --version
uv run python -c "import pandas; print(pandas.__version__)"

uv sync --locked crea .venv si todavía no existe y lo sincroniza con el lockfile sin resolver versiones nuevas. Si pyproject.toml y uv.lock no están al día, el comando falla para que puedas revisar el cambio; usa uv sync sin --locked solo cuando estés actualizando deliberadamente la resolución.

uv run usa el Python del proyecto y no exige activar .venv manualmente. Además, comprueba que el entorno esté sincronizado antes de ejecutar el comando. Es la forma recomendada para scripts, módulos y herramientas del curso.

Salida esperada en este repositorio:

Python 3.14.3
3.0.5

La primera línea confirma el intérprete y la segunda la versión de pandas instalada por el lockfile actual. Si el lockfile se actualiza en el futuro, la versión concreta puede cambiar de forma controlada.

Exigir que el lockfile no cambie

En una comprobación reproducible (por ejemplo, al corregir una entrega o en una integración continua, CI, que comprueba cada cambio automáticamente), usa --locked:

uv sync --locked

El comando falla si uv.lock no existe o ya no corresponde con pyproject.toml; no intenta resolver una versión nueva. Para comprobar solo esa coherencia sin sincronizar el entorno:

uv lock --check

Salida esperada: puede mostrar una línea como Resolved ... packages in ... y termina con código de salida 0 cuando todo es correcto. Un código distinto indica que hay que revisar el lockfile, normalmente ejecutando uv lock y examinando el cambio resultante.

Dependencias del proyecto

Añadir y quitar paquetes

Cada línea del bloque siguiente es una operación independiente:

uv add pandas
uv add "pandas>=3,<4"
uv add --dev pytest ruff
uv remove pandas
  • uv add pandas añade una dependencia de ejecución.
  • Una restricción como "pandas>=3,<4" expresa el intervalo compatible. Las comillas evitan que algunos intérpretes de comandos interpreten < y >.
  • uv add --dev añade herramientas necesarias para desarrollar, probar o revisar el proyecto, pero no para ejecutar su funcionalidad principal.
  • uv remove elimina una dependencia directa y recalcula el entorno. Un paquete podría continuar instalado si otra dependencia todavía lo necesita.

Efecto observable: pyproject.toml registra o elimina la dependencia, uv.lock recalcula la resolución y .venv queda sincronizado. Revisa esos archivos con el control de cambios; no hace falta tocar uv.lock manualmente.

El nombre del paquete es el nombre que recibe uv; el nombre de importación puede ser diferente. Por ejemplo:

uv add scikit-learn
import sklearn

Actualizar versiones de forma deliberada

Las restricciones de pyproject.toml limitan qué versiones son aceptables, pero el lockfile conserva una elección concreta. Para actualizar solo un paquete y después instalarlo:

uv lock --upgrade-package pandas
uv sync

Para actualizar todas las dependencias permitidas por sus restricciones:

uv lock --upgrade
uv sync

Antes de subir el cambio, revisa pyproject.toml y uv.lock. Actualizar no significa que el código siga siendo compatible automáticamente: ejecuta las comprobaciones del proyecto después.

Consultar el árbol

uv tree
uv tree --depth 0

uv tree muestra las dependencias directas y transitivas. --depth 0 limita la vista a las dependencias directas y es útil para una comprobación rápida.

La lista vigente de dependencias está siempre en pyproject.toml, y uv tree --depth 0 la muestra; no la dupliques en otro archivo sin necesidad.

Versiones de Python

uv también puede localizar e instalar intérpretes de Python:

uv python list
uv python install 3.14
uv python pin 3.14

Estas órdenes tienen funciones distintas:

  • uv python list muestra las versiones disponibles o instaladas;
  • uv python install 3.14 instala esa versión si uv no la encuentra;
  • uv python pin 3.14 fija la versión preferida del proyecto en .python-version.

No confundas dos restricciones relacionadas:

  • requires-python en pyproject.toml expresa qué versiones puede soportar el proyecto, por ejemplo >=3.14;
  • .python-version indica qué versión se usará normalmente al trabajar en el proyecto.

La primera es un requisito del proyecto; la segunda es una preferencia local compartida con el equipo.

Ejecutar código y herramientas

Usa uv run delante del comando que deba ejecutarse dentro del entorno:

uv run python script.py
uv run python -m paquete.modulo
uv run marimo edit cuaderno.py
uv run zensical build

Esto evita el error habitual de instalar una librería en .venv y ejecutar el programa con otro Python. El comando python script.py solo es equivalente si el terminal tiene activado el entorno correcto.

La activación es opcional. Si necesitas escribir muchos comandos sin el prefijo uv run, puedes activar el entorno temporalmente:

source .venv/bin/activate
python script.py
deactivate
.venv\Scripts\Activate.ps1
python script.py
deactivate

Activar .venv solo cambia el PATH de esa terminal; no declara ni fija dependencias. En VS Code, selecciona el mismo intérprete desde Python: Select Interpreter, normalmente .venv/bin/python en Linux y macOS o .venv\Scripts\python.exe en Windows. Para cuadernos, consulta la guía de marimo.

uvx: herramientas de un solo uso

uvx ejecuta una herramienta en un entorno aislado y temporal, normalmente reutilizando la caché de uv. No añade la herramienta a pyproject.toml, no modifica uv.lock y no la instala como dependencia del proyecto.

Por ejemplo, para revisar código con ruff sin incorporarlo al proyecto:

uvx ruff check .

Efecto observable: ruff analiza los archivos y muestra sus diagnósticos; los archivos de dependencias del proyecto no cambian. Si una herramienta forma parte del flujo obligatorio del equipo, declárala como dependencia de desarrollo y ejecútala con uv run:

uv add --dev ruff
uv run ruff check .

uv pip: caso avanzado

uv pip ofrece una interfaz compatible con el flujo de pip, pero no modifica pyproject.toml ni uv.lock. Puede ser útil para trabajar explícitamente con un entorno virtual que no está gestionado como proyecto.

source .venv/bin/activate
uv pip install pandas
.venv\Scripts\Activate.ps1
uv pip install pandas

En el modo proyecto del curso, usa uv add para las dependencias normales. Una instalación hecha solo con uv pip puede desaparecer al ejecutar uv sync, porque no está declarada en el proyecto. No uses uv pip install --system: las instalaciones globales dificultan saber qué Python y qué versiones utiliza un programa.

Reproducibilidad y control de versiones

Versiona estos archivos:

pyproject.toml
uv.lock
.python-version

No versiones .venv, cachés ni secretos como .env. El entorno virtual se recrea en cualquier equipo con:

uv sync

Después de cambiar pyproject.toml con uv add, uv remove o una edición revisada, incluye también uv.lock en el mismo commit. Al comprobar una contribución, uv sync --locked detecta si ambos archivos siguen siendo coherentes.

No mezcles dos fuentes de verdad

No instales una dependencia con pip o uv pip y esperes que el proyecto la recuerde. Declárala con uv add; así queda documentada, resuelta y disponible para el resto del equipo.

Problemas habituales

Síntoma Causa probable Comprobación o solución
No pyproject.toml found La terminal está fuera de la raíz del proyecto Ejecuta pwd y entra con cd en la carpeta correcta
No such file or directory: marimo El paquete no está sincronizado o se ejecutó sin el entorno Ejecuta uv sync y después uv run marimo --version
ModuleNotFoundError aunque instalaste el paquete El programa usa otro intérprete de Python Ejecuta el programa con uv run y selecciona .venv en VS Code
uv.lock necesita cambios El lockfile no refleja pyproject.toml Ejecuta uv lock, revisa el diff y vuelve a sincronizar
Un paquete instalado manualmente desaparece No estaba declarado en el proyecto Sustituye uv pip install ... por uv add ...
VS Code marca imports como inexistentes Tiene seleccionado otro intérprete Usa Python: Select Interpreter y elige el de .venv

Comandos de referencia rápida

Necesidad Comando
Comprobar la versión de uv uv --version
Crear la configuración inicial uv init --python 3.14
Fijar Python para un proyecto existente uv python pin 3.14
Sincronizar un proyecto clonado uv sync
Sin permitir cambios en el lockfile uv sync --locked
Añadir una dependencia uv add paquete
Añadir una herramienta de desarrollo uv add --dev herramienta
Quitar una dependencia uv remove paquete
Resolver sin instalar uv lock
Comprobar la resolución uv lock --check
Actualizar una dependencia uv lock --upgrade-package paquete
Consultar dependencias uv tree
Forzar reinstalación uv sync --reinstall
Ejecutar un script uv run python script.py
Abrir un cuaderno en el editor web uv run marimo edit cuaderno.py
Ejecutar una herramienta aislada uvx herramienta

Comprobación final

Desde la raíz de este proyecto, ejecuta:

uv lock --check
uv run python -c "import marimo, numpy, pandas, sklearn; print('Entorno listo')"

Salida esperada:

Entorno listo

La comprobación aporta una evidencia pequeña pero útil: el lockfile es coherente y el intérprete del proyecto puede importar varias dependencias fundamentales. Las prácticas y los cuadernos deben añadir después sus propias comprobaciones de comportamiento.

Siguiente paso

Con esto cierras las herramientas del curso. Empieza el contenido: Programación de IA o Machine Learning.

Para ampliar la referencia, consulta la documentación oficial de uv y, para el trabajo interactivo, la guía de cuadernos marimo.