mirror of
https://github.com/astral-sh/uv.git
synced 2025-07-07 21:35:00 +00:00
Rename uv-traits
and split into separate modules (#2674)
This is driving me a little crazy and is becoming a larger problem in #2596 where I need to move more types (like `Upgrade` and `Reinstall`) into this crate. Anything that's shared across our core resolver, install, and build crates needs to be defined in this crate to avoid cyclic dependencies. We've outgrown it being a single file with some shared traits. There are no behavioral changes here.
This commit is contained in:
parent
39769d82a0
commit
0b08ba1e67
44 changed files with 696 additions and 624 deletions
30
crates/uv-types/Cargo.toml
Normal file
30
crates/uv-types/Cargo.toml
Normal file
|
@ -0,0 +1,30 @@
|
|||
[package]
|
||||
name = "uv-types"
|
||||
version = "0.0.1"
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
documentation = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
license = { workspace = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
distribution-types = { workspace = true }
|
||||
once-map = { workspace = true }
|
||||
pep508_rs = { workspace = true }
|
||||
uv-cache = { workspace = true }
|
||||
uv-interpreter = { workspace = true }
|
||||
uv-normalize = { workspace = true }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
rustc-hash = { workspace = true }
|
||||
serde = { workspace = true, optional = true }
|
||||
serde_json = { workspace = true, optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
serde = ["dep:serde", "dep:serde_json"]
|
179
crates/uv-types/src/build_options.rs
Normal file
179
crates/uv-types/src/build_options.rs
Normal file
|
@ -0,0 +1,179 @@
|
|||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use pep508_rs::PackageName;
|
||||
use uv_interpreter::PythonEnvironment;
|
||||
|
||||
use crate::{PackageNameSpecifier, PackageNameSpecifiers};
|
||||
|
||||
/// Whether to enforce build isolation when building source distributions.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum BuildIsolation<'a> {
|
||||
Isolated,
|
||||
Shared(&'a PythonEnvironment),
|
||||
}
|
||||
|
||||
impl<'a> BuildIsolation<'a> {
|
||||
/// Returns `true` if build isolation is enforced.
|
||||
pub fn is_isolated(&self) -> bool {
|
||||
matches!(self, Self::Isolated)
|
||||
}
|
||||
}
|
||||
|
||||
/// The strategy to use when building source distributions that lack a `pyproject.toml`.
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
||||
pub enum SetupPyStrategy {
|
||||
/// Perform a PEP 517 build.
|
||||
#[default]
|
||||
Pep517,
|
||||
/// Perform a build by invoking `setuptools` directly.
|
||||
Setuptools,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq)]
|
||||
pub enum BuildKind {
|
||||
/// A regular PEP 517 wheel build
|
||||
#[default]
|
||||
Wheel,
|
||||
/// A PEP 660 editable installation wheel build
|
||||
Editable,
|
||||
}
|
||||
|
||||
impl Display for BuildKind {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Wheel => f.write_str("wheel"),
|
||||
Self::Editable => f.write_str("editable"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum NoBinary {
|
||||
/// Allow installation of any wheel.
|
||||
None,
|
||||
|
||||
/// Do not allow installation from any wheels.
|
||||
All,
|
||||
|
||||
/// Do not allow installation from the specific wheels.
|
||||
Packages(Vec<PackageName>),
|
||||
}
|
||||
|
||||
impl NoBinary {
|
||||
/// Determine the binary installation strategy to use.
|
||||
pub fn from_args(no_binary: Vec<PackageNameSpecifier>) -> Self {
|
||||
let combined = PackageNameSpecifiers::from_iter(no_binary.into_iter());
|
||||
match combined {
|
||||
PackageNameSpecifiers::All => Self::All,
|
||||
PackageNameSpecifiers::None => Self::None,
|
||||
PackageNameSpecifiers::Packages(packages) => Self::Packages(packages),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NoBinary {
|
||||
/// Returns `true` if all wheels are allowed.
|
||||
pub fn is_none(&self) -> bool {
|
||||
matches!(self, Self::None)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum NoBuild {
|
||||
/// Allow building wheels from any source distribution.
|
||||
None,
|
||||
|
||||
/// Do not allow building wheels from any source distribution.
|
||||
All,
|
||||
|
||||
/// Do not allow building wheels from the given package's source distributions.
|
||||
Packages(Vec<PackageName>),
|
||||
}
|
||||
|
||||
impl NoBuild {
|
||||
/// Determine the build strategy to use.
|
||||
pub fn from_args(only_binary: Vec<PackageNameSpecifier>, no_build: bool) -> Self {
|
||||
if no_build {
|
||||
Self::All
|
||||
} else {
|
||||
let combined = PackageNameSpecifiers::from_iter(only_binary.into_iter());
|
||||
match combined {
|
||||
PackageNameSpecifiers::All => Self::All,
|
||||
PackageNameSpecifiers::None => Self::None,
|
||||
PackageNameSpecifiers::Packages(packages) => Self::Packages(packages),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NoBuild {
|
||||
/// Returns `true` if all builds are allowed.
|
||||
pub fn is_none(&self) -> bool {
|
||||
matches!(self, Self::None)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Error;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn no_build_from_args() -> Result<(), Error> {
|
||||
assert_eq!(
|
||||
NoBuild::from_args(vec![PackageNameSpecifier::from_str(":all:")?], false),
|
||||
NoBuild::All,
|
||||
);
|
||||
assert_eq!(
|
||||
NoBuild::from_args(vec![PackageNameSpecifier::from_str(":all:")?], true),
|
||||
NoBuild::All,
|
||||
);
|
||||
assert_eq!(
|
||||
NoBuild::from_args(vec![PackageNameSpecifier::from_str(":none:")?], true),
|
||||
NoBuild::All,
|
||||
);
|
||||
assert_eq!(
|
||||
NoBuild::from_args(vec![PackageNameSpecifier::from_str(":none:")?], false),
|
||||
NoBuild::None,
|
||||
);
|
||||
assert_eq!(
|
||||
NoBuild::from_args(
|
||||
vec![
|
||||
PackageNameSpecifier::from_str("foo")?,
|
||||
PackageNameSpecifier::from_str("bar")?
|
||||
],
|
||||
false
|
||||
),
|
||||
NoBuild::Packages(vec![
|
||||
PackageName::from_str("foo")?,
|
||||
PackageName::from_str("bar")?
|
||||
]),
|
||||
);
|
||||
assert_eq!(
|
||||
NoBuild::from_args(
|
||||
vec![
|
||||
PackageNameSpecifier::from_str("test")?,
|
||||
PackageNameSpecifier::All
|
||||
],
|
||||
false
|
||||
),
|
||||
NoBuild::All,
|
||||
);
|
||||
assert_eq!(
|
||||
NoBuild::from_args(
|
||||
vec![
|
||||
PackageNameSpecifier::from_str("foo")?,
|
||||
PackageNameSpecifier::from_str(":none:")?,
|
||||
PackageNameSpecifier::from_str("bar")?
|
||||
],
|
||||
false
|
||||
),
|
||||
NoBuild::Packages(vec![PackageName::from_str("bar")?]),
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
176
crates/uv-types/src/config_settings.rs
Normal file
176
crates/uv-types/src/config_settings.rs
Normal file
|
@ -0,0 +1,176 @@
|
|||
use std::{
|
||||
collections::{btree_map::Entry, BTreeMap},
|
||||
str::FromStr,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ConfigSettingEntry {
|
||||
/// The key of the setting. For example, given `key=value`, this would be `key`.
|
||||
key: String,
|
||||
/// The value of the setting. For example, given `key=value`, this would be `value`.
|
||||
value: String,
|
||||
}
|
||||
|
||||
impl FromStr for ConfigSettingEntry {
|
||||
type Err = anyhow::Error;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let Some((key, value)) = s.split_once('=') else {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Invalid config setting: {s} (expected `KEY=VALUE`)"
|
||||
));
|
||||
};
|
||||
Ok(Self {
|
||||
key: key.trim().to_string(),
|
||||
value: value.trim().to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
enum ConfigSettingValue {
|
||||
/// The value consists of a single string.
|
||||
String(String),
|
||||
/// The value consists of a list of strings.
|
||||
List(Vec<String>),
|
||||
}
|
||||
|
||||
/// Settings to pass to a PEP 517 build backend, structured as a map from (string) key to string or
|
||||
/// list of strings.
|
||||
///
|
||||
/// See: <https://peps.python.org/pep-0517/#config-settings>
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct ConfigSettings(BTreeMap<String, ConfigSettingValue>);
|
||||
|
||||
impl FromIterator<ConfigSettingEntry> for ConfigSettings {
|
||||
fn from_iter<T: IntoIterator<Item = ConfigSettingEntry>>(iter: T) -> Self {
|
||||
let mut config = BTreeMap::default();
|
||||
for entry in iter {
|
||||
match config.entry(entry.key) {
|
||||
Entry::Vacant(vacant) => {
|
||||
vacant.insert(ConfigSettingValue::String(entry.value));
|
||||
}
|
||||
Entry::Occupied(mut occupied) => match occupied.get_mut() {
|
||||
ConfigSettingValue::String(existing) => {
|
||||
let existing = existing.clone();
|
||||
occupied.insert(ConfigSettingValue::List(vec![existing, entry.value]));
|
||||
}
|
||||
ConfigSettingValue::List(existing) => {
|
||||
existing.push(entry.value);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Self(config)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl ConfigSettings {
|
||||
/// Convert the settings to a string that can be passed directly to a PEP 517 build backend.
|
||||
pub fn escape_for_python(&self) -> String {
|
||||
serde_json::to_string(self).expect("Failed to serialize config settings")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl serde::Serialize for ConfigSettings {
|
||||
fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
|
||||
use serde::ser::SerializeMap;
|
||||
|
||||
let mut map = serializer.serialize_map(Some(self.0.len()))?;
|
||||
for (key, value) in &self.0 {
|
||||
match value {
|
||||
ConfigSettingValue::String(value) => {
|
||||
map.serialize_entry(&key, &value)?;
|
||||
}
|
||||
ConfigSettingValue::List(values) => {
|
||||
map.serialize_entry(&key, &values)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
map.end()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn collect_config_settings() {
|
||||
let settings: ConfigSettings = vec![
|
||||
ConfigSettingEntry {
|
||||
key: "key".to_string(),
|
||||
value: "value".to_string(),
|
||||
},
|
||||
ConfigSettingEntry {
|
||||
key: "key".to_string(),
|
||||
value: "value2".to_string(),
|
||||
},
|
||||
ConfigSettingEntry {
|
||||
key: "list".to_string(),
|
||||
value: "value3".to_string(),
|
||||
},
|
||||
ConfigSettingEntry {
|
||||
key: "list".to_string(),
|
||||
value: "value4".to_string(),
|
||||
},
|
||||
]
|
||||
.into_iter()
|
||||
.collect();
|
||||
assert_eq!(
|
||||
settings.0.get("key"),
|
||||
Some(&ConfigSettingValue::List(vec![
|
||||
"value".to_string(),
|
||||
"value2".to_string()
|
||||
]))
|
||||
);
|
||||
assert_eq!(
|
||||
settings.0.get("list"),
|
||||
Some(&ConfigSettingValue::List(vec![
|
||||
"value3".to_string(),
|
||||
"value4".to_string()
|
||||
]))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "serde")]
|
||||
fn escape_for_python() {
|
||||
let mut settings = ConfigSettings::default();
|
||||
settings.0.insert(
|
||||
"key".to_string(),
|
||||
ConfigSettingValue::String("value".to_string()),
|
||||
);
|
||||
settings.0.insert(
|
||||
"list".to_string(),
|
||||
ConfigSettingValue::List(vec!["value1".to_string(), "value2".to_string()]),
|
||||
);
|
||||
assert_eq!(
|
||||
settings.escape_for_python(),
|
||||
r#"{"key":"value","list":["value1","value2"]}"#
|
||||
);
|
||||
|
||||
let mut settings = ConfigSettings::default();
|
||||
settings.0.insert(
|
||||
"key".to_string(),
|
||||
ConfigSettingValue::String("Hello, \"world!\"".to_string()),
|
||||
);
|
||||
settings.0.insert(
|
||||
"list".to_string(),
|
||||
ConfigSettingValue::List(vec!["'value1'".to_string()]),
|
||||
);
|
||||
assert_eq!(
|
||||
settings.escape_for_python(),
|
||||
r#"{"key":"Hello, \"world!\"","list":["'value1'"]}"#
|
||||
);
|
||||
|
||||
let mut settings = ConfigSettings::default();
|
||||
settings.0.insert(
|
||||
"key".to_string(),
|
||||
ConfigSettingValue::String("val\\1 {}ue".to_string()),
|
||||
);
|
||||
assert_eq!(settings.escape_for_python(), r#"{"key":"val\\1 {}ue"}"#);
|
||||
}
|
||||
}
|
8
crates/uv-types/src/downloads.rs
Normal file
8
crates/uv-types/src/downloads.rs
Normal file
|
@ -0,0 +1,8 @@
|
|||
use distribution_types::{CachedDist, DistributionId};
|
||||
use once_map::OnceMap;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct InFlight {
|
||||
/// The in-flight distribution downloads.
|
||||
pub downloads: OnceMap<DistributionId, Result<CachedDist, String>>,
|
||||
}
|
14
crates/uv-types/src/lib.rs
Normal file
14
crates/uv-types/src/lib.rs
Normal file
|
@ -0,0 +1,14 @@
|
|||
//! Fundamental types shared across `uv` crates.
|
||||
pub use build_options::*;
|
||||
pub use config_settings::*;
|
||||
pub use downloads::*;
|
||||
pub use name_specifiers::*;
|
||||
pub use package_options::*;
|
||||
pub use traits::*;
|
||||
|
||||
mod build_options;
|
||||
mod config_settings;
|
||||
mod downloads;
|
||||
mod name_specifiers;
|
||||
mod package_options;
|
||||
mod traits;
|
63
crates/uv-types/src/name_specifiers.rs
Normal file
63
crates/uv-types/src/name_specifiers.rs
Normal file
|
@ -0,0 +1,63 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use pep508_rs::PackageName;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PackageNameSpecifier {
|
||||
All,
|
||||
None,
|
||||
Package(PackageName),
|
||||
}
|
||||
|
||||
impl FromStr for PackageNameSpecifier {
|
||||
type Err = uv_normalize::InvalidNameError;
|
||||
|
||||
fn from_str(name: &str) -> Result<Self, Self::Err> {
|
||||
match name {
|
||||
":all:" => Ok(Self::All),
|
||||
":none:" => Ok(Self::None),
|
||||
_ => Ok(Self::Package(PackageName::from_str(name)?)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Package name specification.
|
||||
///
|
||||
/// Consumes both package names and selection directives for compatibility with pip flags
|
||||
/// such as `--no-binary`.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum PackageNameSpecifiers {
|
||||
All,
|
||||
None,
|
||||
Packages(Vec<PackageName>),
|
||||
}
|
||||
|
||||
impl PackageNameSpecifiers {
|
||||
pub(crate) fn from_iter(specifiers: impl Iterator<Item = PackageNameSpecifier>) -> Self {
|
||||
let mut packages = Vec::new();
|
||||
let mut all: bool = false;
|
||||
|
||||
for specifier in specifiers {
|
||||
match specifier {
|
||||
PackageNameSpecifier::None => {
|
||||
packages.clear();
|
||||
all = false;
|
||||
}
|
||||
PackageNameSpecifier::All => {
|
||||
all = true;
|
||||
}
|
||||
PackageNameSpecifier::Package(name) => {
|
||||
packages.push(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if all {
|
||||
Self::All
|
||||
} else if packages.is_empty() {
|
||||
Self::None
|
||||
} else {
|
||||
Self::Packages(packages)
|
||||
}
|
||||
}
|
||||
}
|
74
crates/uv-types/src/package_options.rs
Normal file
74
crates/uv-types/src/package_options.rs
Normal file
|
@ -0,0 +1,74 @@
|
|||
use pep508_rs::PackageName;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
/// Whether to reinstall packages.
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Reinstall {
|
||||
/// Don't reinstall any packages; respect the existing installation.
|
||||
None,
|
||||
|
||||
/// Reinstall all packages in the plan.
|
||||
All,
|
||||
|
||||
/// Reinstall only the specified packages.
|
||||
Packages(Vec<PackageName>),
|
||||
}
|
||||
|
||||
impl Reinstall {
|
||||
/// Determine the reinstall strategy to use.
|
||||
pub fn from_args(reinstall: bool, reinstall_package: Vec<PackageName>) -> Self {
|
||||
if reinstall {
|
||||
Self::All
|
||||
} else if !reinstall_package.is_empty() {
|
||||
Self::Packages(reinstall_package)
|
||||
} else {
|
||||
Self::None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if no packages should be reinstalled.
|
||||
pub fn is_none(&self) -> bool {
|
||||
matches!(self, Self::None)
|
||||
}
|
||||
|
||||
/// Returns `true` if all packages should be reinstalled.
|
||||
pub fn is_all(&self) -> bool {
|
||||
matches!(self, Self::All)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether to allow package upgrades.
|
||||
#[derive(Debug)]
|
||||
pub enum Upgrade {
|
||||
/// Prefer pinned versions from the existing lockfile, if possible.
|
||||
None,
|
||||
|
||||
/// Allow package upgrades for all packages, ignoring the existing lockfile.
|
||||
All,
|
||||
|
||||
/// Allow package upgrades, but only for the specified packages.
|
||||
Packages(FxHashSet<PackageName>),
|
||||
}
|
||||
|
||||
impl Upgrade {
|
||||
/// Determine the upgrade strategy from the command-line arguments.
|
||||
pub fn from_args(upgrade: bool, upgrade_package: Vec<PackageName>) -> Self {
|
||||
if upgrade {
|
||||
Self::All
|
||||
} else if !upgrade_package.is_empty() {
|
||||
Self::Packages(upgrade_package.into_iter().collect())
|
||||
} else {
|
||||
Self::None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if no packages should be upgraded.
|
||||
pub fn is_none(&self) -> bool {
|
||||
matches!(self, Self::None)
|
||||
}
|
||||
|
||||
/// Returns `true` if all packages should be upgraded.
|
||||
pub fn is_all(&self) -> bool {
|
||||
matches!(self, Self::All)
|
||||
}
|
||||
}
|
129
crates/uv-types/src/traits.rs
Normal file
129
crates/uv-types/src/traits.rs
Normal file
|
@ -0,0 +1,129 @@
|
|||
use std::future::Future;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use distribution_types::{IndexLocations, Resolution, SourceDist};
|
||||
|
||||
use pep508_rs::Requirement;
|
||||
use uv_cache::Cache;
|
||||
use uv_interpreter::{Interpreter, PythonEnvironment};
|
||||
|
||||
use crate::{BuildIsolation, BuildKind, NoBinary, NoBuild, SetupPyStrategy};
|
||||
|
||||
/// Avoids cyclic crate dependencies between resolver, installer and builder.
|
||||
///
|
||||
/// To resolve the dependencies of a packages, we may need to build one or more source
|
||||
/// distributions. To building a source distribution, we need to create a virtual environment from
|
||||
/// the same base python as we use for the root resolution, resolve the build requirements
|
||||
/// (potentially which nested source distributions, recursing a level deeper), installing
|
||||
/// them and then build. The installer, the resolver and the source distribution builder are each in
|
||||
/// their own crate. To avoid circular crate dependencies, this type dispatches between the three
|
||||
/// crates with its three main methods ([`BuildContext::resolve`], [`BuildContext::install`] and
|
||||
/// [`BuildContext::setup_build`]).
|
||||
///
|
||||
/// The overall main crate structure looks like this:
|
||||
///
|
||||
/// ```text
|
||||
/// ┌────────────────┐
|
||||
/// │ uv │
|
||||
/// └───────▲────────┘
|
||||
/// │
|
||||
/// │
|
||||
/// ┌───────┴────────┐
|
||||
/// ┌─────────►│ uv-dispatch │◄─────────┐
|
||||
/// │ └───────▲────────┘ │
|
||||
/// │ │ │
|
||||
/// │ │ │
|
||||
/// ┌───────┴────────┐ ┌───────┴────────┐ ┌────────┴───────┐
|
||||
/// │ uv-resolver │ │ uv-installer │ │ uv-build │
|
||||
/// └───────▲────────┘ └───────▲────────┘ └────────▲───────┘
|
||||
/// │ │ │
|
||||
/// └─────────────┐ │ ┌──────────────┘
|
||||
/// ┌──┴────┴────┴───┐
|
||||
/// │ uv-types │
|
||||
/// └────────────────┘
|
||||
/// ```
|
||||
///
|
||||
/// Put in a different way, the types here allow `uv-resolver` to depend on `uv-build` and
|
||||
/// `uv-build` to depend on `uv-resolver` which having actual crate dependencies between
|
||||
/// them.
|
||||
pub trait BuildContext: Sync {
|
||||
type SourceDistBuilder: SourceBuildTrait + Send + Sync;
|
||||
|
||||
/// Return a reference to the cache.
|
||||
fn cache(&self) -> &Cache;
|
||||
|
||||
/// All (potentially nested) source distribution builds use the same base python and can reuse
|
||||
/// it's metadata (e.g. wheel compatibility tags).
|
||||
fn interpreter(&self) -> &Interpreter;
|
||||
|
||||
/// Whether to enforce build isolation when building source distributions.
|
||||
fn build_isolation(&self) -> BuildIsolation;
|
||||
|
||||
/// Whether source distribution building is disabled. This [`BuildContext::setup_build`] calls
|
||||
/// will fail in this case. This method exists to avoid fetching source distributions if we know
|
||||
/// we can't build them
|
||||
fn no_build(&self) -> &NoBuild;
|
||||
|
||||
/// Whether using pre-built wheels is disabled.
|
||||
fn no_binary(&self) -> &NoBinary;
|
||||
|
||||
/// The index locations being searched.
|
||||
fn index_locations(&self) -> &IndexLocations;
|
||||
|
||||
/// The strategy to use when building source distributions that lack a `pyproject.toml`.
|
||||
fn setup_py_strategy(&self) -> SetupPyStrategy;
|
||||
|
||||
/// Resolve the given requirements into a ready-to-install set of package versions.
|
||||
fn resolve<'a>(
|
||||
&'a self,
|
||||
requirements: &'a [Requirement],
|
||||
) -> impl Future<Output = Result<Resolution>> + Send + 'a;
|
||||
|
||||
/// Install the given set of package versions into the virtual environment. The environment must
|
||||
/// use the same base Python as [`BuildContext::interpreter`]
|
||||
fn install<'a>(
|
||||
&'a self,
|
||||
resolution: &'a Resolution,
|
||||
venv: &'a PythonEnvironment,
|
||||
) -> impl Future<Output = Result<()>> + Send + 'a;
|
||||
|
||||
/// Setup a source distribution build by installing the required dependencies. A wrapper for
|
||||
/// `uv_build::SourceBuild::setup`.
|
||||
///
|
||||
/// For PEP 517 builds, this calls `get_requires_for_build_wheel`.
|
||||
///
|
||||
/// `package_id` is for error reporting only.
|
||||
/// `dist` is for safety checks and may be null for editable builds.
|
||||
fn setup_build<'a>(
|
||||
&'a self,
|
||||
source: &'a Path,
|
||||
subdirectory: Option<&'a Path>,
|
||||
package_id: &'a str,
|
||||
dist: Option<&'a SourceDist>,
|
||||
build_kind: BuildKind,
|
||||
) -> impl Future<Output = Result<Self::SourceDistBuilder>> + Send + 'a;
|
||||
}
|
||||
|
||||
/// A wrapper for `uv_build::SourceBuild` to avoid cyclical crate dependencies.
|
||||
///
|
||||
/// You can either call only `wheel()` to build the wheel directly, call only `metadata()` to get
|
||||
/// the metadata without performing the actual or first call `metadata()` and then `wheel()`.
|
||||
pub trait SourceBuildTrait {
|
||||
/// A wrapper for `uv_build::SourceBuild::get_metadata_without_build`.
|
||||
///
|
||||
/// For PEP 517 builds, this calls `prepare_metadata_for_build_wheel`
|
||||
///
|
||||
/// Returns the metadata directory if we're having a PEP 517 build and the
|
||||
/// `prepare_metadata_for_build_wheel` hook exists
|
||||
fn metadata(&mut self) -> impl Future<Output = Result<Option<PathBuf>>> + Send;
|
||||
|
||||
/// A wrapper for `uv_build::SourceBuild::build`.
|
||||
///
|
||||
/// For PEP 517 builds, this calls `build_wheel`.
|
||||
///
|
||||
/// Returns the filename of the built wheel inside the given `wheel_dir`.
|
||||
fn wheel<'a>(&'a self, wheel_dir: &'a Path)
|
||||
-> impl Future<Output = Result<String>> + Send + 'a;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue