mirror of https://github.com/astral-sh/uv
Merge `uv-toolchain` and `uv-interpreter` (#3265)
Moves all of `uv-toolchain` into `uv-interpreter`. We may split these out in the future, but the refactoring I want to do for interpreter discovery is easier if I don't have to deal with entanglement. Includes some restructuring of `uv-interpreter`. Part of #2386
This commit is contained in:
parent
1d2c57a259
commit
630d3fde5c
|
|
@ -4524,7 +4524,6 @@ dependencies = [
|
|||
"uv-normalize",
|
||||
"uv-requirements",
|
||||
"uv-resolver",
|
||||
"uv-toolchain",
|
||||
"uv-types",
|
||||
"uv-virtualenv",
|
||||
"uv-warnings",
|
||||
|
|
@ -4716,7 +4715,6 @@ dependencies = [
|
|||
"uv-interpreter",
|
||||
"uv-normalize",
|
||||
"uv-resolver",
|
||||
"uv-toolchain",
|
||||
"uv-types",
|
||||
"uv-workspace",
|
||||
"walkdir",
|
||||
|
|
@ -4891,6 +4889,7 @@ dependencies = [
|
|||
"cache-key",
|
||||
"configparser",
|
||||
"fs-err",
|
||||
"futures",
|
||||
"indoc",
|
||||
"insta",
|
||||
"install-wheel-rs",
|
||||
|
|
@ -4901,16 +4900,22 @@ dependencies = [
|
|||
"platform-tags",
|
||||
"pypi-types",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"reqwest-middleware",
|
||||
"rmp-serde",
|
||||
"same-file",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"url",
|
||||
"uv-cache",
|
||||
"uv-client",
|
||||
"uv-extract",
|
||||
"uv-fs",
|
||||
"uv-toolchain",
|
||||
"uv-warnings",
|
||||
"which",
|
||||
"winapi",
|
||||
|
|
@ -5007,30 +5012,6 @@ dependencies = [
|
|||
"uv-warnings",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uv-toolchain"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"fs-err",
|
||||
"futures",
|
||||
"once_cell",
|
||||
"pep440_rs",
|
||||
"pep508_rs",
|
||||
"reqwest",
|
||||
"reqwest-middleware",
|
||||
"schemars",
|
||||
"serde",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"url",
|
||||
"uv-client",
|
||||
"uv-extract",
|
||||
"uv-fs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uv-types"
|
||||
version = "0.0.1"
|
||||
|
|
@ -5100,9 +5081,9 @@ dependencies = [
|
|||
"tracing",
|
||||
"uv-configuration",
|
||||
"uv-fs",
|
||||
"uv-interpreter",
|
||||
"uv-normalize",
|
||||
"uv-resolver",
|
||||
"uv-toolchain",
|
||||
"uv-warnings",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ uv-interpreter = { path = "crates/uv-interpreter" }
|
|||
uv-normalize = { path = "crates/uv-normalize" }
|
||||
uv-requirements = { path = "crates/uv-requirements" }
|
||||
uv-resolver = { path = "crates/uv-resolver" }
|
||||
uv-toolchain = { path = "crates/uv-toolchain" }
|
||||
uv-types = { path = "crates/uv-types" }
|
||||
uv-version = { path = "crates/uv-version" }
|
||||
uv-virtualenv = { path = "crates/uv-virtualenv" }
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ uv-installer = { workspace = true }
|
|||
uv-interpreter = { workspace = true }
|
||||
uv-normalize = { workspace = true }
|
||||
uv-resolver = { workspace = true }
|
||||
uv-toolchain = { workspace = true }
|
||||
uv-types = { workspace = true }
|
||||
uv-workspace = { workspace = true, features = ["schemars"] }
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use tokio::time::Instant;
|
|||
use tracing::{info, info_span, Instrument};
|
||||
|
||||
use uv_fs::Simplified;
|
||||
use uv_toolchain::{
|
||||
use uv_interpreter::managed::{
|
||||
DownloadResult, Error, PythonDownload, PythonDownloadRequest, TOOLCHAIN_DIRECTORY,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -16,26 +16,34 @@ workspace = true
|
|||
cache-key = { workspace = true }
|
||||
install-wheel-rs = { workspace = true }
|
||||
pep440_rs = { workspace = true }
|
||||
pep508_rs = { workspace = true, features = ["serde"] }
|
||||
pep508_rs = { workspace = true, features = ["serde", "non-pep508-extensions"] }
|
||||
platform-tags = { workspace = true }
|
||||
pypi-types = { workspace = true }
|
||||
uv-cache = { workspace = true }
|
||||
uv-client = { workspace = true }
|
||||
uv-extract = { workspace = true }
|
||||
uv-fs = { workspace = true }
|
||||
uv-toolchain = { workspace = true }
|
||||
uv-warnings = { workspace = true }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
configparser = { workspace = true }
|
||||
fs-err = { workspace = true, features = ["tokio"] }
|
||||
itertools = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
once_cell = { workspace = true }
|
||||
regex = { workspace = true }
|
||||
reqwest = { workspace = true }
|
||||
reqwest-middleware = { workspace = true }
|
||||
rmp-serde = { workspace = true }
|
||||
same-file = { workspace = true }
|
||||
schemars = { workspace = true, optional = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json = { workspace = true }
|
||||
tempfile = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tokio-util = { workspace = true, features = ["compat"] }
|
||||
tracing = { workspace = true }
|
||||
url = { workspace = true }
|
||||
which = { workspace = true }
|
||||
|
||||
[target.'cfg(target_os = "windows")'.dependencies]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
pub(crate) mod cfg;
|
||||
pub(crate) mod python_environment;
|
||||
pub(crate) mod virtualenv;
|
||||
|
|
@ -8,7 +8,7 @@ use tracing::{debug, info};
|
|||
use uv_cache::Cache;
|
||||
use uv_fs::{LockedFile, Simplified};
|
||||
|
||||
use crate::cfg::PyVenvConfiguration;
|
||||
use crate::environment::cfg::PyVenvConfiguration;
|
||||
use crate::{find_default_python, find_requested_python, Error, Interpreter, Target};
|
||||
|
||||
/// A Python environment, consisting of a Python [`Interpreter`] and its associated paths.
|
||||
|
|
@ -6,11 +6,11 @@ use std::path::PathBuf;
|
|||
use tracing::{debug, instrument};
|
||||
|
||||
use uv_cache::Cache;
|
||||
use uv_toolchain::PythonVersion;
|
||||
use uv_warnings::warn_user_once;
|
||||
|
||||
use crate::environment::python_environment::{detect_python_executable, detect_virtual_env};
|
||||
use crate::interpreter::InterpreterInfoError;
|
||||
use crate::python_environment::{detect_python_executable, detect_virtual_env};
|
||||
use crate::PythonVersion;
|
||||
use crate::{Error, Interpreter};
|
||||
|
||||
/// Find a Python of a specific version, a binary with a name or a path to a binary.
|
||||
|
|
|
|||
|
|
@ -16,10 +16,8 @@ use platform_tags::{Tags, TagsError};
|
|||
use pypi_types::Scheme;
|
||||
use uv_cache::{Cache, CacheBucket, CachedByTimestamp, Freshness, Timestamp};
|
||||
use uv_fs::{write_atomic_sync, PythonExt, Simplified};
|
||||
use uv_toolchain::PythonVersion;
|
||||
|
||||
use crate::Virtualenv;
|
||||
use crate::{Error, Target};
|
||||
use crate::{Error, PythonVersion, Target, Virtualenv};
|
||||
|
||||
/// A Python executable and its associated platform markers.
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
|
|||
|
|
@ -14,20 +14,22 @@ use std::process::ExitStatus;
|
|||
|
||||
use thiserror::Error;
|
||||
|
||||
pub use crate::cfg::PyVenvConfiguration;
|
||||
pub use crate::environment::cfg::PyVenvConfiguration;
|
||||
pub use crate::environment::python_environment::PythonEnvironment;
|
||||
pub use crate::environment::virtualenv::Virtualenv;
|
||||
pub use crate::find_python::{find_best_python, find_default_python, find_requested_python};
|
||||
pub use crate::interpreter::Interpreter;
|
||||
use crate::interpreter::InterpreterInfoError;
|
||||
pub use crate::python_environment::PythonEnvironment;
|
||||
pub use crate::python_version::PythonVersion;
|
||||
pub use crate::target::Target;
|
||||
pub use crate::virtualenv::Virtualenv;
|
||||
|
||||
mod cfg;
|
||||
mod environment;
|
||||
mod find_python;
|
||||
mod interpreter;
|
||||
mod python_environment;
|
||||
pub mod managed;
|
||||
mod python_version;
|
||||
pub mod selectors;
|
||||
mod target;
|
||||
mod virtualenv;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum Error {
|
||||
|
|
@ -73,7 +75,7 @@ pub enum Error {
|
|||
#[error("Failed to write to cache")]
|
||||
Encode(#[from] rmp_serde::encode::Error),
|
||||
#[error("Broken virtualenv: Failed to parse pyvenv.cfg")]
|
||||
Cfg(#[from] cfg::Error),
|
||||
Cfg(#[from] environment::cfg::Error),
|
||||
#[error("Error finding `{}` in PATH", _0.to_string_lossy())]
|
||||
WhichError(OsString, #[source] which::Error),
|
||||
#[error("Can't use Python at `{interpreter}`")]
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use std::fmt::{self, Display};
|
||||
use std::fmt::Display;
|
||||
use std::io;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::selectors::{Arch, ImplementationName, Libc, Os, PythonSelectorError};
|
||||
use crate::PythonVersion;
|
||||
use thiserror::Error;
|
||||
use uv_client::BetterReqwestError;
|
||||
|
|
@ -16,12 +17,8 @@ use uv_fs::Simplified;
|
|||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error {
|
||||
#[error("operating system not supported: {0}")]
|
||||
OsNotSupported(String),
|
||||
#[error("architecture not supported: {0}")]
|
||||
ArchNotSupported(String),
|
||||
#[error("libc type could not be detected")]
|
||||
LibcNotDetected(),
|
||||
#[error(transparent)]
|
||||
SelectorError(#[from] PythonSelectorError),
|
||||
#[error("invalid python version: {0}")]
|
||||
InvalidPythonVersion(String),
|
||||
#[error("download failed")]
|
||||
|
|
@ -139,24 +136,6 @@ impl FromStr for PythonDownloadRequest {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum Libc {
|
||||
Gnu,
|
||||
Musl,
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum ImplementationName {
|
||||
Cpython,
|
||||
}
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub struct Platform {
|
||||
os: Os,
|
||||
arch: Arch,
|
||||
libc: Libc,
|
||||
}
|
||||
|
||||
include!("python_versions.inc");
|
||||
|
||||
pub enum DownloadResult {
|
||||
|
|
@ -273,147 +252,6 @@ impl PythonDownload {
|
|||
}
|
||||
}
|
||||
|
||||
impl Platform {
|
||||
pub fn new(os: Os, arch: Arch, libc: Libc) -> Self {
|
||||
Self { os, arch, libc }
|
||||
}
|
||||
pub fn from_env() -> Result<Self, Error> {
|
||||
Ok(Self::new(
|
||||
Os::from_env()?,
|
||||
Arch::from_env()?,
|
||||
Libc::from_env()?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// All supported operating systems.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum Os {
|
||||
Windows,
|
||||
Linux,
|
||||
Macos,
|
||||
FreeBsd,
|
||||
NetBsd,
|
||||
OpenBsd,
|
||||
Dragonfly,
|
||||
Illumos,
|
||||
Haiku,
|
||||
}
|
||||
|
||||
impl fmt::Display for Os {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Self::Windows => write!(f, "Windows"),
|
||||
Self::Macos => write!(f, "MacOS"),
|
||||
Self::FreeBsd => write!(f, "FreeBSD"),
|
||||
Self::NetBsd => write!(f, "NetBSD"),
|
||||
Self::Linux => write!(f, "Linux"),
|
||||
Self::OpenBsd => write!(f, "OpenBSD"),
|
||||
Self::Dragonfly => write!(f, "DragonFly"),
|
||||
Self::Illumos => write!(f, "Illumos"),
|
||||
Self::Haiku => write!(f, "Haiku"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Os {
|
||||
pub(crate) fn from_env() -> Result<Self, Error> {
|
||||
Self::from_str(std::env::consts::OS)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Os {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_str() {
|
||||
"windows" => Ok(Self::Windows),
|
||||
"linux" => Ok(Self::Linux),
|
||||
"macos" => Ok(Self::Macos),
|
||||
"freebsd" => Ok(Self::FreeBsd),
|
||||
"netbsd" => Ok(Self::NetBsd),
|
||||
"openbsd" => Ok(Self::OpenBsd),
|
||||
"dragonfly" => Ok(Self::Dragonfly),
|
||||
"illumos" => Ok(Self::Illumos),
|
||||
"haiku" => Ok(Self::Haiku),
|
||||
_ => Err(Error::OsNotSupported(s.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// All supported CPU architectures
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum Arch {
|
||||
Aarch64,
|
||||
Armv6L,
|
||||
Armv7L,
|
||||
Powerpc64Le,
|
||||
Powerpc64,
|
||||
X86,
|
||||
X86_64,
|
||||
S390X,
|
||||
}
|
||||
|
||||
impl fmt::Display for Arch {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Self::Aarch64 => write!(f, "aarch64"),
|
||||
Self::Armv6L => write!(f, "armv6l"),
|
||||
Self::Armv7L => write!(f, "armv7l"),
|
||||
Self::Powerpc64Le => write!(f, "ppc64le"),
|
||||
Self::Powerpc64 => write!(f, "ppc64"),
|
||||
Self::X86 => write!(f, "i686"),
|
||||
Self::X86_64 => write!(f, "x86_64"),
|
||||
Self::S390X => write!(f, "s390x"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Arch {
|
||||
type Err = Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_str() {
|
||||
"aarch64" | "arm64" => Ok(Self::Aarch64),
|
||||
"armv6l" => Ok(Self::Armv6L),
|
||||
"armv7l" => Ok(Self::Armv7L),
|
||||
"powerpc64le" | "ppc64le" => Ok(Self::Powerpc64Le),
|
||||
"powerpc64" | "ppc64" => Ok(Self::Powerpc64),
|
||||
"x86" | "i686" | "i386" => Ok(Self::X86),
|
||||
"x86_64" | "amd64" => Ok(Self::X86_64),
|
||||
"s390x" => Ok(Self::S390X),
|
||||
_ => Err(Error::ArchNotSupported(s.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Arch {
|
||||
pub(crate) fn from_env() -> Result<Self, Error> {
|
||||
Self::from_str(std::env::consts::ARCH)
|
||||
}
|
||||
}
|
||||
|
||||
impl Libc {
|
||||
pub(crate) fn from_env() -> Result<Self, Error> {
|
||||
// TODO(zanieb): Perform this lookup
|
||||
match std::env::consts::OS {
|
||||
"linux" => Ok(Libc::Gnu),
|
||||
"windows" | "macos" => Ok(Libc::None),
|
||||
_ => Err(Error::LibcNotDetected()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Libc {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Libc::Gnu => f.write_str("gnu"),
|
||||
Libc::None => f.write_str("none"),
|
||||
Libc::Musl => f.write_str("musl"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<reqwest::Error> for Error {
|
||||
fn from(error: reqwest::Error) -> Self {
|
||||
Self::NetworkError(BetterReqwestError::from(error))
|
||||
|
|
@ -2,8 +2,9 @@ use std::collections::BTreeSet;
|
|||
use std::ffi::OsStr;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::downloads::{Arch, Error, Libc, Os};
|
||||
use crate::managed::downloads::Error;
|
||||
use crate::python_version::PythonVersion;
|
||||
use crate::selectors::{Arch, Libc, Os};
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
pub use crate::managed::downloads::{DownloadResult, Error, PythonDownload, PythonDownloadRequest};
|
||||
pub use crate::managed::find::{toolchains_for_version, Toolchain, TOOLCHAIN_DIRECTORY};
|
||||
|
||||
mod downloads;
|
||||
mod find;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// DO NOT EDIT
|
||||
//
|
||||
// Generated with `crates/uv-toolchain/template-version-metadata.py`
|
||||
// From template at `crates/uv-toolchain/src/python_versions.inc.mustache`
|
||||
// Generated with `crates/uv-interpreter/template-version-metadata.py`
|
||||
// From template at `crates/uv-interpreter/src/python_versions.inc.mustache`
|
||||
|
||||
pub(crate) const PYTHON_DOWNLOADS: &[PythonDownload] = &[
|
||||
PythonDownload {
|
||||
|
|
@ -5,7 +5,7 @@ use std::str::FromStr;
|
|||
use pep440_rs::Version;
|
||||
use pep508_rs::{MarkerEnvironment, StringVersion};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct PythonVersion(StringVersion);
|
||||
|
||||
impl Deref for PythonVersion {
|
||||
|
|
@ -20,21 +20,22 @@ impl FromStr for PythonVersion {
|
|||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let version = StringVersion::from_str(s)?;
|
||||
let version = StringVersion::from_str(s)
|
||||
.map_err(|err| format!("Python version `{s}` could not be parsed: {err}"))?;
|
||||
if version.is_dev() {
|
||||
return Err(format!("Python version {s} is a development release"));
|
||||
return Err(format!("Python version `{s}` is a development release"));
|
||||
}
|
||||
if version.is_local() {
|
||||
return Err(format!("Python version {s} is a local version"));
|
||||
return Err(format!("Python version `{s}` is a local version"));
|
||||
}
|
||||
if version.epoch() != 0 {
|
||||
return Err(format!("Python version {s} has a non-zero epoch"));
|
||||
return Err(format!("Python version `{s}` has a non-zero epoch"));
|
||||
}
|
||||
if version.version < Version::new([3, 7]) {
|
||||
return Err(format!("Python version {s} must be >= 3.7"));
|
||||
return Err(format!("Python version `{s}` must be >= 3.7"));
|
||||
}
|
||||
if version.version >= Version::new([4, 0]) {
|
||||
return Err(format!("Python version {s} must be < 4.0"));
|
||||
return Err(format!("Python version `{s}` must be < 4.0"));
|
||||
}
|
||||
|
||||
Ok(Self(version))
|
||||
|
|
@ -52,7 +53,6 @@ impl schemars::JsonSchema for PythonVersion {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> serde::Deserialize<'de> for PythonVersion {
|
||||
fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
|
||||
let s = String::deserialize(deserializer)?;
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
use std::{
|
||||
fmt::{self, Display},
|
||||
str::FromStr,
|
||||
};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
||||
pub enum ImplementationName {
|
||||
Cpython,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Platform {
|
||||
os: Os,
|
||||
arch: Arch,
|
||||
libc: Libc,
|
||||
}
|
||||
|
||||
/// All supported operating systems.
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum Os {
|
||||
Windows,
|
||||
Linux,
|
||||
Macos,
|
||||
FreeBsd,
|
||||
NetBsd,
|
||||
OpenBsd,
|
||||
Dragonfly,
|
||||
Illumos,
|
||||
Haiku,
|
||||
}
|
||||
|
||||
/// All supported CPU architectures
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub enum Arch {
|
||||
Aarch64,
|
||||
Armv6L,
|
||||
Armv7L,
|
||||
Powerpc64Le,
|
||||
Powerpc64,
|
||||
X86,
|
||||
X86_64,
|
||||
S390X,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
||||
pub enum Libc {
|
||||
Gnu,
|
||||
Musl,
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Error, Debug)]
|
||||
pub enum PythonSelectorError {
|
||||
#[error("Operating system not supported: {0}")]
|
||||
OsNotSupported(String),
|
||||
#[error("Architecture not supported: {0}")]
|
||||
ArchNotSupported(String),
|
||||
#[error("Libc type could not be detected")]
|
||||
LibcNotDetected(),
|
||||
#[error("Implementation not supported: {0}")]
|
||||
ImplementationNotSupported(String),
|
||||
}
|
||||
|
||||
impl ImplementationName {
|
||||
pub fn as_str(&self) -> &str {
|
||||
match self {
|
||||
Self::Cpython => "cpython",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for ImplementationName {
|
||||
type Err = PythonSelectorError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s {
|
||||
"cpython" => Ok(Self::Cpython),
|
||||
_ => Err(PythonSelectorError::ImplementationNotSupported(
|
||||
s.to_string(),
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for ImplementationName {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl Platform {
|
||||
pub fn new(os: Os, arch: Arch, libc: Libc) -> Self {
|
||||
Self { os, arch, libc }
|
||||
}
|
||||
pub fn from_env() -> Result<Self, PythonSelectorError> {
|
||||
Ok(Self::new(
|
||||
Os::from_env()?,
|
||||
Arch::from_env()?,
|
||||
Libc::from_env()?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Os {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Self::Windows => write!(f, "Windows"),
|
||||
Self::Macos => write!(f, "MacOS"),
|
||||
Self::FreeBsd => write!(f, "FreeBSD"),
|
||||
Self::NetBsd => write!(f, "NetBSD"),
|
||||
Self::Linux => write!(f, "Linux"),
|
||||
Self::OpenBsd => write!(f, "OpenBSD"),
|
||||
Self::Dragonfly => write!(f, "DragonFly"),
|
||||
Self::Illumos => write!(f, "Illumos"),
|
||||
Self::Haiku => write!(f, "Haiku"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Os {
|
||||
pub(crate) fn from_env() -> Result<Self, PythonSelectorError> {
|
||||
Self::from_str(std::env::consts::OS)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Os {
|
||||
type Err = PythonSelectorError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_str() {
|
||||
"windows" => Ok(Self::Windows),
|
||||
"linux" => Ok(Self::Linux),
|
||||
"macos" => Ok(Self::Macos),
|
||||
"freebsd" => Ok(Self::FreeBsd),
|
||||
"netbsd" => Ok(Self::NetBsd),
|
||||
"openbsd" => Ok(Self::OpenBsd),
|
||||
"dragonfly" => Ok(Self::Dragonfly),
|
||||
"illumos" => Ok(Self::Illumos),
|
||||
"haiku" => Ok(Self::Haiku),
|
||||
_ => Err(PythonSelectorError::OsNotSupported(s.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Arch {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Self::Aarch64 => write!(f, "aarch64"),
|
||||
Self::Armv6L => write!(f, "armv6l"),
|
||||
Self::Armv7L => write!(f, "armv7l"),
|
||||
Self::Powerpc64Le => write!(f, "ppc64le"),
|
||||
Self::Powerpc64 => write!(f, "ppc64"),
|
||||
Self::X86 => write!(f, "i686"),
|
||||
Self::X86_64 => write!(f, "x86_64"),
|
||||
Self::S390X => write!(f, "s390x"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Arch {
|
||||
type Err = PythonSelectorError;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
match s.to_lowercase().as_str() {
|
||||
"aarch64" | "arm64" => Ok(Self::Aarch64),
|
||||
"armv6l" => Ok(Self::Armv6L),
|
||||
"armv7l" => Ok(Self::Armv7L),
|
||||
"powerpc64le" | "ppc64le" => Ok(Self::Powerpc64Le),
|
||||
"powerpc64" | "ppc64" => Ok(Self::Powerpc64),
|
||||
"x86" | "i686" | "i386" => Ok(Self::X86),
|
||||
"x86_64" | "amd64" => Ok(Self::X86_64),
|
||||
"s390x" => Ok(Self::S390X),
|
||||
_ => Err(PythonSelectorError::ArchNotSupported(s.to_string())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Arch {
|
||||
pub(crate) fn from_env() -> Result<Self, PythonSelectorError> {
|
||||
Self::from_str(std::env::consts::ARCH)
|
||||
}
|
||||
}
|
||||
|
||||
impl Libc {
|
||||
pub(crate) fn from_env() -> Result<Self, PythonSelectorError> {
|
||||
// TODO(zanieb): Perform this lookup
|
||||
match std::env::consts::OS {
|
||||
"linux" => Ok(Libc::Gnu),
|
||||
"windows" | "macos" => Ok(Libc::None),
|
||||
_ => Err(PythonSelectorError::LibcNotDetected()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Libc {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Libc::Gnu => f.write_str("gnu"),
|
||||
Libc::None => f.write_str("none"),
|
||||
Libc::Musl => f.write_str("musl"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,7 +19,7 @@ from pathlib import Path
|
|||
CRATE_ROOT = Path(__file__).parent
|
||||
WORKSPACE_ROOT = CRATE_ROOT.parent.parent
|
||||
VERSION_METADATA = CRATE_ROOT / "python-version-metadata.json"
|
||||
TEMPLATE = CRATE_ROOT / "src" / "python_versions.inc.mustache"
|
||||
TEMPLATE = CRATE_ROOT / "src" / "managed" / "python_versions.inc.mustache"
|
||||
TARGET = TEMPLATE.with_suffix("")
|
||||
|
||||
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
[package]
|
||||
name = "uv-toolchain"
|
||||
version = "0.1.0"
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
homepage.workspace = true
|
||||
documentation.workspace = true
|
||||
repository.workspace = true
|
||||
authors.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
pep440_rs = { workspace = true }
|
||||
pep508_rs = { workspace = true, features = ["non-pep508-extensions"] }
|
||||
uv-client = { workspace = true }
|
||||
uv-extract = { workspace = true }
|
||||
uv-fs = { workspace = true }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
fs-err = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
once_cell = {workspace = true}
|
||||
reqwest = { workspace = true }
|
||||
reqwest-middleware = { workspace = true }
|
||||
schemars = { workspace = true, optional = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
tempfile = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
tokio-util = { workspace = true, features = ["compat"] }
|
||||
tracing = { workspace = true }
|
||||
url = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
pub use crate::downloads::{
|
||||
DownloadResult, Error, Platform, PythonDownload, PythonDownloadRequest,
|
||||
};
|
||||
pub use crate::find::{toolchains_for_version, Toolchain, TOOLCHAIN_DIRECTORY};
|
||||
pub use crate::python_version::PythonVersion;
|
||||
|
||||
mod downloads;
|
||||
mod find;
|
||||
mod python_version;
|
||||
|
|
@ -19,7 +19,7 @@ uv-configuration = { workspace = true, features = ["schemars", "serde"] }
|
|||
uv-fs = { workspace = true }
|
||||
uv-normalize = { workspace = true, features = ["schemars"] }
|
||||
uv-resolver = { workspace = true, features = ["schemars", "serde"] }
|
||||
uv-toolchain = { workspace = true, features = ["schemars", "serde"] }
|
||||
uv-interpreter = { workspace = true, features = ["schemars"] }
|
||||
uv-warnings = { workspace = true }
|
||||
|
||||
dirs-sys = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ use install_wheel_rs::linker::LinkMode;
|
|||
use uv_configuration::{
|
||||
ConfigSettings, IndexStrategy, KeyringProviderType, PackageNameSpecifier, TargetTriple,
|
||||
};
|
||||
use uv_interpreter::PythonVersion;
|
||||
use uv_normalize::{ExtraName, PackageName};
|
||||
use uv_resolver::{AnnotationStyle, ExcludeNewer, PreReleaseMode, ResolutionMode};
|
||||
use uv_toolchain::PythonVersion;
|
||||
|
||||
/// A `pyproject.toml` with an (optional) `[tool.uv]` section.
|
||||
#[allow(dead_code)]
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ uv-interpreter = { workspace = true }
|
|||
uv-normalize = { workspace = true }
|
||||
uv-requirements = { workspace = true }
|
||||
uv-resolver = { workspace = true, features = ["clap"] }
|
||||
uv-toolchain = { workspace = true }
|
||||
uv-types = { workspace = true }
|
||||
uv-virtualenv = { workspace = true }
|
||||
uv-warnings = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ use uv_cache::CacheArgs;
|
|||
use uv_configuration::{
|
||||
ConfigSettingEntry, IndexStrategy, KeyringProviderType, PackageNameSpecifier, TargetTriple,
|
||||
};
|
||||
use uv_interpreter::PythonVersion;
|
||||
use uv_normalize::{ExtraName, PackageName};
|
||||
use uv_resolver::{AnnotationStyle, ExcludeNewer, PreReleaseMode, ResolutionMode};
|
||||
use uv_toolchain::PythonVersion;
|
||||
|
||||
use crate::commands::{extra_name_with_clap_error, ListFormat, VersionFormat};
|
||||
use crate::compat;
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ use uv_configuration::{KeyringProviderType, TargetTriple};
|
|||
use uv_dispatch::BuildDispatch;
|
||||
use uv_fs::Simplified;
|
||||
use uv_installer::Downloader;
|
||||
use uv_interpreter::PythonVersion;
|
||||
use uv_interpreter::{find_best_python, find_requested_python, PythonEnvironment};
|
||||
use uv_normalize::{ExtraName, PackageName};
|
||||
use uv_requirements::{
|
||||
|
|
@ -40,7 +41,6 @@ use uv_resolver::{
|
|||
InMemoryIndex, Manifest, OptionsBuilder, PreReleaseMode, PythonRequirement, ResolutionMode,
|
||||
Resolver,
|
||||
};
|
||||
use uv_toolchain::PythonVersion;
|
||||
use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy, InFlight};
|
||||
use uv_warnings::warn_user;
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ use uv_fs::Simplified;
|
|||
use uv_installer::{
|
||||
BuiltEditable, Downloader, Plan, Planner, ResolvedEditable, SatisfiesResult, SitePackages,
|
||||
};
|
||||
use uv_interpreter::{Interpreter, PythonEnvironment, Target};
|
||||
use uv_interpreter::{Interpreter, PythonEnvironment, PythonVersion, Target};
|
||||
use uv_normalize::PackageName;
|
||||
use uv_requirements::{
|
||||
ExtrasSpecification, LookaheadResolver, NamedRequirementsResolver, RequirementsSource,
|
||||
|
|
@ -43,7 +43,6 @@ use uv_resolver::{
|
|||
DependencyMode, ExcludeNewer, Exclusions, FlatIndex, InMemoryIndex, Manifest, Options,
|
||||
OptionsBuilder, PreReleaseMode, Preference, ResolutionGraph, ResolutionMode, Resolver,
|
||||
};
|
||||
use uv_toolchain::PythonVersion;
|
||||
use uv_types::{BuildIsolation, HashStrategy, InFlight};
|
||||
use uv_warnings::warn_user;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,13 +26,12 @@ use uv_configuration::{KeyringProviderType, TargetTriple};
|
|||
use uv_dispatch::BuildDispatch;
|
||||
use uv_fs::Simplified;
|
||||
use uv_installer::{is_dynamic, Downloader, Plan, Planner, ResolvedEditable, SitePackages};
|
||||
use uv_interpreter::{Interpreter, PythonEnvironment, Target};
|
||||
use uv_interpreter::{Interpreter, PythonEnvironment, PythonVersion, Target};
|
||||
use uv_requirements::{
|
||||
ExtrasSpecification, NamedRequirementsResolver, RequirementsSource, RequirementsSpecification,
|
||||
SourceTreeResolver,
|
||||
};
|
||||
use uv_resolver::{DependencyMode, FlatIndex, InMemoryIndex, Manifest, OptionsBuilder, Resolver};
|
||||
use uv_toolchain::PythonVersion;
|
||||
use uv_types::{BuildIsolation, EmptyInstalledPackages, HashStrategy, InFlight};
|
||||
use uv_warnings::warn_user;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,11 +9,10 @@ use uv_configuration::{
|
|||
ConfigSettings, IndexStrategy, KeyringProviderType, NoBinary, NoBuild, PreviewMode, Reinstall,
|
||||
SetupPyStrategy, TargetTriple, Upgrade,
|
||||
};
|
||||
use uv_interpreter::Target;
|
||||
use uv_interpreter::{PythonVersion, Target};
|
||||
use uv_normalize::PackageName;
|
||||
use uv_requirements::ExtrasSpecification;
|
||||
use uv_resolver::{AnnotationStyle, DependencyMode, ExcludeNewer, PreReleaseMode, ResolutionMode};
|
||||
use uv_toolchain::PythonVersion;
|
||||
use uv_workspace::{PipOptions, Workspace};
|
||||
|
||||
use crate::cli::{
|
||||
|
|
|
|||
|
|
@ -13,11 +13,10 @@ use std::ffi::OsString;
|
|||
use std::path::{Path, PathBuf};
|
||||
use std::process::Output;
|
||||
use std::str::FromStr;
|
||||
use uv_interpreter::find_requested_python;
|
||||
|
||||
use uv_cache::Cache;
|
||||
use uv_fs::Simplified;
|
||||
use uv_toolchain::{toolchains_for_version, PythonVersion};
|
||||
use uv_interpreter::managed::toolchains_for_version;
|
||||
use uv_interpreter::{find_requested_python, PythonVersion};
|
||||
|
||||
// Exclude any packages uploaded after this date.
|
||||
pub static EXCLUDE_NEWER: &str = "2024-03-25T00:00:00Z";
|
||||
|
|
@ -341,7 +340,7 @@ pub fn create_venv<Parent: assert_fs::prelude::PathChild + AsRef<std::path::Path
|
|||
)
|
||||
.expect("Tests are run on a supported platform")
|
||||
.first()
|
||||
.map(uv_toolchain::Toolchain::executable)
|
||||
.map(uv_interpreter::managed::Toolchain::executable)
|
||||
// We'll search for the request Python on the PATH if not found in the toolchain versions
|
||||
// We hack this into a `PathBuf` to satisfy the compiler but it's just a string
|
||||
.unwrap_or(PathBuf::from(python));
|
||||
|
|
|
|||
|
|
@ -984,7 +984,7 @@ fn compile_python_invalid_version() -> Result<()> {
|
|||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: invalid value '3.7.x' for '--python-version <PYTHON_VERSION>': after parsing '3.7', found '.x', which is not part of a valid version
|
||||
error: invalid value '3.7.x' for '--python-version <PYTHON_VERSION>': Python version `3.7.x` could not be parsed: after parsing '3.7', found '.x', which is not part of a valid version
|
||||
|
||||
For more information, try '--help'.
|
||||
"###
|
||||
|
|
@ -1009,7 +1009,7 @@ fn compile_python_dev_version() -> Result<()> {
|
|||
----- stdout -----
|
||||
|
||||
----- stderr -----
|
||||
error: invalid value '3.7-dev' for '--python-version <PYTHON_VERSION>': Python version 3.7-dev is a development release
|
||||
error: invalid value '3.7-dev' for '--python-version <PYTHON_VERSION>': Python version `3.7-dev` is a development release
|
||||
|
||||
For more information, try '--help'.
|
||||
"###
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ use assert_fs::fixture::ChildPath;
|
|||
use assert_fs::prelude::*;
|
||||
use fs_err::PathExt;
|
||||
use uv_fs::Simplified;
|
||||
use uv_toolchain::PythonVersion;
|
||||
use uv_interpreter::PythonVersion;
|
||||
|
||||
use crate::common::{get_bin, python_path_with_versions, uv_snapshot, TestContext, EXCLUDE_NEWER};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue