mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Add python-downloads-json-url
option for uv.toml
to configure custom Python installations via JSON URL (#12974)
Some checks are pending
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 | free-threaded python on 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 / 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 / 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 windows trampoline | i686 (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 / 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 | 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 | 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 macos aarch64 (push) Blocked by required conditions
CI / check system | python on macos x86-64 (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 / 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 | free-threaded python on 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 / 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 / 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 windows trampoline | i686 (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 / 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 | 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 | 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 macos aarch64 (push) Blocked by required conditions
CI / check system | python on macos x86-64 (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
## Summary Part of #12838. Allow users to configure `python-downloads-json-url` in `uv.toml` and not just from env. I followed similar PR #8695, so same as there it's also available in the CLI (I think maybe it's better not to be configurable from the CLI, but since the mirror parameters are, I think it's better to do the same) ## Test Plan <!-- How was it tested? -->
This commit is contained in:
parent
5ee54b4fa3
commit
0593b967ba
22 changed files with 232 additions and 55 deletions
|
@ -4728,6 +4728,12 @@ pub struct PythonListArgs {
|
|||
/// Select the output format.
|
||||
#[arg(long, value_enum, default_value_t = PythonListFormat::default())]
|
||||
pub output_format: PythonListFormat,
|
||||
|
||||
/// URL pointing to JSON of custom Python installations.
|
||||
///
|
||||
/// Note that currently, only local paths are supported.
|
||||
#[arg(long, env = EnvVars::UV_PYTHON_DOWNLOADS_JSON_URL)]
|
||||
pub python_downloads_json_url: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Args)]
|
||||
|
@ -4791,6 +4797,12 @@ pub struct PythonInstallArgs {
|
|||
#[arg(long, env = EnvVars::UV_PYPY_INSTALL_MIRROR)]
|
||||
pub pypy_mirror: Option<String>,
|
||||
|
||||
/// URL pointing to JSON of custom Python installations.
|
||||
///
|
||||
/// Note that currently, only local paths are supported.
|
||||
#[arg(long, env = EnvVars::UV_PYTHON_DOWNLOADS_JSON_URL)]
|
||||
pub python_downloads_json_url: Option<String>,
|
||||
|
||||
/// Reinstall the requested Python version, if it's already installed.
|
||||
///
|
||||
/// By default, uv will exit successfully if the version is already
|
||||
|
|
|
@ -268,8 +268,9 @@ impl PythonDownloadRequest {
|
|||
/// Iterate over all [`PythonDownload`]'s that match this request.
|
||||
pub fn iter_downloads(
|
||||
&self,
|
||||
python_downloads_json_url: Option<&str>,
|
||||
) -> Result<impl Iterator<Item = &'static ManagedPythonDownload> + use<'_>, Error> {
|
||||
Ok(ManagedPythonDownload::iter_all()?
|
||||
Ok(ManagedPythonDownload::iter_all(python_downloads_json_url)?
|
||||
.filter(move |download| self.satisfied_by_download(download)))
|
||||
}
|
||||
|
||||
|
@ -496,8 +497,9 @@ impl ManagedPythonDownload {
|
|||
/// be searched for — even if a pre-release was not explicitly requested.
|
||||
pub fn from_request(
|
||||
request: &PythonDownloadRequest,
|
||||
python_downloads_json_url: Option<&str>,
|
||||
) -> Result<&'static ManagedPythonDownload, Error> {
|
||||
if let Some(download) = request.iter_downloads()?.next() {
|
||||
if let Some(download) = request.iter_downloads(python_downloads_json_url)?.next() {
|
||||
return Ok(download);
|
||||
}
|
||||
|
||||
|
@ -505,7 +507,7 @@ impl ManagedPythonDownload {
|
|||
if let Some(download) = request
|
||||
.clone()
|
||||
.with_prereleases(true)
|
||||
.iter_downloads()?
|
||||
.iter_downloads(python_downloads_json_url)?
|
||||
.next()
|
||||
{
|
||||
return Ok(download);
|
||||
|
@ -514,32 +516,36 @@ impl ManagedPythonDownload {
|
|||
|
||||
Err(Error::NoDownloadFound(request.clone()))
|
||||
}
|
||||
|
||||
//noinspection RsUnresolvedPath - RustRover can't see through the `include!`
|
||||
|
||||
/// Iterate over all [`ManagedPythonDownload`]s.
|
||||
pub fn iter_all() -> Result<impl Iterator<Item = &'static ManagedPythonDownload>, Error> {
|
||||
let runtime_source = std::env::var(EnvVars::UV_PYTHON_DOWNLOADS_JSON_URL);
|
||||
|
||||
///
|
||||
/// Note: The list is generated on the first call to this function.
|
||||
/// so `python_downloads_json_url` is only used in the first call to this function.
|
||||
pub fn iter_all(
|
||||
python_downloads_json_url: Option<&str>,
|
||||
) -> Result<impl Iterator<Item = &'static ManagedPythonDownload>, Error> {
|
||||
let downloads = PYTHON_DOWNLOADS.get_or_try_init(|| {
|
||||
let json_downloads: HashMap<String, JsonPythonDownload> =
|
||||
if let Ok(json_source) = &runtime_source {
|
||||
if Url::parse(json_source).is_ok() {
|
||||
return Err(Error::RemoteJSONNotSupported());
|
||||
}
|
||||
let json_downloads: HashMap<String, JsonPythonDownload> = if let Some(json_source) =
|
||||
python_downloads_json_url
|
||||
{
|
||||
if Url::parse(json_source).is_ok() {
|
||||
return Err(Error::RemoteJSONNotSupported());
|
||||
}
|
||||
|
||||
let file = match fs_err::File::open(json_source) {
|
||||
Ok(file) => file,
|
||||
Err(e) => { Err(Error::Io(e)) }?,
|
||||
};
|
||||
|
||||
serde_json::from_reader(file)
|
||||
.map_err(|e| Error::InvalidPythonDownloadsJSON(json_source.clone(), e))?
|
||||
} else {
|
||||
serde_json::from_str(BUILTIN_PYTHON_DOWNLOADS_JSON).map_err(|e| {
|
||||
Error::InvalidPythonDownloadsJSON("EMBEDDED IN THE BINARY".to_string(), e)
|
||||
})?
|
||||
let file = match fs_err::File::open(json_source) {
|
||||
Ok(file) => file,
|
||||
Err(e) => { Err(Error::Io(e)) }?,
|
||||
};
|
||||
|
||||
serde_json::from_reader(file)
|
||||
.map_err(|e| Error::InvalidPythonDownloadsJSON(json_source.to_string(), e))?
|
||||
} else {
|
||||
serde_json::from_str(BUILTIN_PYTHON_DOWNLOADS_JSON).map_err(|e| {
|
||||
Error::InvalidPythonDownloadsJSON("EMBEDDED IN THE BINARY".to_string(), e)
|
||||
})?
|
||||
};
|
||||
|
||||
let result = parse_json_downloads(json_downloads);
|
||||
Ok(Cow::Owned(result))
|
||||
})?;
|
||||
|
|
|
@ -88,6 +88,7 @@ impl PythonInstallation {
|
|||
reporter: Option<&dyn Reporter>,
|
||||
python_install_mirror: Option<&str>,
|
||||
pypy_install_mirror: Option<&str>,
|
||||
python_downloads_json_url: Option<&str>,
|
||||
) -> Result<Self, Error> {
|
||||
let request = request.unwrap_or(&PythonRequest::Default);
|
||||
|
||||
|
@ -127,6 +128,7 @@ impl PythonInstallation {
|
|||
reporter,
|
||||
python_install_mirror,
|
||||
pypy_install_mirror,
|
||||
python_downloads_json_url,
|
||||
)
|
||||
.await
|
||||
{
|
||||
|
@ -146,13 +148,14 @@ impl PythonInstallation {
|
|||
reporter: Option<&dyn Reporter>,
|
||||
python_install_mirror: Option<&str>,
|
||||
pypy_install_mirror: Option<&str>,
|
||||
python_downloads_json_url: Option<&str>,
|
||||
) -> Result<Self, Error> {
|
||||
let installations = ManagedPythonInstallations::from_settings(None)?.init()?;
|
||||
let installations_dir = installations.root();
|
||||
let scratch_dir = installations.scratch();
|
||||
let _lock = installations.lock().await?;
|
||||
|
||||
let download = ManagedPythonDownload::from_request(&request)?;
|
||||
let download = ManagedPythonDownload::from_request(&request, python_downloads_json_url)?;
|
||||
let client = client_builder.build();
|
||||
|
||||
info!("Fetching requested Python...");
|
||||
|
|
|
@ -819,21 +819,40 @@ pub struct PythonInstallMirrors {
|
|||
"#
|
||||
)]
|
||||
pub pypy_install_mirror: Option<String>,
|
||||
|
||||
/// URL pointing to JSON of custom Python installations.
|
||||
///
|
||||
/// Note that currently, only local paths are supported.
|
||||
#[option(
|
||||
default = "None",
|
||||
value_type = "str",
|
||||
example = r#"
|
||||
python-downloads-json-url = "/etc/uv/python-downloads.json"
|
||||
"#
|
||||
)]
|
||||
pub python_downloads_json_url: Option<String>,
|
||||
}
|
||||
|
||||
impl Default for PythonInstallMirrors {
|
||||
fn default() -> Self {
|
||||
PythonInstallMirrors::resolve(None, None)
|
||||
PythonInstallMirrors::resolve(None, None, None)
|
||||
}
|
||||
}
|
||||
|
||||
impl PythonInstallMirrors {
|
||||
pub fn resolve(python_mirror: Option<String>, pypy_mirror: Option<String>) -> Self {
|
||||
pub fn resolve(
|
||||
python_mirror: Option<String>,
|
||||
pypy_mirror: Option<String>,
|
||||
python_downloads_json_url: Option<String>,
|
||||
) -> Self {
|
||||
let python_mirror_env = std::env::var(EnvVars::UV_PYTHON_INSTALL_MIRROR).ok();
|
||||
let pypy_mirror_env = std::env::var(EnvVars::UV_PYPY_INSTALL_MIRROR).ok();
|
||||
let python_downloads_json_url_env =
|
||||
std::env::var(EnvVars::UV_PYTHON_DOWNLOADS_JSON_URL).ok();
|
||||
PythonInstallMirrors {
|
||||
python_install_mirror: python_mirror_env.or(python_mirror),
|
||||
pypy_install_mirror: pypy_mirror_env.or(pypy_mirror),
|
||||
python_downloads_json_url: python_downloads_json_url_env.or(python_downloads_json_url),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1814,6 +1833,7 @@ pub struct OptionsWire {
|
|||
// install_mirror: PythonInstallMirrors,
|
||||
python_install_mirror: Option<String>,
|
||||
pypy_install_mirror: Option<String>,
|
||||
python_downloads_json_url: Option<String>,
|
||||
|
||||
// #[serde(flatten)]
|
||||
// publish: PublishOptions
|
||||
|
@ -1861,6 +1881,7 @@ impl From<OptionsWire> for Options {
|
|||
python_downloads,
|
||||
python_install_mirror,
|
||||
pypy_install_mirror,
|
||||
python_downloads_json_url,
|
||||
concurrent_downloads,
|
||||
concurrent_builds,
|
||||
concurrent_installs,
|
||||
|
@ -1967,6 +1988,7 @@ impl From<OptionsWire> for Options {
|
|||
install_mirrors: PythonInstallMirrors::resolve(
|
||||
python_install_mirror,
|
||||
pypy_install_mirror,
|
||||
python_downloads_json_url,
|
||||
),
|
||||
conflicts,
|
||||
publish: PublishOptions {
|
||||
|
|
|
@ -484,6 +484,7 @@ async fn build_package(
|
|||
Some(&PythonDownloadReporter::single(printer)),
|
||||
install_mirrors.python_install_mirror.as_deref(),
|
||||
install_mirrors.pypy_install_mirror.as_deref(),
|
||||
install_mirrors.python_downloads_json_url.as_deref(),
|
||||
)
|
||||
.await?
|
||||
.into_interpreter();
|
||||
|
|
|
@ -425,6 +425,7 @@ async fn init_project(
|
|||
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?
|
||||
.into_interpreter();
|
||||
|
@ -451,6 +452,7 @@ async fn init_project(
|
|||
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?
|
||||
.into_interpreter();
|
||||
|
@ -516,6 +518,7 @@ async fn init_project(
|
|||
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?
|
||||
.into_interpreter();
|
||||
|
@ -542,6 +545,7 @@ async fn init_project(
|
|||
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?
|
||||
.into_interpreter();
|
||||
|
|
|
@ -710,6 +710,7 @@ impl ScriptInterpreter {
|
|||
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?
|
||||
.into_interpreter();
|
||||
|
@ -903,6 +904,7 @@ impl ProjectInterpreter {
|
|||
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?;
|
||||
|
||||
|
@ -2280,6 +2282,7 @@ pub(crate) async fn init_script_python_requirement(
|
|||
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?
|
||||
.into_interpreter();
|
||||
|
|
|
@ -608,6 +608,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
|
|||
Some(&download_reporter),
|
||||
install_mirrors.python_install_mirror.as_deref(),
|
||||
install_mirrors.pypy_install_mirror.as_deref(),
|
||||
install_mirrors.python_downloads_json_url.as_deref(),
|
||||
)
|
||||
.await?
|
||||
.into_interpreter();
|
||||
|
@ -841,6 +842,7 @@ hint: If you are running a script with `{}` in the shebang, you may need to incl
|
|||
Some(&download_reporter),
|
||||
install_mirrors.python_install_mirror.as_deref(),
|
||||
install_mirrors.pypy_install_mirror.as_deref(),
|
||||
install_mirrors.python_downloads_json_url.as_deref(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ struct InstallRequest {
|
|||
}
|
||||
|
||||
impl InstallRequest {
|
||||
fn new(request: PythonRequest) -> Result<Self> {
|
||||
fn new(request: PythonRequest, python_downloads_json_url: Option<&str>) -> Result<Self> {
|
||||
// Make sure the request is a valid download request and fill platform information
|
||||
let download_request = PythonDownloadRequest::from_request(&request)
|
||||
.ok_or_else(|| {
|
||||
|
@ -55,18 +55,20 @@ impl InstallRequest {
|
|||
.fill()?;
|
||||
|
||||
// Find a matching download
|
||||
let download = match ManagedPythonDownload::from_request(&download_request) {
|
||||
Ok(download) => download,
|
||||
Err(downloads::Error::NoDownloadFound(request))
|
||||
if request.libc().is_some_and(Libc::is_musl)
|
||||
&& request.arch().is_some_and(Arch::is_arm) =>
|
||||
let download =
|
||||
match ManagedPythonDownload::from_request(&download_request, python_downloads_json_url)
|
||||
{
|
||||
return Err(anyhow::anyhow!(
|
||||
"uv does not yet provide musl Python distributions on aarch64."
|
||||
));
|
||||
}
|
||||
Err(err) => return Err(err.into()),
|
||||
};
|
||||
Ok(download) => download,
|
||||
Err(downloads::Error::NoDownloadFound(request))
|
||||
if request.libc().is_some_and(Libc::is_musl)
|
||||
&& request.arch().is_some_and(Arch::is_arm) =>
|
||||
{
|
||||
return Err(anyhow::anyhow!(
|
||||
"uv does not yet provide musl Python distributions on aarch64."
|
||||
));
|
||||
}
|
||||
Err(err) => return Err(err.into()),
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
request,
|
||||
|
@ -131,6 +133,7 @@ pub(crate) async fn install(
|
|||
force: bool,
|
||||
python_install_mirror: Option<String>,
|
||||
pypy_install_mirror: Option<String>,
|
||||
python_downloads_json_url: Option<String>,
|
||||
network_settings: NetworkSettings,
|
||||
default: bool,
|
||||
python_downloads: PythonDownloads,
|
||||
|
@ -171,13 +174,13 @@ pub(crate) async fn install(
|
|||
}]
|
||||
})
|
||||
.into_iter()
|
||||
.map(InstallRequest::new)
|
||||
.map(|a| InstallRequest::new(a, python_downloads_json_url.as_deref()))
|
||||
.collect::<Result<Vec<_>>>()?
|
||||
} else {
|
||||
targets
|
||||
.iter()
|
||||
.map(|target| PythonRequest::parse(target.as_str()))
|
||||
.map(InstallRequest::new)
|
||||
.map(|a| InstallRequest::new(a, python_downloads_json_url.as_deref()))
|
||||
.collect::<Result<Vec<_>>>()?
|
||||
};
|
||||
|
||||
|
@ -219,7 +222,10 @@ pub(crate) async fn install(
|
|||
changelog.existing.insert(installation.key().clone());
|
||||
if matches!(&request.request, &PythonRequest::Any) {
|
||||
// Construct an install request matching the existing installation
|
||||
match InstallRequest::new(PythonRequest::Key(installation.into())) {
|
||||
match InstallRequest::new(
|
||||
PythonRequest::Key(installation.into()),
|
||||
python_downloads_json_url.as_deref(),
|
||||
) {
|
||||
Ok(request) => {
|
||||
debug!("Will reinstall `{}`", installation.key().green());
|
||||
unsatisfied.push(Cow::Owned(request));
|
||||
|
|
|
@ -59,6 +59,7 @@ pub(crate) async fn list(
|
|||
all_arches: bool,
|
||||
show_urls: bool,
|
||||
output_format: PythonListFormat,
|
||||
python_downloads_json_url: Option<String>,
|
||||
python_preference: PythonPreference,
|
||||
python_downloads: PythonDownloads,
|
||||
cache: &Cache,
|
||||
|
@ -101,7 +102,7 @@ pub(crate) async fn list(
|
|||
|
||||
let downloads = download_request
|
||||
.as_ref()
|
||||
.map(PythonDownloadRequest::iter_downloads)
|
||||
.map(|a| PythonDownloadRequest::iter_downloads(a, python_downloads_json_url.as_deref()))
|
||||
.transpose()?
|
||||
.into_iter()
|
||||
.flatten();
|
||||
|
|
|
@ -150,6 +150,7 @@ pub(crate) async fn refine_interpreter(
|
|||
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?
|
||||
.into_interpreter();
|
||||
|
|
|
@ -84,6 +84,7 @@ pub(crate) async fn install(
|
|||
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?
|
||||
.into_interpreter();
|
||||
|
|
|
@ -724,6 +724,7 @@ async fn get_or_create_environment(
|
|||
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?
|
||||
.into_interpreter();
|
||||
|
|
|
@ -98,6 +98,7 @@ pub(crate) async fn upgrade(
|
|||
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?
|
||||
.into_interpreter(),
|
||||
|
|
|
@ -222,6 +222,7 @@ async fn venv_impl(
|
|||
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
|
||||
.into_diagnostic()?;
|
||||
|
|
|
@ -1333,6 +1333,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
args.all_arches,
|
||||
args.show_urls,
|
||||
args.output_format,
|
||||
args.python_downloads_json_url,
|
||||
globals.python_preference,
|
||||
globals.python_downloads,
|
||||
&cache,
|
||||
|
@ -1355,6 +1356,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
|
|||
args.force,
|
||||
args.python_install_mirror,
|
||||
args.pypy_install_mirror,
|
||||
args.python_downloads_json_url,
|
||||
globals.network_settings,
|
||||
args.default,
|
||||
globals.python_downloads,
|
||||
|
|
|
@ -849,12 +849,13 @@ pub(crate) struct PythonListSettings {
|
|||
pub(crate) all_versions: bool,
|
||||
pub(crate) show_urls: bool,
|
||||
pub(crate) output_format: PythonListFormat,
|
||||
pub(crate) python_downloads_json_url: Option<String>,
|
||||
}
|
||||
|
||||
impl PythonListSettings {
|
||||
/// Resolve the [`PythonListSettings`] from the CLI and filesystem configuration.
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
pub(crate) fn resolve(args: PythonListArgs, _filesystem: Option<FilesystemOptions>) -> Self {
|
||||
pub(crate) fn resolve(args: PythonListArgs, filesystem: Option<FilesystemOptions>) -> Self {
|
||||
let PythonListArgs {
|
||||
request,
|
||||
all_versions,
|
||||
|
@ -864,8 +865,18 @@ impl PythonListSettings {
|
|||
only_downloads,
|
||||
show_urls,
|
||||
output_format,
|
||||
python_downloads_json_url: python_downloads_json_url_arg,
|
||||
} = args;
|
||||
|
||||
let options = filesystem.map(FilesystemOptions::into_options);
|
||||
let python_downloads_json_url_option = match options {
|
||||
Some(options) => options.install_mirrors.python_downloads_json_url,
|
||||
None => None,
|
||||
};
|
||||
|
||||
let python_downloads_json_url =
|
||||
python_downloads_json_url_arg.or(python_downloads_json_url_option);
|
||||
|
||||
let kinds = if only_installed {
|
||||
PythonListKinds::Installed
|
||||
} else if only_downloads {
|
||||
|
@ -882,6 +893,7 @@ impl PythonListSettings {
|
|||
all_versions,
|
||||
show_urls,
|
||||
output_format,
|
||||
python_downloads_json_url,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -913,6 +925,7 @@ pub(crate) struct PythonInstallSettings {
|
|||
pub(crate) force: bool,
|
||||
pub(crate) python_install_mirror: Option<String>,
|
||||
pub(crate) pypy_install_mirror: Option<String>,
|
||||
pub(crate) python_downloads_json_url: Option<String>,
|
||||
pub(crate) default: bool,
|
||||
}
|
||||
|
||||
|
@ -921,15 +934,18 @@ impl PythonInstallSettings {
|
|||
#[allow(clippy::needless_pass_by_value)]
|
||||
pub(crate) fn resolve(args: PythonInstallArgs, filesystem: Option<FilesystemOptions>) -> Self {
|
||||
let options = filesystem.map(FilesystemOptions::into_options);
|
||||
let (python_mirror, pypy_mirror) = match options {
|
||||
let (python_mirror, pypy_mirror, python_downloads_json_url) = match options {
|
||||
Some(options) => (
|
||||
options.install_mirrors.python_install_mirror,
|
||||
options.install_mirrors.pypy_install_mirror,
|
||||
options.install_mirrors.python_downloads_json_url,
|
||||
),
|
||||
None => (None, None),
|
||||
None => (None, None, None),
|
||||
};
|
||||
let python_mirror = args.mirror.or(python_mirror);
|
||||
let pypy_mirror = args.pypy_mirror.or(pypy_mirror);
|
||||
let python_downloads_json_url =
|
||||
args.python_downloads_json_url.or(python_downloads_json_url);
|
||||
|
||||
let PythonInstallArgs {
|
||||
install_dir,
|
||||
|
@ -938,6 +954,7 @@ impl PythonInstallSettings {
|
|||
force,
|
||||
mirror: _,
|
||||
pypy_mirror: _,
|
||||
python_downloads_json_url: _,
|
||||
default,
|
||||
} = args;
|
||||
|
||||
|
@ -948,6 +965,7 @@ impl PythonInstallSettings {
|
|||
force,
|
||||
python_install_mirror: python_mirror,
|
||||
pypy_install_mirror: pypy_mirror,
|
||||
python_downloads_json_url,
|
||||
default,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -519,6 +519,13 @@ fn help_subsubcommand() {
|
|||
|
||||
[env: UV_PYPY_INSTALL_MIRROR=]
|
||||
|
||||
--python-downloads-json-url <PYTHON_DOWNLOADS_JSON_URL>
|
||||
URL pointing to JSON of custom Python installations.
|
||||
|
||||
Note that currently, only local paths are supported.
|
||||
|
||||
[env: UV_PYTHON_DOWNLOADS_JSON_URL=]
|
||||
|
||||
-r, --reinstall
|
||||
Reinstall the requested Python version, if it's already installed.
|
||||
|
||||
|
@ -772,15 +779,22 @@ fn help_flag_subsubcommand() {
|
|||
[TARGETS]... The Python version(s) to install [env: UV_PYTHON=]
|
||||
|
||||
Options:
|
||||
-i, --install-dir <INSTALL_DIR> The directory to store the Python installation in [env:
|
||||
UV_PYTHON_INSTALL_DIR=]
|
||||
--mirror <MIRROR> Set the URL to use as the source for downloading Python
|
||||
installations [env: UV_PYTHON_INSTALL_MIRROR=]
|
||||
--pypy-mirror <PYPY_MIRROR> Set the URL to use as the source for downloading PyPy
|
||||
installations [env: UV_PYPY_INSTALL_MIRROR=]
|
||||
-r, --reinstall Reinstall the requested Python version, if it's already installed
|
||||
-f, --force Replace existing Python executables during installation
|
||||
--default Use as the default Python version
|
||||
-i, --install-dir <INSTALL_DIR>
|
||||
The directory to store the Python installation in [env: UV_PYTHON_INSTALL_DIR=]
|
||||
--mirror <MIRROR>
|
||||
Set the URL to use as the source for downloading Python installations [env:
|
||||
UV_PYTHON_INSTALL_MIRROR=]
|
||||
--pypy-mirror <PYPY_MIRROR>
|
||||
Set the URL to use as the source for downloading PyPy installations [env:
|
||||
UV_PYPY_INSTALL_MIRROR=]
|
||||
--python-downloads-json-url <PYTHON_DOWNLOADS_JSON_URL>
|
||||
URL pointing to JSON of custom Python installations [env: UV_PYTHON_DOWNLOADS_JSON_URL=]
|
||||
-r, --reinstall
|
||||
Reinstall the requested Python version, if it's already installed
|
||||
-f, --force
|
||||
Replace existing Python executables during installation
|
||||
--default
|
||||
Use as the default Python version
|
||||
|
||||
Cache options:
|
||||
-n, --no-cache Avoid reading from or writing to the cache, instead using a temporary
|
||||
|
|
|
@ -148,6 +148,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -328,6 +329,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -509,6 +511,7 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -722,6 +725,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -871,6 +875,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -1063,6 +1068,7 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -1302,6 +1308,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -1550,6 +1557,7 @@ fn resolve_index_url() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -1755,6 +1763,7 @@ fn resolve_find_links() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -1926,6 +1935,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -2155,6 +2165,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -2367,6 +2378,7 @@ fn resolve_top_level() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -2537,6 +2549,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -2691,6 +2704,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -2845,6 +2859,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -3001,6 +3016,7 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -3231,6 +3247,7 @@ fn resolve_tool() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -3340,6 +3357,7 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -3555,6 +3573,7 @@ fn resolve_both() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -3860,6 +3879,7 @@ fn resolve_config_file() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -3967,7 +3987,7 @@ fn resolve_config_file() -> anyhow::Result<()> {
|
|||
|
|
||||
1 | [project]
|
||||
| ^^^^^^^
|
||||
unknown field `project`, expected one of `required-version`, `native-tls`, `offline`, `no-cache`, `cache-dir`, `preview`, `python-preference`, `python-downloads`, `concurrent-downloads`, `concurrent-builds`, `concurrent-installs`, `index`, `index-url`, `extra-index-url`, `no-index`, `find-links`, `index-strategy`, `keyring-provider`, `allow-insecure-host`, `resolution`, `prerelease`, `fork-strategy`, `dependency-metadata`, `config-settings`, `no-build-isolation`, `no-build-isolation-package`, `exclude-newer`, `link-mode`, `compile-bytecode`, `no-sources`, `upgrade`, `upgrade-package`, `reinstall`, `reinstall-package`, `no-build`, `no-build-package`, `no-binary`, `no-binary-package`, `python-install-mirror`, `pypy-install-mirror`, `publish-url`, `trusted-publishing`, `check-url`, `pip`, `cache-keys`, `override-dependencies`, `constraint-dependencies`, `build-constraint-dependencies`, `environments`, `required-environments`, `conflicts`, `workspace`, `sources`, `managed`, `package`, `default-groups`, `dev-dependencies`, `build-backend`
|
||||
unknown field `project`, expected one of `required-version`, `native-tls`, `offline`, `no-cache`, `cache-dir`, `preview`, `python-preference`, `python-downloads`, `concurrent-downloads`, `concurrent-builds`, `concurrent-installs`, `index`, `index-url`, `extra-index-url`, `no-index`, `find-links`, `index-strategy`, `keyring-provider`, `allow-insecure-host`, `resolution`, `prerelease`, `fork-strategy`, `dependency-metadata`, `config-settings`, `no-build-isolation`, `no-build-isolation-package`, `exclude-newer`, `link-mode`, `compile-bytecode`, `no-sources`, `upgrade`, `upgrade-package`, `reinstall`, `reinstall-package`, `no-build`, `no-build-package`, `no-binary`, `no-binary-package`, `python-install-mirror`, `pypy-install-mirror`, `python-downloads-json-url`, `publish-url`, `trusted-publishing`, `check-url`, `pip`, `cache-keys`, `override-dependencies`, `constraint-dependencies`, `build-constraint-dependencies`, `environments`, `required-environments`, `conflicts`, `workspace`, `sources`, `managed`, `package`, `default-groups`, `dev-dependencies`, `build-backend`
|
||||
"###
|
||||
);
|
||||
|
||||
|
@ -4108,6 +4128,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -4265,6 +4286,7 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -4441,6 +4463,7 @@ fn allow_insecure_host() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -4676,6 +4699,7 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -4890,6 +4914,7 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -5110,6 +5135,7 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -5325,6 +5351,7 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -5547,6 +5574,7 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -5762,6 +5790,7 @@ fn index_priority() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -5923,6 +5952,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -6070,6 +6100,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -6215,6 +6246,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -6362,6 +6394,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -6507,6 +6540,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
@ -6653,6 +6687,7 @@ fn verify_hashes() -> anyhow::Result<()> {
|
|||
install_mirrors: PythonInstallMirrors {
|
||||
python_install_mirror: None,
|
||||
pypy_install_mirror: None,
|
||||
python_downloads_json_url: None,
|
||||
},
|
||||
system: false,
|
||||
extras: ExtrasSpecification(
|
||||
|
|
|
@ -4770,6 +4770,11 @@ uv python list [OPTIONS] [REQUEST]
|
|||
<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-list--python-downloads-json-url"><a href="#uv-python-list--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>
|
||||
|
||||
<p>May also be set with the <code>UV_PYTHON_DOWNLOADS_JSON_URL</code> environment variable.</p>
|
||||
</dd><dt id="uv-python-list--quiet"><a href="#uv-python-list--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>
|
||||
|
@ -4941,6 +4946,11 @@ uv python install [OPTIONS] [TARGETS]...
|
|||
<p>Distributions can be read from a local directory by using the <code>file://</code> URL scheme.</p>
|
||||
|
||||
<p>May also be set with the <code>UV_PYPY_INSTALL_MIRROR</code> environment variable.</p>
|
||||
</dd><dt id="uv-python-install--python-downloads-json-url"><a href="#uv-python-install--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>
|
||||
|
||||
<p>May also be set with the <code>UV_PYTHON_DOWNLOADS_JSON_URL</code> environment variable.</p>
|
||||
</dd><dt id="uv-python-install--quiet"><a href="#uv-python-install--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>
|
||||
|
|
|
@ -1655,6 +1655,32 @@ Whether to allow Python downloads.
|
|||
|
||||
---
|
||||
|
||||
### [`python-downloads-json-url`](#python-downloads-json-url) {: #python-downloads-json-url }
|
||||
|
||||
URL pointing to JSON of custom Python installations.
|
||||
|
||||
Note that currently, only local paths are supported.
|
||||
|
||||
**Default value**: `None`
|
||||
|
||||
**Type**: `str`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
=== "pyproject.toml"
|
||||
|
||||
```toml
|
||||
[tool.uv]
|
||||
python-downloads-json-url = "/etc/uv/python-downloads.json"
|
||||
```
|
||||
=== "uv.toml"
|
||||
|
||||
```toml
|
||||
python-downloads-json-url = "/etc/uv/python-downloads.json"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### [`python-install-mirror`](#python-install-mirror) {: #python-install-mirror }
|
||||
|
||||
Mirror URL for downloading managed Python installations.
|
||||
|
|
7
uv.schema.json
generated
7
uv.schema.json
generated
|
@ -431,6 +431,13 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"python-downloads-json-url": {
|
||||
"description": "URL pointing to JSON of custom Python installations.\n\nNote that currently, only local paths are supported.",
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"python-install-mirror": {
|
||||
"description": "Mirror URL for downloading managed Python installations.\n\nBy default, managed Python installations are downloaded from [`python-build-standalone`](https://github.com/astral-sh/python-build-standalone). This variable can be set to a mirror URL to use a different source for Python installations. The provided URL will replace `https://github.com/astral-sh/python-build-standalone/releases/download` in, e.g., `https://github.com/astral-sh/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-aarch64-apple-darwin-install_only.tar.gz`.\n\nDistributions can be read from a local directory by using the `file://` URL scheme.",
|
||||
"type": [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue