mirror of https://github.com/astral-sh/uv
Add `UV_PYTHON_EXTRA_INSTALL_DIRS`
This commit is contained in:
parent
ea5a09215b
commit
4b69fde81b
|
|
@ -339,54 +339,61 @@ fn python_executables_from_installed<'a>(
|
||||||
preference: PythonPreference,
|
preference: PythonPreference,
|
||||||
preview: Preview,
|
preview: Preview,
|
||||||
) -> Box<dyn Iterator<Item = Result<(PythonSource, PathBuf), Error>> + 'a> {
|
) -> Box<dyn Iterator<Item = Result<(PythonSource, PathBuf), Error>> + 'a> {
|
||||||
let from_managed_installations = iter::once_with(move || {
|
let extra_managed_install_dirs = env::var_os(EnvVars::UV_PYTHON_EXTRA_INSTALL_DIRS)
|
||||||
ManagedPythonInstallations::from_settings(None)
|
.into_iter()
|
||||||
.map_err(Error::from)
|
.flat_map(|value| env::split_paths(&value).collect::<Vec<_>>())
|
||||||
.and_then(|installed_installations| {
|
.filter(|path| !path.as_os_str().is_empty());
|
||||||
debug!(
|
|
||||||
|
let from_managed_installations = iter::once(None)
|
||||||
|
.chain(extra_managed_install_dirs.into_iter().map(Some))
|
||||||
|
.map(move |install_dir| {
|
||||||
|
ManagedPythonInstallations::from_settings(install_dir)
|
||||||
|
.map_err(Error::from)
|
||||||
|
.and_then(|installed_installations| {
|
||||||
|
debug!(
|
||||||
"Searching for managed installations at `{}`",
|
"Searching for managed installations at `{}`",
|
||||||
installed_installations.root().user_display()
|
installed_installations.root().user_display()
|
||||||
);
|
);
|
||||||
let installations = installed_installations.find_matching_current_platform()?;
|
let installations = installed_installations.find_matching_current_platform()?;
|
||||||
|
|
||||||
let build_versions = python_build_versions_from_env()?;
|
let build_versions = python_build_versions_from_env()?;
|
||||||
|
|
||||||
// Check that the Python version and platform satisfy the request to avoid
|
// Check that the Python version and platform satisfy the request to avoid
|
||||||
// unnecessary interpreter queries later
|
// unnecessary interpreter queries later
|
||||||
Ok(installations
|
Ok(installations
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(move |installation| {
|
.filter(move |installation| {
|
||||||
if !version.matches_version(&installation.version()) {
|
if !version.matches_version(&installation.version()) {
|
||||||
debug!("Skipping managed installation `{installation}`: does not satisfy `{version}`");
|
debug!("Skipping managed installation `{installation}`: does not satisfy `{version}`");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if !platform.matches(installation.platform()) {
|
if !platform.matches(installation.platform()) {
|
||||||
debug!("Skipping managed installation `{installation}`: does not satisfy requested platform `{platform}`");
|
debug!("Skipping managed installation `{installation}`: does not satisfy requested platform `{platform}`");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(requested_build) = build_versions.get(&installation.implementation()) {
|
|
||||||
let Some(installation_build) = installation.build() else {
|
|
||||||
debug!(
|
|
||||||
"Skipping managed installation `{installation}`: a build version was requested but is not recorded for this installation"
|
|
||||||
);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
if installation_build != requested_build {
|
|
||||||
debug!(
|
|
||||||
"Skipping managed installation `{installation}`: requested build version `{requested_build}` does not match installation build version `{installation_build}`"
|
|
||||||
);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
true
|
if let Some(requested_build) = build_versions.get(&installation.implementation()) {
|
||||||
})
|
let Some(installation_build) = installation.build() else {
|
||||||
.inspect(|installation| debug!("Found managed installation `{installation}`"))
|
debug!(
|
||||||
.map(move |installation| {
|
"Skipping managed installation `{installation}`: a build version was requested but is not recorded for this installation"
|
||||||
// If it's not a patch version request, then attempt to read the stable
|
);
|
||||||
// minor version link.
|
return false;
|
||||||
let executable = version
|
};
|
||||||
|
if installation_build != requested_build {
|
||||||
|
debug!(
|
||||||
|
"Skipping managed installation `{installation}`: requested build version `{requested_build}` does not match installation build version `{installation_build}`"
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
})
|
||||||
|
.inspect(|installation| debug!("Found managed installation `{installation}`"))
|
||||||
|
.map(move |installation| {
|
||||||
|
// If it's not a patch version request, then attempt to read the stable
|
||||||
|
// minor version link.
|
||||||
|
let executable = version
|
||||||
.patch()
|
.patch()
|
||||||
.is_none()
|
.is_none()
|
||||||
.then(|| {
|
.then(|| {
|
||||||
|
|
@ -394,21 +401,21 @@ fn python_executables_from_installed<'a>(
|
||||||
&installation,
|
&installation,
|
||||||
preview,
|
preview,
|
||||||
)
|
)
|
||||||
.filter(PythonMinorVersionLink::exists)
|
.filter(PythonMinorVersionLink::exists)
|
||||||
.map(
|
.map(
|
||||||
|minor_version_link| {
|
|minor_version_link| {
|
||||||
minor_version_link.symlink_executable.clone()
|
minor_version_link.symlink_executable.clone()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.flatten()
|
.flatten()
|
||||||
.unwrap_or_else(|| installation.executable(false));
|
.unwrap_or_else(|| installation.executable(false));
|
||||||
(PythonSource::Managed, executable)
|
(PythonSource::Managed, executable)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.flatten_ok();
|
.flatten_ok();
|
||||||
|
|
||||||
let from_search_path = iter::once_with(move || {
|
let from_search_path = iter::once_with(move || {
|
||||||
python_executables_from_search_path(version, implementation)
|
python_executables_from_search_path(version, implementation)
|
||||||
|
|
|
||||||
|
|
@ -262,7 +262,7 @@ impl ManagedPythonInstallations {
|
||||||
) -> Result<impl DoubleEndedIterator<Item = ManagedPythonInstallation> + use<>, Error> {
|
) -> Result<impl DoubleEndedIterator<Item = ManagedPythonInstallation> + use<>, Error> {
|
||||||
let platform = Platform::from_env()?;
|
let platform = Platform::from_env()?;
|
||||||
|
|
||||||
let iter = Self::from_settings(None)?
|
let iter = self
|
||||||
.find_all()?
|
.find_all()?
|
||||||
.filter(move |installation| {
|
.filter(move |installation| {
|
||||||
if !platform.supports(installation.platform()) {
|
if !platform.supports(installation.platform()) {
|
||||||
|
|
|
||||||
|
|
@ -371,6 +371,13 @@ impl EnvVars {
|
||||||
#[attr_added_in("0.2.22")]
|
#[attr_added_in("0.2.22")]
|
||||||
pub const UV_PYTHON_INSTALL_DIR: &'static str = "UV_PYTHON_INSTALL_DIR";
|
pub const UV_PYTHON_INSTALL_DIR: &'static str = "UV_PYTHON_INSTALL_DIR";
|
||||||
|
|
||||||
|
/// Specifies additional directories to search for managed Python installations.
|
||||||
|
///
|
||||||
|
/// Directories should be separated by the platform-specific path separator, i.e.,
|
||||||
|
/// `:` on Unix and `;` on Windows.
|
||||||
|
#[attr_added_in("next release")]
|
||||||
|
pub const UV_PYTHON_EXTRA_INSTALL_DIRS: &'static str = "UV_PYTHON_EXTRA_INSTALL_DIRS";
|
||||||
|
|
||||||
/// Whether to install the Python executable into the `UV_PYTHON_BIN_DIR` directory.
|
/// Whether to install the Python executable into the `UV_PYTHON_BIN_DIR` directory.
|
||||||
#[attr_added_in("0.8.0")]
|
#[attr_added_in("0.8.0")]
|
||||||
pub const UV_PYTHON_INSTALL_BIN: &'static str = "UV_PYTHON_INSTALL_BIN";
|
pub const UV_PYTHON_INSTALL_BIN: &'static str = "UV_PYTHON_INSTALL_BIN";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue