Account for `python_downloads_json_url` on Pre-release Python version warnings (#16737)

Solves #16711
This commit is contained in:
Meitar Reihan 2025-11-14 23:12:35 +02:00 committed by GitHub
parent 4e4235648a
commit 7f4d8c67a8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 62 additions and 8 deletions

View File

@ -6032,6 +6032,12 @@ pub struct PythonFindArgs {
/// Show the Python version that would be used instead of the path to the interpreter. /// Show the Python version that would be used instead of the path to the interpreter.
#[arg(long)] #[arg(long)]
pub show_version: bool, pub show_version: bool,
/// URL pointing to JSON of custom Python installations.
///
/// Note that currently, only local paths are supported.
#[arg(long)]
pub python_downloads_json_url: Option<String>,
} }
#[derive(Args)] #[derive(Args)]

View File

@ -59,12 +59,13 @@ impl PythonInstallation {
request: &PythonRequest, request: &PythonRequest,
environments: EnvironmentPreference, environments: EnvironmentPreference,
preference: PythonPreference, preference: PythonPreference,
python_downloads_json_url: Option<&str>,
cache: &Cache, cache: &Cache,
preview: Preview, preview: Preview,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
let installation = let installation =
find_python_installation(request, environments, preference, cache, preview)??; find_python_installation(request, environments, preference, cache, preview)??;
installation.warn_if_outdated_prerelease(request, None); installation.warn_if_outdated_prerelease(request, python_downloads_json_url);
Ok(installation) Ok(installation)
} }
@ -74,12 +75,13 @@ impl PythonInstallation {
request: &PythonRequest, request: &PythonRequest,
environments: EnvironmentPreference, environments: EnvironmentPreference,
preference: PythonPreference, preference: PythonPreference,
python_downloads_json_url: Option<&str>,
cache: &Cache, cache: &Cache,
preview: Preview, preview: Preview,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
let installation = let installation =
find_best_python_installation(request, environments, preference, cache, preview)??; find_best_python_installation(request, environments, preference, cache, preview)??;
installation.warn_if_outdated_prerelease(request, None); installation.warn_if_outdated_prerelease(request, python_downloads_json_url);
Ok(installation) Ok(installation)
} }
@ -102,7 +104,14 @@ impl PythonInstallation {
let request = request.unwrap_or(&PythonRequest::Default); let request = request.unwrap_or(&PythonRequest::Default);
// Search for the installation // Search for the installation
let err = match Self::find(request, environments, preference, cache, preview) { let err = match Self::find(
request,
environments,
preference,
python_downloads_json_url,
cache,
preview,
) {
Ok(installation) => return Ok(installation), Ok(installation) => return Ok(installation),
Err(err) => err, Err(err) => err,
}; };

View File

@ -44,6 +44,7 @@ use uv_resolver::{
InMemoryIndex, OptionsBuilder, PrereleaseMode, PylockToml, PythonRequirement, ResolutionMode, InMemoryIndex, OptionsBuilder, PrereleaseMode, PylockToml, PythonRequirement, ResolutionMode,
ResolverEnvironment, ResolverEnvironment,
}; };
use uv_settings::PythonInstallMirrors;
use uv_static::EnvVars; use uv_static::EnvVars;
use uv_torch::{TorchMode, TorchSource, TorchStrategy}; use uv_torch::{TorchMode, TorchSource, TorchStrategy};
use uv_types::{EmptyInstalledPackages, HashStrategy}; use uv_types::{EmptyInstalledPackages, HashStrategy};
@ -102,6 +103,7 @@ pub(crate) async fn pip_compile(
extra_build_dependencies: &ExtraBuildDependencies, extra_build_dependencies: &ExtraBuildDependencies,
extra_build_variables: &ExtraBuildVariables, extra_build_variables: &ExtraBuildVariables,
build_options: BuildOptions, build_options: BuildOptions,
install_mirrors: PythonInstallMirrors,
mut python_version: Option<PythonVersion>, mut python_version: Option<PythonVersion>,
python_platform: Option<TargetTriple>, python_platform: Option<TargetTriple>,
universal: bool, universal: bool,
@ -296,6 +298,7 @@ pub(crate) async fn pip_compile(
&request, &request,
environment_preference, environment_preference,
python_preference, python_preference,
install_mirrors.python_downloads_json_url.as_deref(),
&cache, &cache,
preview, preview,
) )
@ -312,6 +315,7 @@ pub(crate) async fn pip_compile(
&request, &request,
environment_preference, environment_preference,
python_preference, python_preference,
install_mirrors.python_downloads_json_url.as_deref(),
&cache, &cache,
preview, preview,
) )

View File

@ -31,6 +31,7 @@ pub(crate) async fn find(
no_config: bool, no_config: bool,
system: bool, system: bool,
python_preference: PythonPreference, python_preference: PythonPreference,
python_downloads_json_url: Option<&str>,
cache: &Cache, cache: &Cache,
printer: Printer, printer: Printer,
preview: Preview, preview: Preview,
@ -78,6 +79,7 @@ pub(crate) async fn find(
&python_request.unwrap_or_default(), &python_request.unwrap_or_default(),
environment_preference, environment_preference,
python_preference, python_preference,
python_downloads_json_url,
cache, cache,
preview, preview,
)?; )?;

View File

@ -100,6 +100,7 @@ pub(crate) async fn pin(
pin, pin,
virtual_project, virtual_project,
python_preference, python_preference,
install_mirrors.python_downloads_json_url.as_deref(),
cache, cache,
preview, preview,
); );
@ -264,6 +265,7 @@ fn warn_if_existing_pin_incompatible_with_project(
pin: &PythonRequest, pin: &PythonRequest,
virtual_project: &VirtualProject, virtual_project: &VirtualProject,
python_preference: PythonPreference, python_preference: PythonPreference,
python_downloads_json_url: Option<&str>,
cache: &Cache, cache: &Cache,
preview: Preview, preview: Preview,
) { ) {
@ -289,6 +291,7 @@ fn warn_if_existing_pin_incompatible_with_project(
pin, pin,
EnvironmentPreference::OnlySystem, EnvironmentPreference::OnlySystem,
python_preference, python_preference,
python_downloads_json_url,
cache, cache,
preview, preview,
) { ) {

View File

@ -631,6 +631,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
&args.settings.extra_build_dependencies, &args.settings.extra_build_dependencies,
&args.settings.extra_build_variables, &args.settings.extra_build_variables,
args.settings.build_options, args.settings.build_options,
args.settings.install_mirrors,
args.settings.python_version, args.settings.python_version,
args.settings.python_platform, args.settings.python_platform,
args.settings.universal, args.settings.universal,
@ -1614,7 +1615,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
command: PythonCommand::Find(args), command: PythonCommand::Find(args),
}) => { }) => {
// Resolve the settings from the command-line arguments and workspace configuration. // Resolve the settings from the command-line arguments and workspace configuration.
let args = settings::PythonFindSettings::resolve(args, filesystem); let args = settings::PythonFindSettings::resolve(args, filesystem, environment);
// Initialize the cache. // Initialize the cache.
let cache = cache.init()?; let cache = cache.init()?;
@ -1641,6 +1642,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
cli.top_level.no_config, cli.top_level.no_config,
args.system, args.system,
globals.python_preference, globals.python_preference,
args.python_downloads_json_url.as_deref(),
&cache, &cache,
printer, printer,
globals.preview, globals.preview,

View File

@ -1235,12 +1235,17 @@ pub(crate) struct PythonFindSettings {
pub(crate) show_version: bool, pub(crate) show_version: bool,
pub(crate) no_project: bool, pub(crate) no_project: bool,
pub(crate) system: bool, pub(crate) system: bool,
pub(crate) python_downloads_json_url: Option<String>,
} }
impl PythonFindSettings { impl PythonFindSettings {
/// Resolve the [`PythonFindSettings`] from the CLI and workspace configuration. /// Resolve the [`PythonFindSettings`] from the CLI and workspace configuration.
#[allow(clippy::needless_pass_by_value)] #[allow(clippy::needless_pass_by_value)]
pub(crate) fn resolve(args: PythonFindArgs, _filesystem: Option<FilesystemOptions>) -> Self { pub(crate) fn resolve(
args: PythonFindArgs,
filesystem: Option<FilesystemOptions>,
environment: EnvironmentOptions,
) -> Self {
let PythonFindArgs { let PythonFindArgs {
request, request,
show_version, show_version,
@ -1248,13 +1253,32 @@ impl PythonFindSettings {
system, system,
no_system, no_system,
script: _, script: _,
python_downloads_json_url,
} = args; } = args;
let filesystem_install_mirrors = filesystem
.map(|fs| fs.install_mirrors.clone())
.unwrap_or_default();
let install_mirrors = PythonInstallMirrors {
python_downloads_json_url,
..Default::default()
}
.combine(environment.install_mirrors)
.combine(filesystem_install_mirrors);
let PythonInstallMirrors {
python_install_mirror: _,
pypy_install_mirror: _,
python_downloads_json_url,
} = install_mirrors;
Self { Self {
request, request,
show_version, show_version,
no_project, no_project,
system: flag(system, no_system, "system").unwrap_or_default(), system: flag(system, no_system, "system").unwrap_or_default(),
python_downloads_json_url,
} }
} }
} }

View File

@ -631,7 +631,7 @@ impl TestContext {
.iter() .iter()
.map(|version| PythonVersion::from_str(version).unwrap()) .map(|version| PythonVersion::from_str(version).unwrap())
.zip( .zip(
python_installations_for_versions(&temp_dir, python_versions) python_installations_for_versions(&temp_dir, python_versions, None)
.expect("Failed to find test Python versions"), .expect("Failed to find test Python versions"),
) )
.collect(); .collect();
@ -1689,7 +1689,7 @@ pub fn python_path_with_versions(
python_versions: &[&str], python_versions: &[&str],
) -> anyhow::Result<OsString> { ) -> anyhow::Result<OsString> {
Ok(env::join_paths( Ok(env::join_paths(
python_installations_for_versions(temp_dir, python_versions)? python_installations_for_versions(temp_dir, python_versions, None)?
.into_iter() .into_iter()
.map(|path| path.parent().unwrap().to_path_buf()), .map(|path| path.parent().unwrap().to_path_buf()),
)?) )?)
@ -1701,6 +1701,7 @@ pub fn python_path_with_versions(
pub fn python_installations_for_versions( pub fn python_installations_for_versions(
temp_dir: &ChildPath, temp_dir: &ChildPath,
python_versions: &[&str], python_versions: &[&str],
python_downloads_json_url: Option<&str>,
) -> anyhow::Result<Vec<PathBuf>> { ) -> anyhow::Result<Vec<PathBuf>> {
let cache = Cache::from_path(temp_dir.child("cache").to_path_buf()).init()?; let cache = Cache::from_path(temp_dir.child("cache").to_path_buf()).init()?;
let selected_pythons = python_versions let selected_pythons = python_versions
@ -1710,6 +1711,7 @@ pub fn python_installations_for_versions(
&PythonRequest::parse(python_version), &PythonRequest::parse(python_version),
EnvironmentPreference::OnlySystem, EnvironmentPreference::OnlySystem,
PythonPreference::Managed, PythonPreference::Managed,
python_downloads_json_url,
&cache, &cache,
Preview::default(), Preview::default(),
) { ) {

View File

@ -3686,7 +3686,9 @@ uv python find [OPTIONS] [REQUEST]
<p>Other command-line arguments (such as relative paths) will be resolved relative to the current working directory.</p> <p>Other command-line arguments (such as relative paths) will be resolved relative to the current working directory.</p>
<p>See <code>--directory</code> to change the working directory entirely.</p> <p>See <code>--directory</code> to change the working directory entirely.</p>
<p>This setting has no effect when used in the <code>uv pip</code> interface.</p> <p>This setting has no effect when used in the <code>uv pip</code> interface.</p>
<p>May also be set with the <code>UV_PROJECT</code> environment variable.</p></dd><dt id="uv-python-find--quiet"><a href="#uv-python-find--quiet"><code>--quiet</code></a>, <code>-q</code></dt><dd><p>Use quiet output.</p> <p>May also be set with the <code>UV_PROJECT</code> environment variable.</p></dd><dt id="uv-python-find--python-downloads-json-url"><a href="#uv-python-find--python-downloads-json-url"><code>--python-downloads-json-url</code></a> <i>python-downloads-json-url</i></dt><dd><p>URL pointing to JSON of custom Python installations.</p>
<p>Note that currently, only local paths are supported.</p>
</dd><dt id="uv-python-find--quiet"><a href="#uv-python-find--quiet"><code>--quiet</code></a>, <code>-q</code></dt><dd><p>Use quiet output.</p>
<p>Repeating this option, e.g., <code>-qq</code>, will enable a silent mode in which uv will write no output to stdout.</p> <p>Repeating this option, e.g., <code>-qq</code>, will enable a silent mode in which uv will write no output to stdout.</p>
</dd><dt id="uv-python-find--script"><a href="#uv-python-find--script"><code>--script</code></a> <i>script</i></dt><dd><p>Find the environment for a Python script, rather than the current project</p> </dd><dt id="uv-python-find--script"><a href="#uv-python-find--script"><code>--script</code></a> <i>script</i></dt><dd><p>Find the environment for a Python script, rather than the current project</p>
</dd><dt id="uv-python-find--show-version"><a href="#uv-python-find--show-version"><code>--show-version</code></a></dt><dd><p>Show the Python version that would be used instead of the path to the interpreter</p> </dd><dt id="uv-python-find--show-version"><a href="#uv-python-find--show-version"><code>--show-version</code></a></dt><dd><p>Show the Python version that would be used instead of the path to the interpreter</p>