|
|
|
|
|
|
|
|
|
|
|
<!doctype html><!-- This is a valid HTML5 document. --> |
|
|
|
|
|
<!-- Screen readers, SEO, extensions and so on. --> |
|
|
|
|
|
<html lang="en"> |
|
|
|
|
|
<!-- Has to be within the first 1024 bytes, hence before the `title` element |
|
|
|
|
|
See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset --> |
|
|
|
|
|
<meta charset="utf-8"> |
|
|
|
|
|
<!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 --> |
|
|
|
|
|
<!-- The viewport meta is quite crowded and we are responsible for that. |
|
|
|
|
|
See: https://codepen.io/tigt/post/meta-viewport-for-2015 --> |
|
|
|
|
|
<meta name="viewport" content="width=device-width,initial-scale=1"> |
|
|
|
|
|
<!-- Required to make a valid HTML5 document. --> |
|
|
|
|
|
<title>uv: Python packaging in Rust (archive) — David Larlet</title> |
|
|
|
|
|
<meta name="description" content="Publication mise en cache pour en conserver une trace."> |
|
|
|
|
|
<!-- That good ol' feed, subscribe :). --> |
|
|
|
|
|
<link rel="alternate" type="application/atom+xml" title="Feed" href="/david/log/"> |
|
|
|
|
|
<!-- Generated from https://realfavicongenerator.net/ such a mess. --> |
|
|
|
|
|
<link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons2/apple-touch-icon.png"> |
|
|
|
|
|
<link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons2/favicon-32x32.png"> |
|
|
|
|
|
<link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons2/favicon-16x16.png"> |
|
|
|
|
|
<link rel="manifest" href="/static/david/icons2/site.webmanifest"> |
|
|
|
|
|
<link rel="mask-icon" href="/static/david/icons2/safari-pinned-tab.svg" color="#07486c"> |
|
|
|
|
|
<link rel="shortcut icon" href="/static/david/icons2/favicon.ico"> |
|
|
|
|
|
<meta name="msapplication-TileColor" content="#f7f7f7"> |
|
|
|
|
|
<meta name="msapplication-config" content="/static/david/icons2/browserconfig.xml"> |
|
|
|
|
|
<meta name="theme-color" content="#f7f7f7" media="(prefers-color-scheme: light)"> |
|
|
|
|
|
<meta name="theme-color" content="#272727" media="(prefers-color-scheme: dark)"> |
|
|
|
|
|
<!-- Is that even respected? Retrospectively? What a shAItshow… |
|
|
|
|
|
https://neil-clarke.com/block-the-bots-that-feed-ai-models-by-scraping-your-website/ --> |
|
|
|
|
|
<meta name="robots" content="noai, noimageai"> |
|
|
|
|
|
<!-- Documented, feel free to shoot an email. --> |
|
|
|
|
|
<link rel="stylesheet" href="/static/david/css/style_2021-01-20.css"> |
|
|
|
|
|
<!-- See https://www.zachleat.com/web/comprehensive-webfonts/ for the trade-off. --> |
|
|
|
|
|
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin> |
|
|
|
|
|
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin> |
|
|
|
|
|
<link rel="preload" href="/static/david/css/fonts/triplicate_t4_poly_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)" crossorigin> |
|
|
|
|
|
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_regular.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> |
|
|
|
|
|
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_bold.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> |
|
|
|
|
|
<link rel="preload" href="/static/david/css/fonts/triplicate_t3_italic.woff2" as="font" type="font/woff2" media="(prefers-color-scheme: dark)" crossorigin> |
|
|
|
|
|
<script> |
|
|
|
|
|
function toggleTheme(themeName) { |
|
|
|
|
|
document.documentElement.classList.toggle( |
|
|
|
|
|
'forced-dark', |
|
|
|
|
|
themeName === 'dark' |
|
|
|
|
|
) |
|
|
|
|
|
document.documentElement.classList.toggle( |
|
|
|
|
|
'forced-light', |
|
|
|
|
|
themeName === 'light' |
|
|
|
|
|
) |
|
|
|
|
|
} |
|
|
|
|
|
const selectedTheme = localStorage.getItem('theme') |
|
|
|
|
|
if (selectedTheme !== 'undefined') { |
|
|
|
|
|
toggleTheme(selectedTheme) |
|
|
|
|
|
} |
|
|
|
|
|
</script> |
|
|
|
|
|
|
|
|
|
|
|
<meta name="robots" content="noindex, nofollow"> |
|
|
|
|
|
<meta content="origin-when-cross-origin" name="referrer"> |
|
|
|
|
|
<!-- Canonical URL for SEO purposes --> |
|
|
|
|
|
<link rel="canonical" href="https://astral.sh/blog/uv"> |
|
|
|
|
|
|
|
|
|
|
|
<body class="remarkdown h1-underline h2-underline h3-underline em-underscore hr-center ul-star pre-tick" data-instant-intensity="viewport-all"> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<article> |
|
|
|
|
|
<header> |
|
|
|
|
|
<h1>uv: Python packaging in Rust</h1> |
|
|
|
|
|
</header> |
|
|
|
|
|
<nav> |
|
|
|
|
|
<p class="center"> |
|
|
|
|
|
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home"> |
|
|
|
|
|
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use> |
|
|
|
|
|
</svg> Accueil</a> • |
|
|
|
|
|
<a href="https://astral.sh/blog/uv" title="Lien vers le contenu original">Source originale</a> |
|
|
|
|
|
<br> |
|
|
|
|
|
Mis en cache le 2024-02-17 |
|
|
|
|
|
</p> |
|
|
|
|
|
</nav> |
|
|
|
|
|
<hr> |
|
|
|
|
|
<p><strong>TL;DR:</strong> <a href="https://github.com/astral-sh/uv">uv</a> is an <strong>extremely fast Python package |
|
|
|
|
|
installer and resolver</strong>, written in Rust, and designed as a drop-in replacement for <code>pip</code> and |
|
|
|
|
|
<code>pip-tools</code> workflows.</p> |
|
|
|
|
|
<p><a href="https://github.com/astral-sh/uv">uv</a> represents a milestone in our pursuit of a <a href="https://blog.rust-lang.org/2016/05/05/cargo-pillars.html#pillars-of-cargo">"Cargo for Python"</a>: |
|
|
|
|
|
a comprehensive Python project and package manager that's fast, reliable, and easy to use.</p> |
|
|
|
|
|
<p>As part of this release, we're also taking stewardship of <a href="https://github.com/mitsuhiko/rye">Rye</a>, |
|
|
|
|
|
an experimental Python packaging tool from <a href="https://github.com/mitsuhiko">Armin Ronacher</a>. We'll |
|
|
|
|
|
maintain <a href="https://github.com/mitsuhiko/rye">Rye</a> as we expand <a href="https://github.com/astral-sh/uv">uv</a> into a unified successor |
|
|
|
|
|
project, to fulfill our <a href="https://rye-up.com/philosophy/">shared vision</a> for Python packaging.</p> |
|
|
|
|
|
<hr> |
|
|
|
|
|
<p>At Astral, we build high-performance developer tools for the Python ecosystem. We're best known |
|
|
|
|
|
for <a href="https://github.com/astral-sh/ruff">Ruff</a>, an extremely fast |
|
|
|
|
|
Python <a href="https://notes.crmarsh.com/python-tooling-could-be-much-much-faster">linter</a> |
|
|
|
|
|
and <a href="https://astral.sh/blog/the-ruff-formatter">formatter</a>.</p> |
|
|
|
|
|
<p>Today, we're releasing the next tool in the Astral toolchain: <strong><a href="https://github.com/astral-sh/uv">uv</a>, an extremely fast Python |
|
|
|
|
|
package resolver and installer, written in Rust</strong>.</p> |
|
|
|
|
|
<div><div class="md:hidden"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 422 250"><g class="uv-warm-vertical-benchmark_svg__mark-group uv-warm-vertical-benchmark_svg__role-frame uv-warm-vertical-benchmark_svg__root" aria-roledescription="group mark container" fill="none" stroke-miterlimit="10"><path class="uv-warm-vertical-benchmark_svg__background" aria-hidden="true" d="M90 0Z"></path><g class="uv-warm-vertical-benchmark_svg__mark-group uv-warm-vertical-benchmark_svg__role-scope uv-warm-vertical-benchmark_svg__cell" aria-roledescription="group mark container"><path class="uv-warm-vertical-benchmark_svg__background" aria-hidden="true" d="M90 0h300v90H90Z"></path><g class="uv-warm-vertical-benchmark_svg__mark-group uv-warm-vertical-benchmark_svg__role-axis" aria-hidden="true"><path class="uv-warm-vertical-benchmark_svg__background" aria-hidden="true" d="M90.5 90.5Z" pointer-events="none"></path><g class="uv-warm-vertical-benchmark_svg__mark-rule uv-warm-vertical-benchmark_svg__role-axis-grid" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M90.5 90.5V.5M176.5 90.5V.5M261.5 90.5V.5M347.5 90.5V.5"></path></g></g><g class="uv-warm-vertical-benchmark_svg__mark-group uv-warm-vertical-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="X-axis for a linear scale with values from 0.0 to 3.5"><path class="uv-warm-vertical-benchmark_svg__background" aria-hidden="true" d="M90.5 90.5Z" pointer-events="none"></path><g class="uv-warm-vertical-benchmark_svg__mark-rule uv-warm-vertical-benchmark_svg__role-axis-tick" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M347.5 90.5"></path></g><g class="uv-warm-vertical-benchmark_svg__mark-text uv-warm-vertical-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="middle" transform="translate(90.5 105.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">0s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(176.214 105.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">1s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(261.929 105.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">2s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(347.643 105.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">3s |
|
|
|
|
|
</text></g></g><g class="uv-warm-vertical-benchmark_svg__mark-group uv-warm-vertical-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="Y-axis for a discrete scale with 4 values: uv, poetry, pip-compile, pdm"><path class="uv-warm-vertical-benchmark_svg__background" aria-hidden="true" d="M90.5.5Z" pointer-events="none"></path><g class="uv-warm-vertical-benchmark_svg__mark-text uv-warm-vertical-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="end" transform="translate(80.5 15.25)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel" font-weight="bold">uv |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(80.5 37.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">poetry |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(80.5 60.25)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">pip-compile |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(80.5 82.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">pdm |
|
|
|
|
|
</text></g></g><g class="uv-warm-vertical-benchmark_svg__mark-rect uv-warm-vertical-benchmark_svg__role-mark uv-warm-vertical-benchmark_svg__child_layer_0_marks" aria-roledescription="rect mark container"><path aria-label="Sum of time: 0.0134756369786; tool: uv" aria-roledescription="bar" d="M90 4.75h1.155v13H90Z" class="uv-warm-vertical-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 0.60278702674; tool: poetry" aria-roledescription="bar" d="M90 27.25h51.667v13H90Z" class="uv-warm-vertical-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 1.55616658094; tool: pip-compile" aria-roledescription="bar" d="M90 49.75h133.386v13H90Z" class="uv-warm-vertical-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 3.37404433084; tool: pdm" aria-roledescription="bar" d="M90 72.25h289.204v13H90Z" class="uv-warm-vertical-benchmark_svg__benchmarkBar"></path></g><g class="uv-warm-vertical-benchmark_svg__mark-text uv-warm-vertical-benchmark_svg__role-mark uv-warm-vertical-benchmark_svg__child_layer_1_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.60278702674; tool: poetry; timeFormat: 0.60s" aria-roledescription="text mark" transform="translate(147.667 37.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">0.60s |
|
|
|
|
|
</text><text aria-label="Sum of time: 1.55616658094; tool: pip-compile; timeFormat: 1.56s" aria-roledescription="text mark" transform="translate(229.386 60.25)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">1.56s |
|
|
|
|
|
</text><text aria-label="Sum of time: 3.37404433084; tool: pdm; timeFormat: 3.37s" aria-roledescription="text mark" transform="translate(385.204 82.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">3.37s |
|
|
|
|
|
</text></g><g class="uv-warm-vertical-benchmark_svg__mark-text uv-warm-vertical-benchmark_svg__role-mark uv-warm-vertical-benchmark_svg__child_layer_2_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.0134756369786; tool: uv; timeFormat: 0.01s" aria-roledescription="text mark" transform="translate(97.155 15.25)" font-family="Roboto Mono,monospace" font-size="12" font-weight="bold" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">0.01s |
|
|
|
|
|
</text></g><path class="uv-warm-vertical-benchmark_svg__background" aria-hidden="true" d="M90 143h300v90H90Z"></path><g class="uv-warm-vertical-benchmark_svg__mark-group uv-warm-vertical-benchmark_svg__role-axis" aria-hidden="true"><path class="uv-warm-vertical-benchmark_svg__background" aria-hidden="true" d="M90.5 233.5Z" pointer-events="none"></path><g class="uv-warm-vertical-benchmark_svg__mark-rule uv-warm-vertical-benchmark_svg__role-axis-grid" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M90.5 233.5v-90M210.5 233.5v-90M330.5 233.5v-90"></path></g></g><g class="uv-warm-vertical-benchmark_svg__mark-group uv-warm-vertical-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="X-axis for a linear scale with values from 0 to 5"><path class="uv-warm-vertical-benchmark_svg__background" aria-hidden="true" d="M90.5 233.5Z" pointer-events="none"></path><g class="uv-warm-vertical-benchmark_svg__mark-rule uv-warm-vertical-benchmark_svg__role-axis-tick" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M330.5 233.5"></path></g><g class="uv-warm-vertical-benchmark_svg__mark-text uv-warm-vertical-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="middle" transform="translate(90.5 248.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">0s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(210.5 248.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">2s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(330.5 248.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">4s |
|
|
|
|
|
</text></g></g><g class="uv-warm-vertical-benchmark_svg__mark-group uv-warm-vertical-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="Y-axis for a discrete scale with 4 values: uv, poetry, pdm, pip-sync"><path class="uv-warm-vertical-benchmark_svg__background" aria-hidden="true" d="M90.5 143.5Z" pointer-events="none"></path><g class="uv-warm-vertical-benchmark_svg__mark-text uv-warm-vertical-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="end" transform="translate(80.5 158.25)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel" font-weight="bold">uv |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(80.5 180.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">poetry |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(80.5 203.25)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">pdm |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(80.5 225.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">pip-sync |
|
|
|
|
|
</text></g></g><g class="uv-warm-vertical-benchmark_svg__mark-rect uv-warm-vertical-benchmark_svg__role-mark uv-warm-vertical-benchmark_svg__child_layer_0_marks" aria-roledescription="rect mark container"><path aria-label="Sum of time: 0.0576289908; tool: uv" aria-roledescription="bar" d="M90 147.75h3.458v13H90Z" class="uv-warm-vertical-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 0.9872183659; tool: poetry" aria-roledescription="bar" d="M90 170.25h59.233v13H90Z" class="uv-warm-vertical-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 1.8969612492; tool: pdm" aria-roledescription="bar" d="M90 192.75h113.818v13H90Z" class="uv-warm-vertical-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 4.6313483826; tool: pip-sync" aria-roledescription="bar" d="M90 215.25h277.88v13H90Z" class="uv-warm-vertical-benchmark_svg__benchmarkBar"></path></g><g class="uv-warm-vertical-benchmark_svg__mark-text uv-warm-vertical-benchmark_svg__role-mark uv-warm-vertical-benchmark_svg__child_layer_1_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.9872183659; tool: poetry; timeFormat: 0.99s" aria-roledescription="text mark" transform="translate(155.233 180.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">0.99s |
|
|
|
|
|
</text><text aria-label="Sum of time: 1.8969612492; tool: pdm; timeFormat: 1.90s" aria-roledescription="text mark" transform="translate(209.818 203.25)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">1.90s |
|
|
|
|
|
</text><text aria-label="Sum of time: 4.6313483826; tool: pip-sync; timeFormat: 4.63s" aria-roledescription="text mark" transform="translate(373.88 225.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">4.63s |
|
|
|
|
|
</text></g><g class="uv-warm-vertical-benchmark_svg__mark-text uv-warm-vertical-benchmark_svg__role-mark uv-warm-vertical-benchmark_svg__child_layer_2_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.0576289908; tool: uv; timeFormat: 0.06s" aria-roledescription="text mark" transform="translate(99.458 158.25)" font-family="Roboto Mono,monospace" font-size="12" font-weight="bold" class="uv-warm-vertical-benchmark_svg__benchmarkLabel">0.06s |
|
|
|
|
|
</text></g></g></g></svg></div><div class="hidden md:block"><div class="flex flex-col items-center text-flare md:flex-row md:justify-center"><div class="w-full md:w-[484px]"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 454 139"><g class="uv-resolve-warm-benchmark_svg__mark-group uv-resolve-warm-benchmark_svg__role-frame uv-resolve-warm-benchmark_svg__root" aria-roledescription="group mark container" fill="none" stroke-miterlimit="10"><path class="uv-resolve-warm-benchmark_svg__background" aria-hidden="true" d="M106 16h300v90H106Z"></path><g class="uv-resolve-warm-benchmark_svg__mark-group uv-resolve-warm-benchmark_svg__role-axis" aria-hidden="true"><path class="uv-resolve-warm-benchmark_svg__background" aria-hidden="true" d="M106.5 106.5Z" pointer-events="none"></path><g class="uv-resolve-warm-benchmark_svg__mark-rule uv-resolve-warm-benchmark_svg__role-axis-grid" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M106.5 106.5v-90M192.5 106.5v-90M277.5 106.5v-90M363.5 106.5v-90"></path></g></g><g class="uv-resolve-warm-benchmark_svg__mark-group uv-resolve-warm-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="X-axis for a linear scale with values from 0.0 to 3.5"><path class="uv-resolve-warm-benchmark_svg__background" aria-hidden="true" d="M106.5 106.5Z" pointer-events="none"></path><g class="uv-resolve-warm-benchmark_svg__mark-rule uv-resolve-warm-benchmark_svg__role-axis-tick" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M363.5 106.5"></path></g><g class="uv-resolve-warm-benchmark_svg__mark-text uv-resolve-warm-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="middle" transform="translate(106.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-resolve-warm-benchmark_svg__benchmarkLabel">0s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(192.214 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-resolve-warm-benchmark_svg__benchmarkLabel">1s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(277.929 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-resolve-warm-benchmark_svg__benchmarkLabel">2s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(363.643 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-resolve-warm-benchmark_svg__benchmarkLabel">3s |
|
|
|
|
|
</text></g></g><g class="uv-resolve-warm-benchmark_svg__mark-group uv-resolve-warm-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="Y-axis for a discrete scale with 4 values: uv, poetry, pip-compile, pdm"><path class="uv-resolve-warm-benchmark_svg__background" aria-hidden="true" d="M106.5 16.5Z" pointer-events="none"></path><g class="uv-resolve-warm-benchmark_svg__mark-text uv-resolve-warm-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="end" transform="translate(96.5 31.25)" font-family="Roboto Mono,monospace" font-size="12" class="uv-resolve-warm-benchmark_svg__benchmarkLabel" font-weight="bold">uv |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(96.5 53.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-resolve-warm-benchmark_svg__benchmarkLabel">poetry |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(96.5 76.25)" font-family="Roboto Mono,monospace" font-size="12" class="uv-resolve-warm-benchmark_svg__benchmarkLabel">pip-compile |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(96.5 98.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-resolve-warm-benchmark_svg__benchmarkLabel">pdm |
|
|
|
|
|
</text></g></g><g class="uv-resolve-warm-benchmark_svg__mark-rect uv-resolve-warm-benchmark_svg__role-mark uv-resolve-warm-benchmark_svg__layer_0_marks" aria-roledescription="rect mark container"><path aria-label="Sum of time: 0.0134756369786; tool: uv" aria-roledescription="bar" d="M106 20.75h1.155v13H106Z" class="uv-resolve-warm-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 0.60278702674; tool: poetry" aria-roledescription="bar" d="M106 43.25h51.667v13H106Z" class="uv-resolve-warm-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 1.55616658094; tool: pip-compile" aria-roledescription="bar" d="M106 65.75h133.386v13H106Z" class="uv-resolve-warm-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 3.37404433084; tool: pdm" aria-roledescription="bar" d="M106 88.25h289.204v13H106Z" class="uv-resolve-warm-benchmark_svg__benchmarkBar"></path></g><g class="uv-resolve-warm-benchmark_svg__mark-text uv-resolve-warm-benchmark_svg__role-mark uv-resolve-warm-benchmark_svg__layer_1_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.60278702674; tool: poetry; timeFormat: 0.60s" aria-roledescription="text mark" transform="translate(163.667 53.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-resolve-warm-benchmark_svg__benchmarkLabel">0.60s |
|
|
|
|
|
</text><text aria-label="Sum of time: 1.55616658094; tool: pip-compile; timeFormat: 1.56s" aria-roledescription="text mark" transform="translate(245.386 76.25)" font-family="Roboto Mono,monospace" font-size="12" class="uv-resolve-warm-benchmark_svg__benchmarkLabel">1.56s |
|
|
|
|
|
</text><text aria-label="Sum of time: 3.37404433084; tool: pdm; timeFormat: 3.37s" aria-roledescription="text mark" transform="translate(401.204 98.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-resolve-warm-benchmark_svg__benchmarkLabel">3.37s |
|
|
|
|
|
</text></g><g class="uv-resolve-warm-benchmark_svg__mark-text uv-resolve-warm-benchmark_svg__role-mark uv-resolve-warm-benchmark_svg__layer_2_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.0134756369786; tool: uv; timeFormat: 0.01s" aria-roledescription="text mark" transform="translate(113.155 31.25)" font-family="Roboto Mono,monospace" font-size="12" font-weight="bold" class="uv-resolve-warm-benchmark_svg__benchmarkLabel">0.01s |
|
|
|
|
|
</text></g></g></svg></div><div class="w-full md:w-[484px]"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 454 139"><g class="uv-install-warm-benchmark_svg__mark-group uv-install-warm-benchmark_svg__role-frame uv-install-warm-benchmark_svg__root" aria-roledescription="group mark container" fill="none" stroke-miterlimit="10"><path class="uv-install-warm-benchmark_svg__background" aria-hidden="true" d="M84 16h300v90H84Z"></path><g class="uv-install-warm-benchmark_svg__mark-group uv-install-warm-benchmark_svg__role-axis" aria-hidden="true"><path class="uv-install-warm-benchmark_svg__background" aria-hidden="true" d="M84.5 106.5Z" pointer-events="none"></path><g class="uv-install-warm-benchmark_svg__mark-rule uv-install-warm-benchmark_svg__role-axis-grid" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M84.5 106.5v-90M204.5 106.5v-90M324.5 106.5v-90"></path></g></g><g class="uv-install-warm-benchmark_svg__mark-group uv-install-warm-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="X-axis for a linear scale with values from 0 to 5"><path class="uv-install-warm-benchmark_svg__background" aria-hidden="true" d="M84.5 106.5Z" pointer-events="none"></path><g class="uv-install-warm-benchmark_svg__mark-rule uv-install-warm-benchmark_svg__role-axis-tick" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M324.5 106.5"></path></g><g class="uv-install-warm-benchmark_svg__mark-text uv-install-warm-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="middle" transform="translate(84.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-install-warm-benchmark_svg__benchmarkLabel">0s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(204.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-install-warm-benchmark_svg__benchmarkLabel">2s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(324.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-install-warm-benchmark_svg__benchmarkLabel">4s |
|
|
|
|
|
</text></g></g><g class="uv-install-warm-benchmark_svg__mark-group uv-install-warm-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="Y-axis for a discrete scale with 4 values: uv, poetry, pdm, pip-sync"><path class="uv-install-warm-benchmark_svg__background" aria-hidden="true" d="M84.5 16.5Z" pointer-events="none"></path><g class="uv-install-warm-benchmark_svg__mark-text uv-install-warm-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="end" transform="translate(74.5 31.25)" font-family="Roboto Mono,monospace" font-size="12" class="uv-install-warm-benchmark_svg__benchmarkLabel" font-weight="bold">uv |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(74.5 53.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-install-warm-benchmark_svg__benchmarkLabel">poetry |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(74.5 76.25)" font-family="Roboto Mono,monospace" font-size="12" class="uv-install-warm-benchmark_svg__benchmarkLabel">pdm |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(74.5 98.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-install-warm-benchmark_svg__benchmarkLabel">pip-sync |
|
|
|
|
|
</text></g></g><g class="uv-install-warm-benchmark_svg__mark-rect uv-install-warm-benchmark_svg__role-mark uv-install-warm-benchmark_svg__layer_0_marks" aria-roledescription="rect mark container"><path aria-label="Sum of time: 0.0576289908; tool: uv" aria-roledescription="bar" d="M84 20.75h3.458v13H84Z" class="uv-install-warm-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 0.9872183659; tool: poetry" aria-roledescription="bar" d="M84 43.25h59.233v13H84Z" class="uv-install-warm-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 1.8969612492; tool: pdm" aria-roledescription="bar" d="M84 65.75h113.818v13H84Z" class="uv-install-warm-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 4.6313483826; tool: pip-sync" aria-roledescription="bar" d="M84 88.25h277.88v13H84Z" class="uv-install-warm-benchmark_svg__benchmarkBar"></path></g><g class="uv-install-warm-benchmark_svg__mark-text uv-install-warm-benchmark_svg__role-mark uv-install-warm-benchmark_svg__layer_1_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.9872183659; tool: poetry; timeFormat: 0.99s" aria-roledescription="text mark" transform="translate(149.233 53.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-install-warm-benchmark_svg__benchmarkLabel">0.99s |
|
|
|
|
|
</text><text aria-label="Sum of time: 1.8969612492; tool: pdm; timeFormat: 1.90s" aria-roledescription="text mark" transform="translate(203.818 76.25)" font-family="Roboto Mono,monospace" font-size="12" class="uv-install-warm-benchmark_svg__benchmarkLabel">1.90s |
|
|
|
|
|
</text><text aria-label="Sum of time: 4.6313483826; tool: pip-sync; timeFormat: 4.63s" aria-roledescription="text mark" transform="translate(367.88 98.75)" font-family="Roboto Mono,monospace" font-size="12" class="uv-install-warm-benchmark_svg__benchmarkLabel">4.63s |
|
|
|
|
|
</text></g><g class="uv-install-warm-benchmark_svg__mark-text uv-install-warm-benchmark_svg__role-mark uv-install-warm-benchmark_svg__layer_2_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.0576289908; tool: uv; timeFormat: 0.06s" aria-roledescription="text mark" transform="translate(93.458 31.25)" font-family="Roboto Mono,monospace" font-size="12" font-weight="bold" class="uv-install-warm-benchmark_svg__benchmarkLabel">0.06s |
|
|
|
|
|
</text></g></g></svg></div></div></div><div class="flex flex-row items-center"><p class="hidden text-sm md:block"><span class="opacity-75">Resolving (left) and installing (right) the <a class="cursor-pointer" target="_blank" rel="noreferrer" href="https://github.com/python-trio/trio">Trio</a> dependencies with a </span><a class="cursor-pointer select-none" aria-label="Toggle cache" tabindex="0" type="button">warm</a> <span class="opacity-75">cache, to simulate recreating a virtual environment or adding a dependency to an existing project (<a href="https://github.com/astral-sh/uv/blob/main/BENCHMARKS.md" target="_blank" rel="noreferrer">source</a>).</span></p><p class="text-sm md:hidden"><span class="opacity-75">Resolving (top) and installing (bottom) the <a class="cursor-pointer" target="_blank" rel="noreferrer" href="https://github.com/python-trio/trio">Trio</a> dependencies with a </span><a class="cursor-pointer select-none" aria-label="Toggle cache" tabindex="0" type="button">warm</a> <span class="opacity-75">cache, to simulate recreating a virtual environment or adding a dependency to an existing project (<a href="https://github.com/astral-sh/uv/blob/main/BENCHMARKS.md" target="_blank" rel="noreferrer">source</a>).</span></p></div></div> |
|
|
|
|
|
<p><a href="https://github.com/astral-sh/uv">uv</a> is designed as a drop-in replacement for <code>pip</code> and <code>pip-tools</code>, |
|
|
|
|
|
and is ready for production use today in projects built around those workflows.</p> |
|
|
|
|
|
<p>Like <a href="https://github.com/astral-sh/ruff">Ruff</a>, uv's implementation was grounded in our core |
|
|
|
|
|
product principles:</p> |
|
|
|
|
|
<ol> |
|
|
|
|
|
<li><strong>An obsessive focus on performance.</strong> In the above <a href="https://github.com/astral-sh/uv/blob/main/BENCHMARKS.md">benchmarks</a>, |
|
|
|
|
|
uv is <strong>8-10x faster</strong> than <code>pip</code> and <code>pip-tools</code> without caching, and <strong>80-115x faster</strong> |
|
|
|
|
|
when running with a warm cache (e.g., recreating a virtual environment or updating a dependency). |
|
|
|
|
|
uv uses a global module cache to avoid re-downloading and re-building dependencies, and |
|
|
|
|
|
leverages Copy-on-Write and hardlinks on supported filesystems to minimize disk space usage.</li> |
|
|
|
|
|
<li><strong>Optimized for adoption.</strong> While we have big aspirations for the future of Python packaging, |
|
|
|
|
|
uv's initial release is centered on supporting the <code>pip</code> and <code>pip-tools</code> APIs behind |
|
|
|
|
|
our <code>uv pip</code> interface, making it usable by existing projects with zero configuration. |
|
|
|
|
|
Similarly, uv can be used as "just" a resolver (<code>uv pip compile</code> to lock your |
|
|
|
|
|
dependencies), "just" a virtual environment creator (<code>uv venv</code>), "just" a package |
|
|
|
|
|
installer (<code>uv pip sync</code>), and so on. It's both unified and modular.</li> |
|
|
|
|
|
<li><strong>A simplified toolchain.</strong> uv ships as a single static binary capable of |
|
|
|
|
|
replacing <code>pip</code>, <code>pip-tools</code>, and <code>virtualenv</code>. uv has no direct Python dependency, so you |
|
|
|
|
|
can install it separately from Python itself, avoiding the need to manage <code>pip</code> installations |
|
|
|
|
|
across multiple Python versions (e.g., <code>pip</code> vs. <code>pip3</code> vs. <code>pip3.7</code>).</li> |
|
|
|
|
|
</ol> |
|
|
|
|
|
<p>While uv will evolve into a <strong>complete Python project and package manager</strong> (a <a href="https://blog.rust-lang.org/2016/05/05/cargo-pillars.html#pillars-of-cargo">"Cargo for Python"</a>), |
|
|
|
|
|
the narrower <code>pip-tools</code> scope allows us to solve the low-level problems involved in building such |
|
|
|
|
|
a tool (like package installation) while shipping something immediately useful with minimal barrier |
|
|
|
|
|
to adoption.</p> |
|
|
|
|
|
<p>You can install <a href="https://github.com/astral-sh/uv">uv</a> today via our standalone installers, |
|
|
|
|
|
or from <a href="https://pypi.org/project/uv/">PyPI</a>.</p> |
|
|
|
|
|
|
|
|
|
|
|
<p><a href="https://github.com/astral-sh/uv">uv</a> supports everything you'd expect from a modern Python |
|
|
|
|
|
packaging tool: editable installs, Git dependencies, URL dependencies, local dependencies, |
|
|
|
|
|
constraint files, source distributions, custom indexes, and more, all designed around drop-in |
|
|
|
|
|
compatibility with your existing tools.</p> |
|
|
|
|
|
<p><a href="https://github.com/astral-sh/uv">uv</a> supports <strong>Linux</strong>, <strong>Windows</strong>, and <strong>macOS</strong>, and |
|
|
|
|
|
has been tested at-scale against the public PyPI index.</p> |
|
|
|
|
|
<h3 class="hover:none group cursor-default"><span id="a-drop-in-compatible-api" class="invisible absolute mt-[-24px] block pt-[24px]"></span>A drop-in compatible API <a href="#a-drop-in-compatible-api" class="hidden group-hover:inline-block">#</a></h3> |
|
|
|
|
|
<p>This initial release centers on what we refer to as uv's <code>pip</code> API. It'll be familiar to those |
|
|
|
|
|
that have used <code>pip</code> and <code>pip-tools</code> in the past:</p> |
|
|
|
|
|
<ul> |
|
|
|
|
|
<li>Instead of <code>pip install</code>, run <code>uv pip install</code> to install Python dependencies from the command |
|
|
|
|
|
line, a requirements file, or a <code>pyproject.toml</code>.</li> |
|
|
|
|
|
<li>Instead of <code>pip-compile</code>, run <code>uv pip compile</code> to generate a locked <code>requirements.txt</code>.</li> |
|
|
|
|
|
<li>Instead of <code>pip-sync</code>, run <code>uv pip sync</code> to sync a virtual environment with a locked <code>requirements.txt</code>.</li> |
|
|
|
|
|
</ul> |
|
|
|
|
|
<p>By scoping these "lower-level" commands under <code>uv pip</code>, we retain space in the CLI for the more |
|
|
|
|
|
"opinionated" project management API we intend to ship in the future, which will look more like |
|
|
|
|
|
<a href="https://github.com/mitsuhiko/rye">Rye</a>, or <a href="https://github.com/rust-lang/cargo">Cargo</a>, or |
|
|
|
|
|
<a href="https://github.com/python-poetry/poetry">Poetry</a>. (Imagine <code>uv run</code>, <code>uv build</code>, and so on.)</p> |
|
|
|
|
|
<p>uv can also be used as a virtual environment manager via <code>uv venv</code>. It's about 80x |
|
|
|
|
|
faster than <code>python -m venv</code> and 7x faster than <code>virtualenv</code>, with no dependency on Python.</p> |
|
|
|
|
|
<div><div class="md:hidden"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 454 282"><g class="uv-venv-vertical-benchmark_svg__mark-group uv-venv-vertical-benchmark_svg__role-frame uv-venv-vertical-benchmark_svg__root" aria-roledescription="group mark container" fill="none" stroke-miterlimit="10"><path class="uv-venv-vertical-benchmark_svg__background" aria-hidden="true" d="M107 16Z"></path><g class="uv-venv-vertical-benchmark_svg__mark-group uv-venv-vertical-benchmark_svg__role-scope uv-venv-vertical-benchmark_svg__cell" aria-roledescription="group mark container"><path class="uv-venv-vertical-benchmark_svg__background" aria-hidden="true" d="M107 16h300v90H107Z"></path><g class="uv-venv-vertical-benchmark_svg__mark-group uv-venv-vertical-benchmark_svg__role-axis" aria-hidden="true"><path class="uv-venv-vertical-benchmark_svg__background" aria-hidden="true" d="M107.5 106.5Z" pointer-events="none"></path><g class="uv-venv-vertical-benchmark_svg__mark-rule uv-venv-vertical-benchmark_svg__role-axis-grid" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M107.5 106.5v-90M182.5 106.5v-90M257.5 106.5v-90M332.5 106.5v-90M407.5 106.5v-90"></path></g></g><g class="uv-venv-vertical-benchmark_svg__mark-group uv-venv-vertical-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="X-axis for a linear scale with values from 0.00 to 0.08"><path class="uv-venv-vertical-benchmark_svg__background" aria-hidden="true" d="M107.5 106.5Z" pointer-events="none"></path><g class="uv-venv-vertical-benchmark_svg__mark-rule uv-venv-vertical-benchmark_svg__role-axis-tick" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M407.5 106.5"></path></g><g class="uv-venv-vertical-benchmark_svg__mark-text uv-venv-vertical-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="middle" transform="translate(107.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">0s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(182.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">0.02s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(257.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">0.04s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(332.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">0.06s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(407.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">0.08s |
|
|
|
|
|
</text></g></g><g class="uv-venv-vertical-benchmark_svg__mark-rect uv-venv-vertical-benchmark_svg__role-mark uv-venv-vertical-benchmark_svg__child_layer_0_marks" aria-roledescription="rect mark container"><path aria-label="Sum of time: 0.0041; tool: uv" aria-roledescription="bar" d="M107 24.5h15.375v13H107Z" class="uv-venv-vertical-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 0.0744; tool: virtualenv" aria-roledescription="bar" d="M107 54.5h279v13H107Z" class="uv-venv-vertical-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 0.0241; tool: venv" aria-roledescription="bar" d="M107 84.5h90.375v13H107Z" class="uv-venv-vertical-benchmark_svg__benchmarkBar"></path></g><g class="uv-venv-vertical-benchmark_svg__mark-text uv-venv-vertical-benchmark_svg__role-mark uv-venv-vertical-benchmark_svg__child_layer_1_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.0744; tool: virtualenv; timeFormat: 74.4ms" aria-roledescription="text mark" transform="translate(392 65)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">74.4ms |
|
|
|
|
|
</text><text aria-label="Sum of time: 0.0241; tool: venv; timeFormat: 24.1ms" aria-roledescription="text mark" transform="translate(203.375 95)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">24.1ms |
|
|
|
|
|
</text></g><g class="uv-venv-vertical-benchmark_svg__mark-text uv-venv-vertical-benchmark_svg__role-mark uv-venv-vertical-benchmark_svg__child_layer_2_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.0041; tool: uv; timeFormat: 4.1ms" aria-roledescription="text mark" transform="translate(128.375 35)" font-family="Roboto Mono,monospace" font-size="12" font-weight="bold" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">4.1ms |
|
|
|
|
|
</text></g><path class="uv-venv-vertical-benchmark_svg__background" aria-hidden="true" d="M107 159h300v90H107Z"></path><g class="uv-venv-vertical-benchmark_svg__mark-group uv-venv-vertical-benchmark_svg__role-axis" aria-hidden="true"><path class="uv-venv-vertical-benchmark_svg__background" aria-hidden="true" d="M107.5 249.5Z" pointer-events="none"></path><g class="uv-venv-vertical-benchmark_svg__mark-rule uv-venv-vertical-benchmark_svg__role-axis-grid" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M107.5 249.5v-90M201.5 249.5v-90M295.5 249.5v-90M388.5 249.5v-90"></path></g></g><g class="uv-venv-vertical-benchmark_svg__mark-group uv-venv-vertical-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="X-axis for a linear scale with values from 0.0 to 1.6"><path class="uv-venv-vertical-benchmark_svg__background" aria-hidden="true" d="M107.5 249.5Z" pointer-events="none"></path><g class="uv-venv-vertical-benchmark_svg__mark-rule uv-venv-vertical-benchmark_svg__role-axis-tick" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M388.5 249.5"></path></g><g class="uv-venv-vertical-benchmark_svg__mark-text uv-venv-vertical-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="middle" transform="translate(107.5 264.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">0s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(201.25 264.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">0.5s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(295 264.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">1s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(388.75 264.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">1.5s |
|
|
|
|
|
</text></g></g><g class="uv-venv-vertical-benchmark_svg__mark-rect uv-venv-vertical-benchmark_svg__role-mark uv-venv-vertical-benchmark_svg__child_layer_0_marks" aria-roledescription="rect mark container"><path aria-label="Sum of time: 0.0182; tool: uv" aria-roledescription="bar" d="M107 167.5h3.413v13H107Z" class="uv-venv-vertical-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 0.1414; tool: virtualenv" aria-roledescription="bar" d="M107 197.5h26.512v13H107Z" class="uv-venv-vertical-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 1.54; tool: venv" aria-roledescription="bar" d="M107 227.5h288.75v13H107Z" class="uv-venv-vertical-benchmark_svg__benchmarkBar"></path></g><g class="uv-venv-vertical-benchmark_svg__mark-text uv-venv-vertical-benchmark_svg__role-mark uv-venv-vertical-benchmark_svg__child_layer_1_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.1414; tool: virtualenv; timeFormat: 141.4ms" aria-roledescription="text mark" transform="translate(139.512 208)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">141.4ms |
|
|
|
|
|
</text><text aria-label="Sum of time: 1.54; tool: venv; timeFormat: 1.54s" aria-roledescription="text mark" transform="translate(401.75 238)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">1.54s |
|
|
|
|
|
</text></g><g class="uv-venv-vertical-benchmark_svg__mark-text uv-venv-vertical-benchmark_svg__role-mark uv-venv-vertical-benchmark_svg__child_layer_2_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.0182; tool: uv; timeFormat: 18.2ms" aria-roledescription="text mark" transform="translate(116.412 178)" font-family="Roboto Mono,monospace" font-size="12" font-weight="bold" class="uv-venv-vertical-benchmark_svg__benchmarkLabel">18.2ms |
|
|
|
|
|
</text></g></g></g></svg></div><div class="hidden md:block"><div class="flex flex-row items-center justify-center text-flare"><div class="w-full md:w-[484px]"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 463 139"><g class="uv-venv-seed-benchmark_svg__mark-group uv-venv-seed-benchmark_svg__role-frame uv-venv-seed-benchmark_svg__root" aria-roledescription="group mark container" fill="none" stroke-miterlimit="10"><path class="uv-venv-seed-benchmark_svg__background" aria-hidden="true" d="M99 16h300v90H99Z"></path><g class="uv-venv-seed-benchmark_svg__mark-group uv-venv-seed-benchmark_svg__role-axis" aria-hidden="true"><path class="uv-venv-seed-benchmark_svg__background" aria-hidden="true" d="M99.5 106.5Z" pointer-events="none"></path><g class="uv-venv-seed-benchmark_svg__mark-rule uv-venv-seed-benchmark_svg__role-axis-grid" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M99.5 106.5v-90M193.5 106.5v-90M287.5 106.5v-90M380.5 106.5v-90"></path></g></g><g class="uv-venv-seed-benchmark_svg__mark-group uv-venv-seed-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="X-axis for a linear scale with values from 0.0 to 1.6"><path class="uv-venv-seed-benchmark_svg__background" aria-hidden="true" d="M99.5 106.5Z" pointer-events="none"></path><g class="uv-venv-seed-benchmark_svg__mark-rule uv-venv-seed-benchmark_svg__role-axis-tick" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M380.5 106.5"></path></g><g class="uv-venv-seed-benchmark_svg__mark-text uv-venv-seed-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="middle" transform="translate(99.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
0s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(193.25 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
0.5s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(287 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
1s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(380.75 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
1.5s |
|
|
|
|
|
</text></g></g><g class="uv-venv-seed-benchmark_svg__mark-group uv-venv-seed-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="Y-axis for a discrete scale with 3 values: uv, virtualenv, venv"><path class="uv-venv-seed-benchmark_svg__background" aria-hidden="true" d="M99.5 16.5Z" pointer-events="none"></path><g class="uv-venv-seed-benchmark_svg__mark-text uv-venv-seed-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="end" transform="translate(89.5 35)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-seed-benchmark_svg__benchmarkLabel" font-weight="bold"> |
|
|
|
|
|
uv |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(89.5 65)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
virtualenv |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(89.5 95)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
venv |
|
|
|
|
|
</text></g></g><g class="uv-venv-seed-benchmark_svg__mark-rect uv-venv-seed-benchmark_svg__role-mark uv-venv-seed-benchmark_svg__layer_0_marks" aria-roledescription="rect mark container"><path aria-label="Sum of time: 0.0182; tool: uv" aria-roledescription="bar" d="M99 24.5h3.413v13H99Z" class="uv-venv-seed-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 0.1414; tool: virtualenv" aria-roledescription="bar" d="M99 54.5h26.512v13H99Z" class="uv-venv-seed-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 1.54; tool: venv" aria-roledescription="bar" d="M99 84.5h288.75v13H99Z" class="uv-venv-seed-benchmark_svg__benchmarkBar"></path></g><g class="uv-venv-seed-benchmark_svg__mark-text uv-venv-seed-benchmark_svg__role-mark uv-venv-seed-benchmark_svg__layer_1_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.1414; tool: virtualenv; timeFormat: 141.4ms" aria-roledescription="text mark" transform="translate(131.512 65)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-seed-benchmark_svg__benchmarkLabel">141.4ms |
|
|
|
|
|
</text><text aria-label="Sum of time: 1.54; tool: venv; timeFormat: 1.54s" aria-roledescription="text mark" transform="translate(393.75 95)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-seed-benchmark_svg__benchmarkLabel">1.54s |
|
|
|
|
|
</text></g><g class="uv-venv-seed-benchmark_svg__mark-text uv-venv-seed-benchmark_svg__role-mark uv-venv-seed-benchmark_svg__layer_2_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.0182; tool: uv; timeFormat: 18.2ms" aria-roledescription="text mark" transform="translate(108.412 35)" font-family="Roboto Mono,monospace" font-size="12" font-weight="bold" class="uv-venv-seed-benchmark_svg__benchmarkLabel">18.2ms |
|
|
|
|
|
</text></g></g></svg></div><div class="w-full md:w-[484px]"><svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 463 139"><g class="uv-venv-no-seed-benchmark_svg__mark-group uv-venv-no-seed-benchmark_svg__role-frame uv-venv-no-seed-benchmark_svg__root" aria-roledescription="group mark container" fill="none" stroke-miterlimit="10"><path class="uv-venv-no-seed-benchmark_svg__background" aria-hidden="true" d="M99 16h300v90H99Z"></path><g class="uv-venv-no-seed-benchmark_svg__mark-group uv-venv-no-seed-benchmark_svg__role-axis" aria-hidden="true"><path class="uv-venv-no-seed-benchmark_svg__background" aria-hidden="true" d="M99.5 106.5Z" pointer-events="none"></path><g class="uv-venv-no-seed-benchmark_svg__mark-rule uv-venv-no-seed-benchmark_svg__role-axis-grid" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M99.5 106.5v-90M174.5 106.5v-90M249.5 106.5v-90M324.5 106.5v-90M399.5 106.5v-90"></path></g></g><g class="uv-venv-no-seed-benchmark_svg__mark-group uv-venv-no-seed-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="X-axis for a linear scale with values from 0.00 to 0.08"><path class="uv-venv-no-seed-benchmark_svg__background" aria-hidden="true" d="M99.5 106.5Z" pointer-events="none"></path><g class="uv-venv-no-seed-benchmark_svg__mark-rule uv-venv-no-seed-benchmark_svg__role-axis-tick" pointer-events="none"><path stroke="rgba(127,127,127,0.25)" d="M399.5 106.5"></path></g><g class="uv-venv-no-seed-benchmark_svg__mark-text uv-venv-no-seed-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="middle" transform="translate(99.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-no-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
0s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(174.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-no-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
0.02s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(249.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-no-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
0.04s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(324.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-no-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
0.06s |
|
|
|
|
|
</text><text text-anchor="middle" transform="translate(399.5 121.5)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-no-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
0.08s |
|
|
|
|
|
</text></g></g><g class="uv-venv-no-seed-benchmark_svg__mark-group uv-venv-no-seed-benchmark_svg__role-axis" aria-roledescription="axis" aria-label="Y-axis for a discrete scale with 3 values: uv, virtualenv, venv"><path class="uv-venv-no-seed-benchmark_svg__background" aria-hidden="true" d="M99.5 16.5Z" pointer-events="none"></path><g class="uv-venv-no-seed-benchmark_svg__mark-text uv-venv-no-seed-benchmark_svg__role-axis-label" pointer-events="none"><text text-anchor="end" transform="translate(89.5 35)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-no-seed-benchmark_svg__benchmarkLabel" font-weight="bold"> |
|
|
|
|
|
uv |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(89.5 65)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-no-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
virtualenv |
|
|
|
|
|
</text><text text-anchor="end" transform="translate(89.5 95)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-no-seed-benchmark_svg__benchmarkLabel"> |
|
|
|
|
|
venv |
|
|
|
|
|
</text></g></g><g class="uv-venv-no-seed-benchmark_svg__mark-rect uv-venv-no-seed-benchmark_svg__role-mark uv-venv-no-seed-benchmark_svg__layer_0_marks" aria-roledescription="rect mark container"><path aria-label="Sum of time: 0.0041; tool: uv" aria-roledescription="bar" d="M99 24.5h15.375v13H99Z" class="uv-venv-no-seed-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 0.0744; tool: virtualenv" aria-roledescription="bar" d="M99 54.5h279v13H99Z" class="uv-venv-no-seed-benchmark_svg__benchmarkBar"></path><path aria-label="Sum of time: 0.0241; tool: venv" aria-roledescription="bar" d="M99 84.5h90.375v13H99Z" class="uv-venv-no-seed-benchmark_svg__benchmarkBar"></path></g><g class="uv-venv-no-seed-benchmark_svg__mark-text uv-venv-no-seed-benchmark_svg__role-mark uv-venv-no-seed-benchmark_svg__layer_1_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.0744; tool: virtualenv; timeFormat: 74.4ms" aria-roledescription="text mark" transform="translate(384 65)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-no-seed-benchmark_svg__benchmarkLabel">74.4ms |
|
|
|
|
|
</text><text aria-label="Sum of time: 0.0241; tool: venv; timeFormat: 24.1ms" aria-roledescription="text mark" transform="translate(195.375 95)" font-family="Roboto Mono,monospace" font-size="12" class="uv-venv-no-seed-benchmark_svg__benchmarkLabel">24.1ms |
|
|
|
|
|
</text></g><g class="uv-venv-no-seed-benchmark_svg__mark-text uv-venv-no-seed-benchmark_svg__role-mark uv-venv-no-seed-benchmark_svg__layer_2_marks" aria-roledescription="text mark container"><text aria-label="Sum of time: 0.0041; tool: uv; timeFormat: 4.1ms" aria-roledescription="text mark" transform="translate(120.375 35)" font-family="Roboto Mono,monospace" font-size="12" font-weight="bold" class="uv-venv-no-seed-benchmark_svg__benchmarkLabel">4.1ms |
|
|
|
|
|
</text></g></g></svg></div></div></div><div class="flex flex-row items-center opacity-75"><p class="text-sm md:hidden">Creating a virtual environment, with (top) and without (bottom) seed packages like pip and setuptools (<a href="https://github.com/astral-sh/uv/blob/ea13d94c57149a8fc6ebfcef46149252e869269f/scripts/benchmarks/venv.sh" target="_blank" rel="noreferrer">source</a>).</p><p class="hidden text-sm md:block">Creating a virtual environment, with (left) and without (right) seed packages like pip and setuptools (<a href="https://github.com/astral-sh/uv/blob/ea13d94c57149a8fc6ebfcef46149252e869269f/scripts/benchmarks/venv.sh" target="_blank" rel="noreferrer">source</a>).</p></div></div> |
|
|
|
|
|
<p>uv's virtual environments are standards-compliant and work interchangeably with other tools — |
|
|
|
|
|
there's no lock-in or customization.</p> |
|
|
|
|
|
<p>Building our own package management stack from scratch also opened up room for new capabilities. |
|
|
|
|
|
For example:</p> |
|
|
|
|
|
<ul> |
|
|
|
|
|
<li><strong>uv supports alternate resolution strategies.</strong> By default, uv follows the standard |
|
|
|
|
|
Python dependency resolution strategy of preferring the latest compatible version of each package. |
|
|
|
|
|
But by passing <code>--resolution=lowest</code>, library authors can test their packages against the lowest-compatible version of their dependencies. (This is similar to Go's |
|
|
|
|
|
<a href="https://go.dev/ref/mod#minimal-version-selection">Minimal version selection</a>.)</li> |
|
|
|
|
|
<li><strong>uv allows for resolutions against arbitrary target Python versions.</strong> While <code>pip</code> |
|
|
|
|
|
and <code>pip-tools</code> always resolve against the currently-installed Python version (generating, e.g., a |
|
|
|
|
|
Python 3.12-compatible resolution when running under Python 3.12), uv accepts |
|
|
|
|
|
a <code>--python-version</code> parameter, enabling you to generate, e.g., Python 3.7-compatible resolutions |
|
|
|
|
|
even when running under newer versions.</li> |
|
|
|
|
|
<li><strong>uv allows for dependency “overrides”.</strong> uv takes pip's “constraints” concepts a step |
|
|
|
|
|
further via overrides (<code>-o overrides.txt</code>), which allow the user to guide the resolver by |
|
|
|
|
|
overriding the declared dependencies of a package. Overrides give the user an escape hatch for |
|
|
|
|
|
working around erroneous upper bounds and other incorrectly-declared dependencies.</li> |
|
|
|
|
|
</ul> |
|
|
|
|
|
<p>In its current form, uv won't be the right fit for all projects. <code>pip</code> is a mature and stable |
|
|
|
|
|
tool, with extensive support for an extremely wide range of use cases and a focus on compatibility. |
|
|
|
|
|
While uv supports a large fraction of the <code>pip</code> interface, it lacks support for some of its |
|
|
|
|
|
legacy features, like <code>.egg</code> distributions.</p> |
|
|
|
|
|
<p>Similarly, uv does not yet generate a platform-agnostic lockfile. This matches <code>pip-tools</code>, but |
|
|
|
|
|
differs from Poetry and PDM, making uv a better fit for projects built around the <code>pip</code> and |
|
|
|
|
|
<code>pip-tools</code> workflows.</p> |
|
|
|
|
|
<p>For those deep in the packaging ecosystem, uv also includes standards-compliant Rust |
|
|
|
|
|
implementations of <a href="https://peps.python.org/pep-0440/">PEP 440</a> (version identifiers), |
|
|
|
|
|
<a href="https://peps.python.org/pep-0508/">PEP 508</a> (dependency specifiers), |
|
|
|
|
|
<a href="https://peps.python.org/pep-0517/">PEP 517</a> (a build-system independent build frontend), |
|
|
|
|
|
<a href="https://peps.python.org/pep-0405/">PEP 405</a> (virtual environments), and more.</p> |
|
|
|
|
|
<h3 class="hover:none group cursor-default"><span id="a-cargo-for-python-uv-and-rye" class="invisible absolute mt-[-24px] block pt-[24px]"></span>A "Cargo for Python": uv and Rye <a href="#a-cargo-for-python-uv-and-rye" class="hidden group-hover:inline-block">#</a></h3> |
|
|
|
|
|
<p>uv represents an intermediary milestone in our pursuit of a <a href="https://blog.rust-lang.org/2016/05/05/cargo-pillars.html#pillars-of-cargo">"Cargo for Python"</a>: a unified Python |
|
|
|
|
|
package and project manager that is extremely fast, reliable, and easy to use.</p> |
|
|
|
|
|
<p>Think: a single binary that bootstraps your Python installation and gives you everything you need to |
|
|
|
|
|
be productive with Python, bundling not only <code>pip</code>, <code>pip-tools</code>, and <code>virtualenv</code>, but also <code>pipx</code>, |
|
|
|
|
|
<code>tox</code>, <code>poetry</code>, <code>pyenv</code>, <code>ruff</code>, and more.</p> |
|
|
|
|
|
<p>Python tooling can be a low-confidence experience: it's a significant amount of work to stand up a |
|
|
|
|
|
new or existing project, and commands fail in confusing ways. In contrast, when working in the Rust |
|
|
|
|
|
ecosystem, you trust the tools to succeed. The Astral toolchain is about bringing Python from a |
|
|
|
|
|
low-confidence to a high-confidence experience.</p> |
|
|
|
|
|
<p>This vision for Python packaging is not far off from that put forward by <a href="https://github.com/mitsuhiko/rye">Rye</a>, |
|
|
|
|
|
an experimental project and package management tool from <a href="https://github.com/mitsuhiko">Armin Ronacher</a>.</p> |
|
|
|
|
|
<p>In talking with Armin, it was clear that our visions were closely aligned, but that fulfilling |
|
|
|
|
|
them would require a significant investment in foundational tooling. For example: building such a |
|
|
|
|
|
tool requires an extremely fast, end-to-end integrated, cross-platform resolver and installer. <strong>In |
|
|
|
|
|
uv, we've built that foundational tooling.</strong></p> |
|
|
|
|
|
<p>We saw this as a rare opportunity to team up, and to avoid fragmenting the Python ecosystem. |
|
|
|
|
|
<strong>As such, in collaboration with Armin, we're excited to be taking over <a href="https://github.com/mitsuhiko/rye">Rye</a>.</strong> |
|
|
|
|
|
Our goal is to evolve uv into a production-ready <a href="https://blog.rust-lang.org/2016/05/05/cargo-pillars.html#pillars-of-cargo">"Cargo for Python"</a>, and to provide a smooth |
|
|
|
|
|
migration path from Rye to uv when the time is right.</p> |
|
|
|
|
|
<p>Until then, we'll be maintaining Rye, migrating it to use uv under-the-hood, and, more |
|
|
|
|
|
generally, treating it as an experimental testbed for the end-user experience we're building |
|
|
|
|
|
towards.</p> |
|
|
|
|
|
<p>While merging projects comes with its own challenges, we're committed to building a single, unified |
|
|
|
|
|
tool under the Astral banner, and to supporting existing Rye users as we evolve uv into a |
|
|
|
|
|
suitable and comprehensive successor project.</p> |
|
|
|
|
|
<h3 class="hover:none group cursor-default"><span id="our-roadmap" class="invisible absolute mt-[-24px] block pt-[24px]"></span>Our Roadmap <a href="#our-roadmap" class="hidden group-hover:inline-block">#</a></h3> |
|
|
|
|
|
<p>Following this release, our first priority is to support users as they consider <a href="https://github.com/astral-sh/uv">uv</a>, |
|
|
|
|
|
with a focus on improving compatibility, performance, and stability across platforms.</p> |
|
|
|
|
|
<p>From there, we'll look towards expanding uv into a complete Python project and package manager: |
|
|
|
|
|
a single binary that gives you everything you need to be productive with Python.</p> |
|
|
|
|
|
<p>We have an ambitious roadmap for uv. But even in its current form, I think it will |
|
|
|
|
|
feel like a very different experience for Python. I hope you'll give it a try.</p> |
|
|
|
|
|
<h3 class="hover:none group cursor-default"><span id="acknowledgements" class="invisible absolute mt-[-24px] block pt-[24px]"></span>Acknowledgements <a href="#acknowledgements" class="hidden group-hover:inline-block">#</a></h3> |
|
|
|
|
|
<p>Finally, we'd like to thank all those that contributed directly or indirectly to the development of |
|
|
|
|
|
uv. Foremost among them are <a href="https://github.com/Eh2406">Jacob Finkelman</a> |
|
|
|
|
|
and <a href="https://github.com/mpizenberg">Matthieu Pizenberg</a>, the maintainers |
|
|
|
|
|
of <a href="https://github.com/pubgrub-rs/pubgrub">pubgrub-rs</a>. uv uses PubGrub as its underlying |
|
|
|
|
|
version solver, and we're grateful to Jacob and Matthieu for the work they put into PubGrub in the |
|
|
|
|
|
past, and for the way they've engaged with us as collaborators throughout the project.</p> |
|
|
|
|
|
<p>We'd also like to thank those projects in the packaging space that've inspired us, |
|
|
|
|
|
especially <a href="https://github.com/rust-lang/cargo">Cargo</a>, along with <a href="https://github.com/oven-sh/bun">Bun</a>, <a href="https://github.com/orogene/orogene">Orogene</a>, |
|
|
|
|
|
and <a href="https://github.com/pnpm/pnpm">pnpm</a> from the JavaScript ecosystem, |
|
|
|
|
|
and <a href="https://github.com/njsmith/posy">Posy</a>, <a href="https://github.com/konstin/monotrail-resolve">Monotrail</a>, |
|
|
|
|
|
and <a href="https://github.com/mitsuhiko/rye">Rye</a> from the Python ecosystem. In particular, thanks |
|
|
|
|
|
to <a href="https://github.com/mitsuhiko">Armin Ronacher</a> for collaborating with us on this effort.</p> |
|
|
|
|
|
<p>Finally, we'd like to thank the maintainers of <a href="https://github.com/pypa/pip">pip</a> and the members of |
|
|
|
|
|
the PyPA more broadly for all the work they do to make Python packaging possible.</p> |
|
|
|
|
|
</article> |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<hr> |
|
|
|
|
|
|
|
|
|
|
|
<footer> |
|
|
|
|
|
<p> |
|
|
|
|
|
<a href="/david/" title="Aller à l’accueil"><svg class="icon icon-home"> |
|
|
|
|
|
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-home"></use> |
|
|
|
|
|
</svg> Accueil</a> • |
|
|
|
|
|
<a href="/david/log/" title="Accès au flux RSS"><svg class="icon icon-rss2"> |
|
|
|
|
|
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-rss2"></use> |
|
|
|
|
|
</svg> Suivre</a> • |
|
|
|
|
|
<a href="http://larlet.com" title="Go to my English profile" data-instant><svg class="icon icon-user-tie"> |
|
|
|
|
|
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-user-tie"></use> |
|
|
|
|
|
</svg> Pro</a> • |
|
|
|
|
|
<a href="mailto:david%40larlet.fr" title="Envoyer un courriel"><svg class="icon icon-mail"> |
|
|
|
|
|
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-mail"></use> |
|
|
|
|
|
</svg> Email</a> • |
|
|
|
|
|
<abbr class="nowrap" title="Hébergeur : Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33184162340"><svg class="icon icon-hammer2"> |
|
|
|
|
|
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-hammer2"></use> |
|
|
|
|
|
</svg> Légal</abbr> |
|
|
|
|
|
</p> |
|
|
|
|
|
<template id="theme-selector"> |
|
|
|
|
|
<form> |
|
|
|
|
|
<fieldset> |
|
|
|
|
|
<legend><svg class="icon icon-brightness-contrast"> |
|
|
|
|
|
<use xlink:href="/static/david/icons2/symbol-defs-2021-12.svg#icon-brightness-contrast"></use> |
|
|
|
|
|
</svg> Thème</legend> |
|
|
|
|
|
<label> |
|
|
|
|
|
<input type="radio" value="auto" name="chosen-color-scheme" checked> Auto |
|
|
|
|
|
</label> |
|
|
|
|
|
<label> |
|
|
|
|
|
<input type="radio" value="dark" name="chosen-color-scheme"> Foncé |
|
|
|
|
|
</label> |
|
|
|
|
|
<label> |
|
|
|
|
|
<input type="radio" value="light" name="chosen-color-scheme"> Clair |
|
|
|
|
|
</label> |
|
|
|
|
|
</fieldset> |
|
|
|
|
|
</form> |
|
|
|
|
|
</template> |
|
|
|
|
|
</footer> |
|
|
|
|
|
<script src="/static/david/js/instantpage-5.1.0.min.js" type="module"></script> |
|
|
|
|
|
<script> |
|
|
|
|
|
function loadThemeForm(templateName) { |
|
|
|
|
|
const themeSelectorTemplate = document.querySelector(templateName) |
|
|
|
|
|
const form = themeSelectorTemplate.content.firstElementChild |
|
|
|
|
|
themeSelectorTemplate.replaceWith(form) |
|
|
|
|
|
|
|
|
|
|
|
form.addEventListener('change', (e) => { |
|
|
|
|
|
const chosenColorScheme = e.target.value |
|
|
|
|
|
localStorage.setItem('theme', chosenColorScheme) |
|
|
|
|
|
toggleTheme(chosenColorScheme) |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
const selectedTheme = localStorage.getItem('theme') |
|
|
|
|
|
if (selectedTheme && selectedTheme !== 'undefined') { |
|
|
|
|
|
form.querySelector(`[value="${selectedTheme}"]`).checked = true |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
const prefersColorSchemeDark = '(prefers-color-scheme: dark)' |
|
|
|
|
|
window.addEventListener('load', () => { |
|
|
|
|
|
let hasDarkRules = false |
|
|
|
|
|
for (const styleSheet of Array.from(document.styleSheets)) { |
|
|
|
|
|
let mediaRules = [] |
|
|
|
|
|
for (const cssRule of styleSheet.cssRules) { |
|
|
|
|
|
if (cssRule.type !== CSSRule.MEDIA_RULE) { |
|
|
|
|
|
continue |
|
|
|
|
|
} |
|
|
|
|
|
// WARNING: Safari does not have/supports `conditionText`. |
|
|
|
|
|
if (cssRule.conditionText) { |
|
|
|
|
|
if (cssRule.conditionText !== prefersColorSchemeDark) { |
|
|
|
|
|
continue |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
if (cssRule.cssText.startsWith(prefersColorSchemeDark)) { |
|
|
|
|
|
continue |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
mediaRules = mediaRules.concat(Array.from(cssRule.cssRules)) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// WARNING: do not try to insert a Rule to a styleSheet you are |
|
|
|
|
|
// currently iterating on, otherwise the browser will be stuck |
|
|
|
|
|
// in a infinite loop… |
|
|
|
|
|
for (const mediaRule of mediaRules) { |
|
|
|
|
|
styleSheet.insertRule(mediaRule.cssText) |
|
|
|
|
|
hasDarkRules = true |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (hasDarkRules) { |
|
|
|
|
|
loadThemeForm('#theme-selector') |
|
|
|
|
|
} |
|
|
|
|
|
}) |
|
|
|
|
|
</script> |
|
|
|
|
|
</body> |
|
|
|
|
|
</html> |