mirror of
https://github.com/astral-sh/uv.git
synced 2025-08-03 10:33:49 +00:00
Add support for Python version requests in uv python list
(#12375)
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / lint (push) Waiting to run
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | macos (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / check system | python on macos x86-64 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / build binary | linux libc (push) Blocked by required conditions
CI / build binary | linux musl (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / build binary | windows x86_64 (push) Blocked by required conditions
CI / build binary | windows aarch64 (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / ecosystem test | pydantic/pydantic-core (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / smoke test | linux (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
CI / smoke test | macos (push) Blocked by required conditions
CI / smoke test | windows x86_64 (push) Blocked by required conditions
CI / smoke test | windows aarch64 (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | deadsnakes python3.9 on ubuntu (push) Blocked by required conditions
CI / integration test | free-threaded on linux (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / integration test | uv_build (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | python on opensuse (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86-64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows x86-64 (push) Blocked by required conditions
CI / check system | x86-64 python3.13 on windows aarch64 (push) Blocked by required conditions
CI / check system | windows registry (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.8 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.11 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.11 on windows x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on windows x86-64 (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows x86-64 (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
Some checks are pending
CI / Determine changes (push) Waiting to run
CI / lint (push) Waiting to run
CI / cargo clippy | ubuntu (push) Blocked by required conditions
CI / cargo clippy | windows (push) Blocked by required conditions
CI / cargo dev generate-all (push) Blocked by required conditions
CI / cargo shear (push) Waiting to run
CI / check windows trampoline | i686 (push) Blocked by required conditions
CI / cargo test | ubuntu (push) Blocked by required conditions
CI / cargo test | macos (push) Blocked by required conditions
CI / cargo test | windows (push) Blocked by required conditions
CI / check windows trampoline | aarch64 (push) Blocked by required conditions
CI / check system | python on macos x86-64 (push) Blocked by required conditions
CI / check windows trampoline | x86_64 (push) Blocked by required conditions
CI / test windows trampoline | i686 (push) Blocked by required conditions
CI / test windows trampoline | x86_64 (push) Blocked by required conditions
CI / typos (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / build binary | linux libc (push) Blocked by required conditions
CI / build binary | linux musl (push) Blocked by required conditions
CI / build binary | macos aarch64 (push) Blocked by required conditions
CI / build binary | macos x86_64 (push) Blocked by required conditions
CI / build binary | windows x86_64 (push) Blocked by required conditions
CI / build binary | windows aarch64 (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / build binary | freebsd (push) Blocked by required conditions
CI / ecosystem test | pydantic/pydantic-core (push) Blocked by required conditions
CI / ecosystem test | prefecthq/prefect (push) Blocked by required conditions
CI / ecosystem test | pallets/flask (push) Blocked by required conditions
CI / smoke test | linux (push) Blocked by required conditions
CI / check system | alpine (push) Blocked by required conditions
CI / smoke test | macos (push) Blocked by required conditions
CI / smoke test | windows x86_64 (push) Blocked by required conditions
CI / smoke test | windows aarch64 (push) Blocked by required conditions
CI / integration test | conda on ubuntu (push) Blocked by required conditions
CI / integration test | deadsnakes python3.9 on ubuntu (push) Blocked by required conditions
CI / integration test | free-threaded on linux (push) Blocked by required conditions
CI / integration test | free-threaded on windows (push) Blocked by required conditions
CI / integration test | pypy on ubuntu (push) Blocked by required conditions
CI / integration test | pypy on windows (push) Blocked by required conditions
CI / integration test | graalpy on ubuntu (push) Blocked by required conditions
CI / integration test | graalpy on windows (push) Blocked by required conditions
CI / integration test | github actions (push) Blocked by required conditions
CI / integration test | determine publish changes (push) Blocked by required conditions
CI / integration test | uv publish (push) Blocked by required conditions
CI / integration test | uv_build (push) Blocked by required conditions
CI / check cache | ubuntu (push) Blocked by required conditions
CI / check cache | macos aarch64 (push) Blocked by required conditions
CI / check system | python on debian (push) Blocked by required conditions
CI / check system | python on fedora (push) Blocked by required conditions
CI / check system | python on ubuntu (push) Blocked by required conditions
CI / check system | python on opensuse (push) Blocked by required conditions
CI / check system | python on rocky linux 8 (push) Blocked by required conditions
CI / check system | python on rocky linux 9 (push) Blocked by required conditions
CI / check system | pypy on ubuntu (push) Blocked by required conditions
CI / check system | pyston (push) Blocked by required conditions
CI / check system | python on macos aarch64 (push) Blocked by required conditions
CI / check system | homebrew python on macos aarch64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86-64 (push) Blocked by required conditions
CI / check system | python3.10 on windows x86 (push) Blocked by required conditions
CI / check system | python3.13 on windows x86-64 (push) Blocked by required conditions
CI / check system | x86-64 python3.13 on windows aarch64 (push) Blocked by required conditions
CI / check system | windows registry (push) Blocked by required conditions
CI / check system | python3.12 via chocolatey (push) Blocked by required conditions
CI / check system | python3.9 via pyenv (push) Blocked by required conditions
CI / check system | python3.13 (push) Blocked by required conditions
CI / check system | conda3.11 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.8 on macos aarch64 (push) Blocked by required conditions
CI / check system | conda3.11 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on linux x86-64 (push) Blocked by required conditions
CI / check system | conda3.11 on windows x86-64 (push) Blocked by required conditions
CI / check system | conda3.8 on windows x86-64 (push) Blocked by required conditions
CI / check system | amazonlinux (push) Blocked by required conditions
CI / check system | embedded python3.10 on windows x86-64 (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
Allows `uv python list <request>` to filter the installed list. I often want this and it's not hard to add. I tested the remote download filtering locally (#12381 is needed for snapshot tests) ``` ❯ cargo run -q -- python list --all-versions 3.13 cpython-3.13.2-macos-aarch64-none <download available> cpython-3.13.1-macos-aarch64-none /opt/homebrew/opt/python@3.13/bin/python3.13 -> ../Frameworks/Python.framework/Versions/3.13/bin/python3.13 cpython-3.13.1-macos-aarch64-none <download available> cpython-3.13.0-macos-aarch64-none /Users/zb/.local/share/uv/python/cpython-3.13.0-macos-aarch64-none/bin/python3.13 ❯ cargo run -q -- python list --all-versions 3.13 --only-installed cpython-3.13.1-macos-aarch64-none /opt/homebrew/opt/python@3.13/bin/python3.13 -> ../Frameworks/Python.framework/Versions/3.13/bin/python3.13 cpython-3.13.0-macos-aarch64-none /Users/zb/.local/share/uv/python/cpython-3.13.0-macos-aarch64-none/bin/python3.13 ```
This commit is contained in:
parent
cdd6de555b
commit
ec499807f8
7 changed files with 199 additions and 15 deletions
|
@ -4577,6 +4577,11 @@ pub enum PythonCommand {
|
|||
#[derive(Args)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct PythonListArgs {
|
||||
/// A Python request to filter by.
|
||||
///
|
||||
/// See `uv help python` to view supported request formats.
|
||||
pub request: Option<String>,
|
||||
|
||||
/// List all Python versions, including old patch versions.
|
||||
///
|
||||
/// By default, only the latest patch version is shown for each minor version.
|
||||
|
|
|
@ -52,6 +52,7 @@ struct PrintData {
|
|||
/// List available Python installations.
|
||||
#[allow(clippy::too_many_arguments, clippy::fn_params_excessive_bools)]
|
||||
pub(crate) async fn list(
|
||||
request: Option<String>,
|
||||
kinds: PythonListKinds,
|
||||
all_versions: bool,
|
||||
all_platforms: bool,
|
||||
|
@ -63,23 +64,31 @@ pub(crate) async fn list(
|
|||
cache: &Cache,
|
||||
printer: Printer,
|
||||
) -> Result<ExitStatus> {
|
||||
let request = request.as_deref().map(PythonRequest::parse);
|
||||
let base_download_request = if python_preference == PythonPreference::OnlySystem {
|
||||
None
|
||||
} else {
|
||||
// If the user request cannot be mapped to a download request, we won't show any downloads
|
||||
PythonDownloadRequest::from_request(request.as_ref().unwrap_or(&PythonRequest::Any))
|
||||
};
|
||||
|
||||
let mut output = BTreeSet::new();
|
||||
if python_preference != PythonPreference::OnlySystem {
|
||||
if let Some(base_download_request) = base_download_request {
|
||||
let download_request = match kinds {
|
||||
PythonListKinds::Installed => None,
|
||||
PythonListKinds::Downloads => Some(if all_platforms {
|
||||
PythonDownloadRequest::default()
|
||||
base_download_request
|
||||
} else {
|
||||
PythonDownloadRequest::from_env()?
|
||||
base_download_request.fill()?
|
||||
}),
|
||||
PythonListKinds::Default => {
|
||||
if python_downloads.is_automatic() {
|
||||
Some(if all_platforms {
|
||||
PythonDownloadRequest::default()
|
||||
base_download_request
|
||||
} else if all_arches {
|
||||
PythonDownloadRequest::from_env()?.with_any_arch()
|
||||
base_download_request.fill()?.with_any_arch()
|
||||
} else {
|
||||
PythonDownloadRequest::from_env()?
|
||||
base_download_request.fill()?
|
||||
})
|
||||
} else {
|
||||
// If fetching is not automatic, then don't show downloads as available by default
|
||||
|
@ -109,7 +118,7 @@ pub(crate) async fn list(
|
|||
match kinds {
|
||||
PythonListKinds::Installed | PythonListKinds::Default => {
|
||||
Some(find_python_installations(
|
||||
&PythonRequest::Any,
|
||||
request.as_ref().unwrap_or(&PythonRequest::Any),
|
||||
EnvironmentPreference::OnlySystem,
|
||||
python_preference,
|
||||
cache,
|
||||
|
|
|
@ -1272,6 +1272,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
let cache = cache.init()?;
|
||||
|
||||
commands::python_list(
|
||||
args.request,
|
||||
args.kinds,
|
||||
args.all_versions,
|
||||
args.all_platforms,
|
||||
|
|
|
@ -826,6 +826,7 @@ pub(crate) enum PythonListKinds {
|
|||
#[allow(clippy::struct_excessive_bools)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct PythonListSettings {
|
||||
pub(crate) request: Option<String>,
|
||||
pub(crate) kinds: PythonListKinds,
|
||||
pub(crate) all_platforms: bool,
|
||||
pub(crate) all_arches: bool,
|
||||
|
@ -839,6 +840,7 @@ impl PythonListSettings {
|
|||
#[allow(clippy::needless_pass_by_value)]
|
||||
pub(crate) fn resolve(args: PythonListArgs, _filesystem: Option<FilesystemOptions>) -> Self {
|
||||
let PythonListArgs {
|
||||
request,
|
||||
all_versions,
|
||||
all_platforms,
|
||||
all_arches,
|
||||
|
@ -857,6 +859,7 @@ impl PythonListSettings {
|
|||
};
|
||||
|
||||
Self {
|
||||
request,
|
||||
kinds,
|
||||
all_platforms,
|
||||
all_arches,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use uv_python::platform::{Arch, Os};
|
||||
use uv_static::EnvVars;
|
||||
|
||||
use crate::common::{uv_snapshot, TestContext};
|
||||
|
@ -27,6 +28,79 @@ fn python_list() {
|
|||
----- stderr -----
|
||||
");
|
||||
|
||||
// Request Python 3.12
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("3.12"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
cpython-3.12.[X]-[PLATFORM] [PYTHON-3.12]
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
|
||||
// Request Python 3.11
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("3.11"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
cpython-3.11.[X]-[PLATFORM] [PYTHON-3.11]
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
|
||||
// Request CPython
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("cpython"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
cpython-3.12.[X]-[PLATFORM] [PYTHON-3.12]
|
||||
cpython-3.11.[X]-[PLATFORM] [PYTHON-3.11]
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
|
||||
// Request CPython 3.12
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("cpython@3.12"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
cpython-3.12.[X]-[PLATFORM] [PYTHON-3.12]
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
|
||||
// Request CPython 3.12 via partial key syntax
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("cpython-3.12"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
cpython-3.12.[X]-[PLATFORM] [PYTHON-3.12]
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
|
||||
// Request CPython 3.12 for the current platform
|
||||
let os = Os::from_env();
|
||||
let arch = Arch::from_env();
|
||||
|
||||
uv_snapshot!(context.filters(), context.python_list().arg(format!("cpython-3.12-{os}-{arch}")), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
cpython-3.12.[X]-[PLATFORM] [PYTHON-3.12]
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
|
||||
// Request PyPy (which should be missing)
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("pypy"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
|
||||
// Swap the order of the Python versions
|
||||
context.python_versions.reverse();
|
||||
|
||||
|
@ -42,16 +116,12 @@ fn python_list() {
|
|||
|
||||
// Request Python 3.11
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("3.11"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
cpython-3.11.[X]-[PLATFORM] [PYTHON-3.11]
|
||||
|
||||
----- stderr -----
|
||||
error: unexpected argument '3.11' found
|
||||
|
||||
Usage: uv python list [OPTIONS]
|
||||
|
||||
For more information, try '--help'.
|
||||
");
|
||||
}
|
||||
|
||||
|
@ -134,3 +204,79 @@ fn python_list_venv() {
|
|||
----- stderr -----
|
||||
");
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn python_list_unsupported_version() {
|
||||
let context: TestContext = TestContext::new_with_versions(&["3.12"])
|
||||
.with_filtered_python_symlinks()
|
||||
.with_filtered_python_keys();
|
||||
|
||||
// Request a low version
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("3.6"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: Invalid version request: Python <3.7 is not supported but 3.6 was requested.
|
||||
");
|
||||
|
||||
// Request a low version with a patch
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("3.6.9"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: Invalid version request: Python <3.7 is not supported but 3.6.9 was requested.
|
||||
");
|
||||
|
||||
// Request a really low version
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("2.6"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: Invalid version request: Python <3.7 is not supported but 2.6 was requested.
|
||||
");
|
||||
|
||||
// Request a really low version with a patch
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("2.6.8"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: Invalid version request: Python <3.7 is not supported but 2.6.8 was requested.
|
||||
");
|
||||
|
||||
// Request a future version
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("4.2"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
|
||||
// Request a low version with a range
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("<3.0"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
|
||||
// Request free-threaded Python on unsupported version
|
||||
uv_snapshot!(context.filters(), context.python_list().arg("3.12t"), @r"
|
||||
success: false
|
||||
exit_code: 2
|
||||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: Invalid version request: Python <3.13 does not support free-threading but 3.12t was requested.
|
||||
");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue