From d19d0e26aa35daefc4ffdf6afec261a053cd615f Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sun, 24 Aug 2025 14:14:42 -0400 Subject: [PATCH] Add `--python-platform` to `uv pip check` (#15486) ## Summary I want this to facilitate some testing for https://github.com/astral-sh/uv/issues/15035. --- crates/uv-cli/src/lib.rs | 21 +++++++++++++ crates/uv/src/commands/pip/check.rs | 11 +++++-- crates/uv/src/lib.rs | 2 ++ crates/uv/src/settings.rs | 6 ++++ crates/uv/tests/it/pip_check.rs | 33 +++++++++++++++++++ docs/reference/cli.md | 49 ++++++++++++++++++++++++++++- 6 files changed, 118 insertions(+), 4 deletions(-) diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs index c5c0bd3cb..3c5a0ac5a 100644 --- a/crates/uv-cli/src/lib.rs +++ b/crates/uv-cli/src/lib.rs @@ -2373,6 +2373,27 @@ pub struct PipCheckArgs { #[arg(long, overrides_with("system"), hide = true)] pub no_system: bool, + + /// The Python version against which packages should be checked. + /// + /// By default, the installed packages are checked against the version of the current + /// interpreter. + #[arg(long)] + pub python_version: Option, + + /// The platform for which packages should be checked. + /// + /// By default, the installed packages are checked against the platform of the current + /// interpreter. + /// + /// Represented as a "target triple", a string that describes the target platform in terms of + /// its CPU, vendor, and operating system name, like `x86_64-unknown-linux-gnu` or + /// `aarch64-apple-darwin`. + /// + /// When targeting macOS (Darwin), the default minimum version is `12.0`. Use + /// `MACOSX_DEPLOYMENT_TARGET` to specify a different minimum version, e.g., `13.0`. + #[arg(long)] + pub python_platform: Option, } #[derive(Args)] diff --git a/crates/uv/src/commands/pip/check.rs b/crates/uv/src/commands/pip/check.rs index aa19af3b1..17e56c610 100644 --- a/crates/uv/src/commands/pip/check.rs +++ b/crates/uv/src/commands/pip/check.rs @@ -5,13 +5,16 @@ use anyhow::Result; use owo_colors::OwoColorize; use uv_cache::Cache; +use uv_configuration::TargetTriple; use uv_distribution_types::{Diagnostic, InstalledDist}; use uv_installer::{SitePackages, SitePackagesDiagnostic}; use uv_preview::Preview; -use uv_python::PythonPreference; -use uv_python::{EnvironmentPreference, PythonEnvironment, PythonRequest}; +use uv_python::{ + EnvironmentPreference, PythonEnvironment, PythonPreference, PythonRequest, PythonVersion, +}; use crate::commands::pip::operations::report_target_environment; +use crate::commands::pip::resolution_markers; use crate::commands::{ExitStatus, elapsed}; use crate::printer::Printer; @@ -19,6 +22,8 @@ use crate::printer::Printer; pub(crate) fn pip_check( python: Option<&str>, system: bool, + python_version: Option<&PythonVersion>, + python_platform: Option<&TargetTriple>, cache: &Cache, printer: Printer, preview: Preview, @@ -53,7 +58,7 @@ pub(crate) fn pip_check( )?; // Determine the markers to use for resolution. - let markers = environment.interpreter().resolver_marker_environment(); + let markers = resolution_markers(python_version, python_platform, environment.interpreter()); // Run the diagnostics. let diagnostics: Vec = diff --git a/crates/uv/src/lib.rs b/crates/uv/src/lib.rs index ae2fc0e92..84c727fd0 100644 --- a/crates/uv/src/lib.rs +++ b/crates/uv/src/lib.rs @@ -916,6 +916,8 @@ async fn run(mut cli: Cli) -> Result { commands::pip_check( args.settings.python.as_deref(), args.settings.system, + args.python_version.as_ref(), + args.python_platform.as_ref(), &cache, printer, globals.preview, diff --git a/crates/uv/src/settings.rs b/crates/uv/src/settings.rs index 8cfe44013..93935b8a3 100644 --- a/crates/uv/src/settings.rs +++ b/crates/uv/src/settings.rs @@ -2589,6 +2589,8 @@ impl PipTreeSettings { #[derive(Debug, Clone)] pub(crate) struct PipCheckSettings { pub(crate) settings: PipSettings, + pub(crate) python_version: Option, + pub(crate) python_platform: Option, } impl PipCheckSettings { @@ -2598,6 +2600,8 @@ impl PipCheckSettings { python, system, no_system, + python_version, + python_platform, } = args; Self { @@ -2609,6 +2613,8 @@ impl PipCheckSettings { }, filesystem, ), + python_version, + python_platform, } } } diff --git a/crates/uv/tests/it/pip_check.rs b/crates/uv/tests/it/pip_check.rs index 891b1f050..c23e9031a 100644 --- a/crates/uv/tests/it/pip_check.rs +++ b/crates/uv/tests/it/pip_check.rs @@ -187,3 +187,36 @@ fn check_multiple_incompatible_packages() -> Result<()> { Ok(()) } + +#[test] +fn check_python_version() { + let context = TestContext::new("3.12"); + + uv_snapshot!(context + .pip_install() + .arg("urllib3") + .arg("--strict"), @r" + success: true + exit_code: 0 + ----- stdout ----- + + ----- stderr ----- + Resolved 1 package in [TIME] + Prepared 1 package in [TIME] + Installed 1 package in [TIME] + + urllib3==2.2.1 + " + ); + + uv_snapshot!(context.filters(), context.pip_check().arg("--python-version").arg("3.7"), @r" + success: false + exit_code: 1 + ----- stdout ----- + + ----- stderr ----- + Checked 1 package in [TIME] + Found 1 incompatibility + The package `urllib3` requires Python >=3.8, but `3.12.[X]` is installed + " + ); +} diff --git a/docs/reference/cli.md b/docs/reference/cli.md index a4c3d33be..1a1d597bc 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -4823,7 +4823,54 @@ uv pip check [OPTIONS]

By default, uv checks packages in a virtual environment but will check packages in a system Python environment if no virtual environment is found.

See uv python for details on Python discovery and supported request formats.

-

May also be set with the UV_PYTHON environment variable.

--quiet, -q

Use quiet output.

+

May also be set with the UV_PYTHON environment variable.

--python-platform python-platform

The platform for which packages should be checked.

+

By default, the installed packages are checked against the platform of the current interpreter.

+

Represented as a "target triple", a string that describes the target platform in terms of its CPU, vendor, and operating system name, like x86_64-unknown-linux-gnu or aarch64-apple-darwin.

+

When targeting macOS (Darwin), the default minimum version is 12.0. Use MACOSX_DEPLOYMENT_TARGET to specify a different minimum version, e.g., 13.0.

+

Possible values:

+
    +
  • windows: An alias for x86_64-pc-windows-msvc, the default target for Windows
  • +
  • linux: An alias for x86_64-unknown-linux-gnu, the default target for Linux
  • +
  • macos: An alias for aarch64-apple-darwin, the default target for macOS
  • +
  • x86_64-pc-windows-msvc: A 64-bit x86 Windows target
  • +
  • aarch64-pc-windows-msvc: An ARM64 Windows target
  • +
  • i686-pc-windows-msvc: A 32-bit x86 Windows target
  • +
  • x86_64-unknown-linux-gnu: An x86 Linux target. Equivalent to x86_64-manylinux_2_28
  • +
  • aarch64-apple-darwin: An ARM-based macOS target, as seen on Apple Silicon devices
  • +
  • x86_64-apple-darwin: An x86 macOS target
  • +
  • aarch64-unknown-linux-gnu: An ARM64 Linux target. Equivalent to aarch64-manylinux_2_28
  • +
  • aarch64-unknown-linux-musl: An ARM64 Linux target
  • +
  • x86_64-unknown-linux-musl: An x86_64 Linux target
  • +
  • x86_64-manylinux2014: An x86_64 target for the manylinux2014 platform. Equivalent to x86_64-manylinux_2_17
  • +
  • x86_64-manylinux_2_17: An x86_64 target for the manylinux_2_17 platform
  • +
  • x86_64-manylinux_2_28: An x86_64 target for the manylinux_2_28 platform
  • +
  • x86_64-manylinux_2_31: An x86_64 target for the manylinux_2_31 platform
  • +
  • x86_64-manylinux_2_32: An x86_64 target for the manylinux_2_32 platform
  • +
  • x86_64-manylinux_2_33: An x86_64 target for the manylinux_2_33 platform
  • +
  • x86_64-manylinux_2_34: An x86_64 target for the manylinux_2_34 platform
  • +
  • x86_64-manylinux_2_35: An x86_64 target for the manylinux_2_35 platform
  • +
  • x86_64-manylinux_2_36: An x86_64 target for the manylinux_2_36 platform
  • +
  • x86_64-manylinux_2_37: An x86_64 target for the manylinux_2_37 platform
  • +
  • x86_64-manylinux_2_38: An x86_64 target for the manylinux_2_38 platform
  • +
  • x86_64-manylinux_2_39: An x86_64 target for the manylinux_2_39 platform
  • +
  • x86_64-manylinux_2_40: An x86_64 target for the manylinux_2_40 platform
  • +
  • aarch64-manylinux2014: An ARM64 target for the manylinux2014 platform. Equivalent to aarch64-manylinux_2_17
  • +
  • aarch64-manylinux_2_17: An ARM64 target for the manylinux_2_17 platform
  • +
  • aarch64-manylinux_2_28: An ARM64 target for the manylinux_2_28 platform
  • +
  • aarch64-manylinux_2_31: An ARM64 target for the manylinux_2_31 platform
  • +
  • aarch64-manylinux_2_32: An ARM64 target for the manylinux_2_32 platform
  • +
  • aarch64-manylinux_2_33: An ARM64 target for the manylinux_2_33 platform
  • +
  • aarch64-manylinux_2_34: An ARM64 target for the manylinux_2_34 platform
  • +
  • aarch64-manylinux_2_35: An ARM64 target for the manylinux_2_35 platform
  • +
  • aarch64-manylinux_2_36: An ARM64 target for the manylinux_2_36 platform
  • +
  • aarch64-manylinux_2_37: An ARM64 target for the manylinux_2_37 platform
  • +
  • aarch64-manylinux_2_38: An ARM64 target for the manylinux_2_38 platform
  • +
  • aarch64-manylinux_2_39: An ARM64 target for the manylinux_2_39 platform
  • +
  • aarch64-manylinux_2_40: An ARM64 target for the manylinux_2_40 platform
  • +
  • wasm32-pyodide2024: A wasm32 target using the Pyodide 2024 platform. Meant for use with Python 3.12
  • +
--python-version python-version

The Python version against which packages should be checked.

+

By default, the installed packages are checked against the version of the current interpreter.

+
--quiet, -q

Use quiet output.

Repeating this option, e.g., -qq, will enable a silent mode in which uv will write no output to stdout.

--system

Check packages in the system Python environment.

Disables discovery of virtual environments.