Support --python-platform in uv tree (#5764)

## Summary

This allows you to set (e.g.) `--python-platform windows` to view the
resolved dependencies on Windows.

Closes https://github.com/astral-sh/uv/issues/5760.
This commit is contained in:
Charlie Marsh 2024-08-05 15:02:35 -04:00 committed by GitHub
parent 3156fccc85
commit 6b45baf7be
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 102 additions and 5 deletions

View file

@ -2370,6 +2370,21 @@ pub struct TreeArgs {
#[command(flatten)]
pub resolver: ResolverArgs,
/// The Python version to use when filtering the tree (via `--filter`). For example, pass
/// `--python-version 3.10` to display the dependencies that would be included when installing
/// on Python 3.10.
#[arg(long, conflicts_with = "universal")]
pub python_version: Option<PythonVersion>,
/// The platform to use when filtering the tree (via `--filter`). For example, pass `--platform
/// windows` to display the dependencies that would be included when installing on Windows.
///
/// 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
/// `aaarch64-apple-darwin`.
#[arg(long, conflicts_with = "universal")]
pub python_platform: Option<TargetTriple>,
/// The Python interpreter for which packages should be listed.
///
/// By default, uv installs into the virtual environment in the current working directory or

View file

@ -16,7 +16,7 @@ pub(crate) mod sync;
pub(crate) mod tree;
pub(crate) mod uninstall;
// Determine the tags, markers, and interpreter to use for resolution.
/// Determine the tags, markers, and interpreter to use for resolution.
pub(crate) fn resolution_environment(
python_version: Option<PythonVersion>,
python_platform: Option<TargetTriple>,

View file

@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::fmt::Write;
use anyhow::Result;
@ -5,9 +6,9 @@ use anyhow::Result;
use pep508_rs::PackageName;
use uv_cache::Cache;
use uv_client::Connectivity;
use uv_configuration::{Concurrency, PreviewMode};
use uv_configuration::{Concurrency, PreviewMode, TargetTriple};
use uv_fs::CWD;
use uv_python::{PythonFetch, PythonPreference, PythonRequest};
use uv_python::{PythonFetch, PythonPreference, PythonRequest, PythonVersion};
use uv_resolver::TreeDisplay;
use uv_warnings::warn_user_once;
use uv_workspace::{DiscoveryOptions, Workspace};
@ -30,6 +31,8 @@ pub(crate) async fn tree(
package: Vec<PackageName>,
no_dedupe: bool,
invert: bool,
python_version: Option<PythonVersion>,
python_platform: Option<TargetTriple>,
python: Option<String>,
settings: ResolverSettings,
python_preference: PythonPreference,
@ -79,10 +82,20 @@ pub(crate) async fn tree(
)
.await?;
// Apply the platform tags to the markers.
let markers = match (python_platform, python_version) {
(Some(python_platform), Some(python_version)) => {
Cow::Owned(python_version.markers(&python_platform.markers(interpreter.markers())))
}
(Some(python_platform), None) => Cow::Owned(python_platform.markers(interpreter.markers())),
(None, Some(python_version)) => Cow::Owned(python_version.markers(interpreter.markers())),
(None, None) => Cow::Borrowed(interpreter.markers()),
};
// Render the tree.
let tree = TreeDisplay::new(
&lock.lock,
(!universal).then(|| interpreter.markers()),
(!universal).then(|| markers.as_ref()),
depth.into(),
prune,
package,

View file

@ -1127,6 +1127,8 @@ async fn run_project(
args.package,
args.no_dedupe,
args.invert,
args.python_version,
args.python_platform,
args.python,
args.resolver,
globals.python_preference,

View file

@ -775,6 +775,8 @@ pub(crate) struct TreeSettings {
pub(crate) package: Vec<PackageName>,
pub(crate) no_dedupe: bool,
pub(crate) invert: bool,
pub(crate) python_version: Option<PythonVersion>,
pub(crate) python_platform: Option<TargetTriple>,
pub(crate) python: Option<String>,
pub(crate) resolver: ResolverSettings,
}
@ -789,6 +791,8 @@ impl TreeSettings {
frozen,
build,
resolver,
python_version,
python_platform,
python,
} = args;
@ -801,6 +805,8 @@ impl TreeSettings {
package: tree.package,
no_dedupe: tree.no_dedupe,
invert: tree.invert,
python_version,
python_platform,
python,
resolver: ResolverSettings::combine(resolver_options(resolver, build), filesystem),
}

View file

@ -219,7 +219,27 @@ fn platform_dependencies() -> Result<()> {
Resolved 8 packages in [TIME]
"###);
// Should include `colorama`, even though it's only included on Windows.
// Unless `--python-platform` is set to `windows`, in which case it should be included.
uv_snapshot!(context.filters(), context.tree().arg("--python-platform").arg("windows"), @r###"
success: true
exit_code: 0
----- stdout -----
project v0.1.0
black v24.3.0
click v8.1.7
colorama v0.4.6
mypy-extensions v1.0.0
packaging v24.0
pathspec v0.12.1
platformdirs v4.2.0
----- stderr -----
warning: `uv tree` is experimental and may change without warning
Resolved 8 packages in [TIME]
"###);
// When `--universal` is _not_ provided, should include `colorama`, even though it's only
// included on Windows.
uv_snapshot!(context.filters(), context.tree().arg("--universal"), @r###"
success: true
exit_code: 0

View file

@ -3392,6 +3392,47 @@ uv tree [OPTIONS]
<li><code>symlink</code>: Symbolically link packages from the wheel into the <code>site-packages</code> directory</li>
</ul>
</dd><dt><code>--python-version</code> <i>python-version</i></dt><dd><p>The Python version to use when filtering the tree (via <code>--filter</code>). For example, pass <code>--python-version 3.10</code> to display the dependencies that would be included when installing on Python 3.10</p>
</dd><dt><code>--python-platform</code> <i>python-platform</i></dt><dd><p>The platform to use when filtering the tree (via <code>--filter</code>). For example, pass <code>--platform windows</code> to display the dependencies that would be included when installing on Windows.</p>
<p>Represented as a &quot;target triple&quot;, a string that describes the target platform in terms of its CPU, vendor, and operating system name, like <code>x86_64-unknown-linux-gnu</code> or <code>aaarch64-apple-darwin</code>.</p>
<p>Possible values:</p>
<ul>
<li><code>windows</code>: An alias for <code>x86_64-pc-windows-msvc</code>, the default target for Windows</li>
<li><code>linux</code>: An alias for <code>x86_64-unknown-linux-gnu</code>, the default target for Linux</li>
<li><code>macos</code>: An alias for <code>aarch64-apple-darwin</code>, the default target for macOS</li>
<li><code>x86_64-pc-windows-msvc</code>: An x86 Windows target</li>
<li><code>x86_64-unknown-linux-gnu</code>: An x86 Linux target. Equivalent to <code>x86_64-manylinux_2_17</code></li>
<li><code>aarch64-apple-darwin</code>: An ARM-based macOS target, as seen on Apple Silicon devices</li>
<li><code>x86_64-apple-darwin</code>: An x86 macOS target</li>
<li><code>aarch64-unknown-linux-gnu</code>: An ARM64 Linux target. Equivalent to <code>aarch64-manylinux_2_17</code></li>
<li><code>aarch64-unknown-linux-musl</code>: An ARM64 Linux target</li>
<li><code>x86_64-unknown-linux-musl</code>: An <code>x86_64</code> Linux target</li>
<li><code>x86_64-manylinux_2_17</code>: An <code>x86_64</code> target for the <code>manylinux_2_17</code> platform</li>
<li><code>x86_64-manylinux_2_28</code>: An <code>x86_64</code> target for the <code>manylinux_2_28</code> platform</li>
<li><code>x86_64-manylinux_2_31</code>: An <code>x86_64</code> target for the <code>manylinux_2_31</code> platform</li>
<li><code>aarch64-manylinux_2_17</code>: An ARM64 target for the <code>manylinux_2_17</code> platform</li>
<li><code>aarch64-manylinux_2_28</code>: An ARM64 target for the <code>manylinux_2_28</code> platform</li>
<li><code>aarch64-manylinux_2_31</code>: An ARM64 target for the <code>manylinux_2_31</code> platform</li>
</ul>
</dd><dt><code>--python</code>, <code>-p</code> <i>python</i></dt><dd><p>The Python interpreter for which packages should be listed.</p>
<p>By default, uv installs into the virtual environment in the current working directory or any parent directory. The <code>--python</code> option allows you to specify a different interpreter, which is intended for use in continuous integration (CI) environments or other automated workflows.</p>