mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-02 06:51:14 +00:00
Separate interpreter selectors into implementation
and platform
modules (#3332)
Split out of #3266 The "selector" concept doesn't seem well enough defined as-is. For example, `PythonVersion` belongs there but isn't present. Going for smaller modules instead.
This commit is contained in:
parent
5048ccef3a
commit
c28a2806b3
5 changed files with 69 additions and 50 deletions
47
crates/uv-interpreter/src/implementation.rs
Normal file
47
crates/uv-interpreter/src/implementation.rs
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
use std::{
|
||||||
|
fmt::{self, Display},
|
||||||
|
str::FromStr,
|
||||||
|
};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Unknown Python implementation `{0}`")]
|
||||||
|
UnknownImplementation(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
||||||
|
pub enum ImplementationName {
|
||||||
|
Cpython,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ImplementationName {
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub(crate) fn iter() -> impl Iterator<Item = &'static ImplementationName> {
|
||||||
|
static NAMES: &[ImplementationName] = &[ImplementationName::Cpython];
|
||||||
|
NAMES.iter()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
match self {
|
||||||
|
Self::Cpython => "cpython",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromStr for ImplementationName {
|
||||||
|
type Err = Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
|
match s.to_ascii_lowercase().as_str() {
|
||||||
|
"cpython" => Ok(Self::Cpython),
|
||||||
|
_ => Err(Error::UnknownImplementation(s.to_string())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for ImplementationName {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.write_str(self.as_str())
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,11 +25,12 @@ pub use crate::target::Target;
|
||||||
|
|
||||||
mod environment;
|
mod environment;
|
||||||
mod find_python;
|
mod find_python;
|
||||||
|
mod implementation;
|
||||||
mod interpreter;
|
mod interpreter;
|
||||||
pub mod managed;
|
pub mod managed;
|
||||||
|
pub mod platform;
|
||||||
mod py_launcher;
|
mod py_launcher;
|
||||||
mod python_version;
|
mod python_version;
|
||||||
pub mod selectors;
|
|
||||||
mod target;
|
mod target;
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
|
|
|
@ -3,7 +3,8 @@ use std::io;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use crate::selectors::{Arch, ImplementationName, Libc, Os, PythonSelectorError};
|
use crate::implementation::{Error as ImplementationError, ImplementationName};
|
||||||
|
use crate::platform::{Arch, Error as PlatformError, Libc, Os};
|
||||||
use crate::PythonVersion;
|
use crate::PythonVersion;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use uv_client::BetterReqwestError;
|
use uv_client::BetterReqwestError;
|
||||||
|
@ -18,7 +19,9 @@ use uv_fs::Simplified;
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error(transparent)]
|
#[error(transparent)]
|
||||||
SelectorError(#[from] PythonSelectorError),
|
PlatformError(#[from] PlatformError),
|
||||||
|
#[error(transparent)]
|
||||||
|
ImplementationError(#[from] ImplementationError),
|
||||||
#[error("invalid python version: {0}")]
|
#[error("invalid python version: {0}")]
|
||||||
InvalidPythonVersion(String),
|
InvalidPythonVersion(String),
|
||||||
#[error("download failed")]
|
#[error("download failed")]
|
||||||
|
|
|
@ -3,8 +3,10 @@ use std::ffi::OsStr;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use crate::managed::downloads::Error;
|
use crate::managed::downloads::Error;
|
||||||
use crate::python_version::PythonVersion;
|
use crate::{
|
||||||
use crate::selectors::{Arch, Libc, Os};
|
platform::{Arch, Libc, Os},
|
||||||
|
python_version::PythonVersion,
|
||||||
|
};
|
||||||
|
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,9 @@
|
||||||
use std::{
|
use std::{
|
||||||
fmt::{self, Display},
|
fmt::{self},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
};
|
};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq, Clone, Copy)]
|
|
||||||
pub enum ImplementationName {
|
|
||||||
Cpython,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Platform {
|
pub struct Platform {
|
||||||
os: Os,
|
os: Os,
|
||||||
|
@ -51,49 +46,20 @@ pub enum Libc {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum PythonSelectorError {
|
pub enum Error {
|
||||||
#[error("Operating system not supported: {0}")]
|
#[error("Operating system not supported: {0}")]
|
||||||
OsNotSupported(String),
|
OsNotSupported(String),
|
||||||
#[error("Architecture not supported: {0}")]
|
#[error("Architecture not supported: {0}")]
|
||||||
ArchNotSupported(String),
|
ArchNotSupported(String),
|
||||||
#[error("Libc type could not be detected")]
|
#[error("Libc type could not be detected")]
|
||||||
LibcNotDetected(),
|
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 {
|
impl Platform {
|
||||||
pub fn new(os: Os, arch: Arch, libc: Libc) -> Self {
|
pub fn new(os: Os, arch: Arch, libc: Libc) -> Self {
|
||||||
Self { os, arch, libc }
|
Self { os, arch, libc }
|
||||||
}
|
}
|
||||||
pub fn from_env() -> Result<Self, PythonSelectorError> {
|
pub fn from_env() -> Result<Self, Error> {
|
||||||
Ok(Self::new(
|
Ok(Self::new(
|
||||||
Os::from_env()?,
|
Os::from_env()?,
|
||||||
Arch::from_env()?,
|
Arch::from_env()?,
|
||||||
|
@ -119,13 +85,13 @@ impl fmt::Display for Os {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Os {
|
impl Os {
|
||||||
pub(crate) fn from_env() -> Result<Self, PythonSelectorError> {
|
pub(crate) fn from_env() -> Result<Self, Error> {
|
||||||
Self::from_str(std::env::consts::OS)
|
Self::from_str(std::env::consts::OS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Os {
|
impl FromStr for Os {
|
||||||
type Err = PythonSelectorError;
|
type Err = Error;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
match s.to_lowercase().as_str() {
|
match s.to_lowercase().as_str() {
|
||||||
|
@ -138,7 +104,7 @@ impl FromStr for Os {
|
||||||
"dragonfly" => Ok(Self::Dragonfly),
|
"dragonfly" => Ok(Self::Dragonfly),
|
||||||
"illumos" => Ok(Self::Illumos),
|
"illumos" => Ok(Self::Illumos),
|
||||||
"haiku" => Ok(Self::Haiku),
|
"haiku" => Ok(Self::Haiku),
|
||||||
_ => Err(PythonSelectorError::OsNotSupported(s.to_string())),
|
_ => Err(Error::OsNotSupported(s.to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +125,7 @@ impl fmt::Display for Arch {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for Arch {
|
impl FromStr for Arch {
|
||||||
type Err = PythonSelectorError;
|
type Err = Error;
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
match s.to_lowercase().as_str() {
|
match s.to_lowercase().as_str() {
|
||||||
|
@ -171,24 +137,24 @@ impl FromStr for Arch {
|
||||||
"x86" | "i686" | "i386" => Ok(Self::X86),
|
"x86" | "i686" | "i386" => Ok(Self::X86),
|
||||||
"x86_64" | "amd64" => Ok(Self::X86_64),
|
"x86_64" | "amd64" => Ok(Self::X86_64),
|
||||||
"s390x" => Ok(Self::S390X),
|
"s390x" => Ok(Self::S390X),
|
||||||
_ => Err(PythonSelectorError::ArchNotSupported(s.to_string())),
|
_ => Err(Error::ArchNotSupported(s.to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Arch {
|
impl Arch {
|
||||||
pub(crate) fn from_env() -> Result<Self, PythonSelectorError> {
|
pub(crate) fn from_env() -> Result<Self, Error> {
|
||||||
Self::from_str(std::env::consts::ARCH)
|
Self::from_str(std::env::consts::ARCH)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Libc {
|
impl Libc {
|
||||||
pub(crate) fn from_env() -> Result<Self, PythonSelectorError> {
|
pub(crate) fn from_env() -> Result<Self, Error> {
|
||||||
// TODO(zanieb): Perform this lookup
|
// TODO(zanieb): Perform this lookup
|
||||||
match std::env::consts::OS {
|
match std::env::consts::OS {
|
||||||
"linux" => Ok(Libc::Gnu),
|
"linux" => Ok(Libc::Gnu),
|
||||||
"windows" | "macos" => Ok(Libc::None),
|
"windows" | "macos" => Ok(Libc::None),
|
||||||
_ => Err(PythonSelectorError::LibcNotDetected()),
|
_ => Err(Error::LibcNotDetected()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue