mirror of https://github.com/astral-sh/uv
Download versions in `uv python pin` if not found (#13946)
As another follow-up in the vein of https://github.com/astral-sh/uv/pull/13944, I noticed `uv python pin` doesn't download Python versions, which is a bit weird because we'll warn it's not found.
This commit is contained in:
parent
210b579188
commit
f20a25f91f
|
|
@ -7,17 +7,22 @@ use owo_colors::OwoColorize;
|
|||
use tracing::debug;
|
||||
|
||||
use uv_cache::Cache;
|
||||
use uv_client::BaseClientBuilder;
|
||||
use uv_dirs::user_uv_config_dir;
|
||||
use uv_fs::Simplified;
|
||||
use uv_python::{
|
||||
EnvironmentPreference, PYTHON_VERSION_FILENAME, PythonInstallation, PythonPreference,
|
||||
PythonRequest, PythonVersionFile, VersionFileDiscoveryOptions,
|
||||
EnvironmentPreference, PYTHON_VERSION_FILENAME, PythonDownloads, PythonInstallation,
|
||||
PythonPreference, PythonRequest, PythonVersionFile, VersionFileDiscoveryOptions,
|
||||
};
|
||||
use uv_settings::PythonInstallMirrors;
|
||||
use uv_warnings::warn_user_once;
|
||||
use uv_workspace::{DiscoveryOptions, VirtualProject, WorkspaceCache};
|
||||
|
||||
use crate::commands::{ExitStatus, project::find_requires_python};
|
||||
use crate::commands::{
|
||||
ExitStatus, project::find_requires_python, reporters::PythonDownloadReporter,
|
||||
};
|
||||
use crate::printer::Printer;
|
||||
use crate::settings::NetworkSettings;
|
||||
|
||||
/// Pin to a specific Python version.
|
||||
#[allow(clippy::fn_params_excessive_bools)]
|
||||
|
|
@ -26,9 +31,12 @@ pub(crate) async fn pin(
|
|||
request: Option<String>,
|
||||
resolved: bool,
|
||||
python_preference: PythonPreference,
|
||||
python_downloads: PythonDownloads,
|
||||
no_project: bool,
|
||||
global: bool,
|
||||
rm: bool,
|
||||
install_mirrors: PythonInstallMirrors,
|
||||
network_settings: NetworkSettings,
|
||||
cache: &Cache,
|
||||
printer: Printer,
|
||||
) -> Result<ExitStatus> {
|
||||
|
|
@ -98,12 +106,26 @@ pub(crate) async fn pin(
|
|||
bail!("Requests for arbitrary names (e.g., `{name}`) are not supported in version files");
|
||||
}
|
||||
|
||||
let python = match PythonInstallation::find(
|
||||
&request,
|
||||
let client_builder = BaseClientBuilder::new()
|
||||
.connectivity(network_settings.connectivity)
|
||||
.native_tls(network_settings.native_tls)
|
||||
.allow_insecure_host(network_settings.allow_insecure_host.clone());
|
||||
let reporter = PythonDownloadReporter::single(printer);
|
||||
|
||||
let python = match PythonInstallation::find_or_download(
|
||||
Some(&request),
|
||||
EnvironmentPreference::OnlySystem,
|
||||
python_preference,
|
||||
python_downloads,
|
||||
&client_builder,
|
||||
cache,
|
||||
) {
|
||||
Some(&reporter),
|
||||
install_mirrors.python_install_mirror.as_deref(),
|
||||
install_mirrors.pypy_install_mirror.as_deref(),
|
||||
install_mirrors.python_downloads_json_url.as_deref(),
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(python) => Some(python),
|
||||
// If no matching Python version is found, don't fail unless `resolved` was requested
|
||||
Err(uv_python::Error::MissingPython(err)) if !resolved => {
|
||||
|
|
|
|||
|
|
@ -1464,9 +1464,12 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
args.request,
|
||||
args.resolved,
|
||||
globals.python_preference,
|
||||
globals.python_downloads,
|
||||
args.no_project,
|
||||
args.global,
|
||||
args.rm,
|
||||
args.install_mirrors,
|
||||
globals.network_settings,
|
||||
&cache,
|
||||
printer,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1057,12 +1057,13 @@ pub(crate) struct PythonPinSettings {
|
|||
pub(crate) no_project: bool,
|
||||
pub(crate) global: bool,
|
||||
pub(crate) rm: bool,
|
||||
pub(crate) install_mirrors: PythonInstallMirrors,
|
||||
}
|
||||
|
||||
impl PythonPinSettings {
|
||||
/// Resolve the [`PythonPinSettings`] from the CLI and workspace configuration.
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
pub(crate) fn resolve(args: PythonPinArgs, _filesystem: Option<FilesystemOptions>) -> Self {
|
||||
pub(crate) fn resolve(args: PythonPinArgs, filesystem: Option<FilesystemOptions>) -> Self {
|
||||
let PythonPinArgs {
|
||||
request,
|
||||
no_resolved,
|
||||
|
|
@ -1072,12 +1073,17 @@ impl PythonPinSettings {
|
|||
rm,
|
||||
} = args;
|
||||
|
||||
let install_mirrors = filesystem
|
||||
.map(|fs| fs.install_mirrors.clone())
|
||||
.unwrap_or_default();
|
||||
|
||||
Self {
|
||||
request,
|
||||
resolved: flag(resolved, no_resolved).unwrap_or(false),
|
||||
no_project,
|
||||
global,
|
||||
rm,
|
||||
install_mirrors,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -816,6 +816,32 @@ fn python_pin_with_comments() -> Result<()> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "python-managed")]
|
||||
fn python_pin_install() {
|
||||
let context: TestContext = TestContext::new_with_versions(&[]).with_filtered_python_sources();
|
||||
|
||||
// Should not install 3.12 when downloads are not automatic
|
||||
uv_snapshot!(context.filters(), context.python_pin().arg("3.12"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Pinned `.python-version` to `3.12`
|
||||
|
||||
----- stderr -----
|
||||
warning: No interpreter found for Python 3.12 in [PYTHON SOURCES]
|
||||
");
|
||||
|
||||
uv_snapshot!(context.filters(), context.python_pin().arg("3.12").env("UV_PYTHON_DOWNLOADS", "auto"), @r"
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Pinned `.python-version` to `3.12`
|
||||
|
||||
----- stderr -----
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn python_pin_rm() {
|
||||
let context: TestContext = TestContext::new_with_versions(&["3.12"]);
|
||||
|
|
|
|||
Loading…
Reference in New Issue