Remove `--legacy-setup-py` command-line argument (#4255)

This is a fallback mode that we supported when we decided to use PEP 517
builds by default. I can't find a single reference to it on GitHub or in
our issue tracker, so I want to drop support for it as part of v0.3.0.
This commit is contained in:
Charlie Marsh 2024-08-19 16:57:59 -04:00 committed by Zanie Blue
parent 47fb902104
commit 732d2fb0fb
23 changed files with 53 additions and 368 deletions

View File

@ -91,7 +91,7 @@ mod resolver {
use uv_cache::Cache;
use uv_client::RegistryClient;
use uv_configuration::{
BuildOptions, Concurrency, ConfigSettings, IndexStrategy, SetupPyStrategy, SourceStrategy,
BuildOptions, Concurrency, ConfigSettings, IndexStrategy, SourceStrategy,
};
use uv_dispatch::BuildDispatch;
use uv_distribution::DistributionDatabase;
@ -179,7 +179,6 @@ mod resolver {
&git,
&in_flight,
IndexStrategy::default(),
SetupPyStrategy::default(),
&config_settings,
build_isolation,
LinkMode::default(),

View File

@ -28,7 +28,7 @@ use distribution_types::Resolution;
use pep440_rs::Version;
use pep508_rs::PackageName;
use pypi_types::{Requirement, VerbatimParsedUrl};
use uv_configuration::{BuildKind, ConfigSettings, SetupPyStrategy};
use uv_configuration::{BuildKind, ConfigSettings};
use uv_fs::{rename_with_retry, PythonExt, Simplified};
use uv_python::{Interpreter, PythonEnvironment};
use uv_types::{BuildContext, BuildIsolation, SourceBuildTrait};
@ -75,14 +75,6 @@ static DEFAULT_BACKEND: LazyLock<Pep517Backend> = LazyLock::new(|| Pep517Backend
)],
});
/// The requirements for `--legacy-setup-py` builds.
static SETUP_PY_REQUIREMENTS: LazyLock<[Requirement; 2]> = LazyLock::new(|| {
[
Requirement::from(pep508_rs::Requirement::from_str("setuptools >= 40.8.0").unwrap()),
Requirement::from(pep508_rs::Requirement::from_str("wheel").unwrap()),
]
});
#[derive(Error, Debug)]
pub enum Error {
#[error(transparent)]
@ -359,8 +351,6 @@ impl Pep517Backend {
pub struct SourceBuildContext {
/// An in-memory resolution of the default backend's requirements for PEP 517 builds.
default_resolution: Rc<Mutex<Option<Resolution>>>,
/// An in-memory resolution of the build requirements for `--legacy-setup-py` builds.
setup_py_resolution: Rc<Mutex<Option<Resolution>>>,
}
/// Holds the state through a series of PEP 517 frontend to backend calls or a single setup.py
@ -373,7 +363,7 @@ pub struct SourceBuild {
source_tree: PathBuf,
config_settings: ConfigSettings,
/// If performing a PEP 517 build, the backend to use.
pep517_backend: Option<Pep517Backend>,
pep517_backend: Pep517Backend,
/// The PEP 621 project metadata, if any.
project: Option<Project>,
/// The virtual environment in which to build the source distribution.
@ -412,7 +402,6 @@ impl SourceBuild {
build_context: &impl BuildContext,
source_build_context: SourceBuildContext,
version_id: String,
setup_py: SetupPyStrategy,
config_settings: ConfigSettings,
build_isolation: BuildIsolation<'_>,
build_kind: BuildKind,
@ -431,8 +420,7 @@ impl SourceBuild {
// Check if we have a PEP 517 build backend.
let (pep517_backend, project) =
Self::extract_pep517_backend(&source_tree, setup_py, &default_backend)
.map_err(|err| *err)?;
Self::extract_pep517_backend(&source_tree, &default_backend).map_err(|err| *err)?;
let package_name = project.clone().map(|p| p.name);
@ -457,7 +445,7 @@ impl SourceBuild {
build_context,
source_build_context,
&default_backend,
pep517_backend.as_ref(),
&pep517_backend,
)
.await?;
@ -503,22 +491,20 @@ impl SourceBuild {
// environment is already setup.
let runner = PythonRunner::new(concurrent_builds);
if build_isolation.is_isolated(package_name.as_ref()) {
if let Some(pep517_backend) = &pep517_backend {
create_pep517_build_environment(
&runner,
&source_tree,
&venv,
pep517_backend,
build_context,
&version_id,
build_kind,
&config_settings,
&environment_variables,
&modified_path,
&temp_dir,
)
.await?;
}
create_pep517_build_environment(
&runner,
&source_tree,
&venv,
&pep517_backend,
build_context,
&version_id,
build_kind,
&config_settings,
&environment_variables,
&modified_path,
&temp_dir,
)
.await?;
}
Ok(Self {
@ -541,9 +527,9 @@ impl SourceBuild {
build_context: &impl BuildContext,
source_build_context: SourceBuildContext,
default_backend: &Pep517Backend,
pep517_backend: Option<&Pep517Backend>,
pep517_backend: &Pep517Backend,
) -> Result<Resolution, Error> {
Ok(if let Some(pep517_backend) = pep517_backend {
Ok(
if pep517_backend.requirements == default_backend.requirements {
let mut resolution = source_build_context.default_resolution.lock().await;
if let Some(resolved_requirements) = &*resolution {
@ -565,29 +551,15 @@ impl SourceBuild {
.map_err(|err| {
Error::RequirementsInstall("build-system.requires (resolve)", err)
})?
}
} else {
// Install default requirements for `setup.py`-based builds.
let mut resolution = source_build_context.setup_py_resolution.lock().await;
if let Some(resolved_requirements) = &*resolution {
resolved_requirements.clone()
} else {
let resolved_requirements = build_context
.resolve(&*SETUP_PY_REQUIREMENTS)
.await
.map_err(|err| Error::RequirementsInstall("setup.py build (resolve)", err))?;
*resolution = Some(resolved_requirements.clone());
resolved_requirements
}
})
},
)
}
/// Extract the PEP 517 backend from the `pyproject.toml` or `setup.py` file.
fn extract_pep517_backend(
source_tree: &Path,
setup_py: SetupPyStrategy,
default_backend: &Pep517Backend,
) -> Result<(Option<Pep517Backend>, Option<Project>), Box<Error>> {
) -> Result<(Pep517Backend, Option<Project>), Box<Error>> {
match fs::read_to_string(source_tree.join("pyproject.toml")) {
Ok(toml) => {
let pyproject_toml: PyProjectToml =
@ -616,7 +588,7 @@ impl SourceBuild {
// a PEP 517 build using the default backend, to match `pip` and `build`.
default_backend.clone()
};
Ok((Some(backend), pyproject_toml.project))
Ok((backend, pyproject_toml.project))
}
Err(err) if err.kind() == io::ErrorKind::NotFound => {
// We require either a `pyproject.toml` or a `setup.py` file at the top level.
@ -629,13 +601,9 @@ impl SourceBuild {
// If no `pyproject.toml` is present, by default, proceed with a PEP 517 build using
// the default backend, to match `build`. `pip` uses `setup.py` directly in this
// case (which we allow via `SetupPyStrategy::Setuptools`), but plans to make PEP
// 517 builds the default in the future.
// case, but plans to make PEP 517 builds the default in the future.
// See: https://github.com/pypa/pip/issues/9175.
match setup_py {
SetupPyStrategy::Pep517 => Ok((Some(default_backend.clone()), None)),
SetupPyStrategy::Setuptools => Ok((None, None)),
}
Ok((default_backend.clone(), None))
}
Err(err) => Err(Box::new(err.into())),
}
@ -644,10 +612,6 @@ impl SourceBuild {
/// Try calling `prepare_metadata_for_build_wheel` to get the metadata without executing the
/// actual build.
pub async fn get_metadata_without_build(&mut self) -> Result<Option<PathBuf>, Error> {
let Some(pep517_backend) = &self.pep517_backend else {
return Ok(None);
};
// We've already called this method; return the existing result.
if let Some(metadata_dir) = &self.metadata_directory {
return Ok(Some(metadata_dir.clone()));
@ -668,7 +632,7 @@ impl SourceBuild {
// this is just an optimization.
//
// See: https://github.com/astral-sh/uv/issues/2130
if pep517_backend.backend == "hatchling.build" {
if self.pep517_backend.backend == "hatchling.build" {
if self
.project
.as_ref()
@ -694,7 +658,7 @@ impl SourceBuild {
debug!(
"Calling `{}.prepare_metadata_for_build_{}()`",
pep517_backend.backend, self.build_kind,
self.pep517_backend.backend, self.build_kind,
);
let script = formatdoc! {
r#"
@ -710,7 +674,7 @@ impl SourceBuild {
with open("{}", "w") as fp:
fp.write(dirname or "")
"#,
pep517_backend.backend_import(),
self.pep517_backend.backend_import(),
self.build_kind,
escape_path_for_python(&metadata_directory),
self.config_settings.escape_for_python(),
@ -760,55 +724,16 @@ impl SourceBuild {
// The build scripts run with the extracted root as cwd, so they need the absolute path.
let wheel_dir = fs::canonicalize(wheel_dir)?;
if let Some(pep517_backend) = &self.pep517_backend {
// Prevent clashes from two uv processes building wheels in parallel.
let tmp_dir = tempdir_in(&wheel_dir)?;
let filename = self.pep517_build(tmp_dir.path(), pep517_backend).await?;
// Prevent clashes from two uv processes building wheels in parallel.
let tmp_dir = tempdir_in(&wheel_dir)?;
let filename = self
.pep517_build(tmp_dir.path(), &self.pep517_backend)
.await?;
let from = tmp_dir.path().join(&filename);
let to = wheel_dir.join(&filename);
rename_with_retry(from, to).await?;
Ok(filename)
} else {
if self.build_kind != BuildKind::Wheel {
return Err(Error::EditableSetupPy);
}
// We checked earlier that setup.py exists.
let span = info_span!(
"run_python_script",
script="setup.py bdist_wheel",
python_version = %self.venv.interpreter().python_version()
);
let output = self
.runner
.run_setup_py(&self.venv, "bdist_wheel", &self.source_tree)
.instrument(span)
.await?;
if !output.status.success() {
return Err(Error::from_command_output(
"Failed building wheel through setup.py".to_string(),
&output,
&self.version_id,
));
}
let dist = fs::read_dir(self.source_tree.join("dist"))?;
let dist_dir = dist.collect::<io::Result<Vec<fs_err::DirEntry>>>()?;
let [dist_wheel] = dist_dir.as_slice() else {
return Err(Error::from_command_output(
format!(
"Expected exactly wheel in `dist/` after invoking setup.py, found {dist_dir:?}"
),
&output,
&self.version_id)
);
};
let from = dist_wheel.path();
let to = wheel_dir.join(dist_wheel.file_name());
fs_err::copy(from, to)?;
Ok(dist_wheel.file_name().to_string_lossy().to_string())
}
let from = tmp_dir.path().join(&filename);
let to = wheel_dir.join(&filename);
rename_with_retry(from, to).await?;
Ok(filename)
}
async fn pep517_build(
@ -1072,28 +997,6 @@ impl PythonRunner {
.await
.map_err(|err| Error::CommandFailed(venv.python_executable().to_path_buf(), err))
}
/// Spawn a process that runs a `setup.py` script.
///
/// If the concurrency limit has been reached this method will wait until a pending
/// script completes before spawning this one.
///
/// Note: It is the caller's responsibility to create an informative span.
async fn run_setup_py(
&self,
venv: &PythonEnvironment,
script: &str,
source_tree: &Path,
) -> Result<Output, Error> {
let _permit = self.control.acquire().await.unwrap();
Command::new(venv.python_executable())
.args(["setup.py", script])
.current_dir(source_tree.simplified())
.output()
.await
.map_err(|err| Error::CommandFailed(venv.python_executable().to_path_buf(), err))
}
}
#[cfg(test)]

View File

@ -869,14 +869,6 @@ pub struct PipCompileArgs {
#[arg(long, overrides_with("generate_hashes"), hide = true)]
pub no_generate_hashes: bool,
/// Use legacy `setuptools` behavior when building source distributions without a
/// `pyproject.toml`.
#[arg(long, overrides_with("no_legacy_setup_py"))]
pub legacy_setup_py: bool,
#[arg(long, overrides_with("legacy_setup_py"), hide = true)]
pub no_legacy_setup_py: bool,
/// Don't build source distributions.
///
/// When enabled, resolving will not run arbitrary Python code. The cached wheels of
@ -1159,14 +1151,6 @@ pub struct PipSyncArgs {
#[arg(long, conflicts_with = "target")]
pub prefix: Option<PathBuf>,
/// Use legacy `setuptools` behavior when building source distributions without a
/// `pyproject.toml`.
#[arg(long, overrides_with("no_legacy_setup_py"))]
pub legacy_setup_py: bool,
#[arg(long, overrides_with("legacy_setup_py"), hide = true)]
pub no_legacy_setup_py: bool,
/// Don't build source distributions.
///
/// When enabled, resolving will not run arbitrary Python code. The cached wheels of
@ -1449,14 +1433,6 @@ pub struct PipInstallArgs {
#[arg(long, conflicts_with = "target")]
pub prefix: Option<PathBuf>,
/// Use legacy `setuptools` behavior when building source distributions without a
/// `pyproject.toml`.
#[arg(long, overrides_with("no_legacy_setup_py"))]
pub legacy_setup_py: bool,
#[arg(long, overrides_with("legacy_setup_py"), hide = true)]
pub no_legacy_setup_py: bool,
/// Don't build source distributions.
///
/// When enabled, resolving will not run arbitrary Python code. The cached wheels of

View File

@ -4,16 +4,6 @@ use pep508_rs::PackageName;
use crate::{PackageNameSpecifier, PackageNameSpecifiers};
/// 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

View File

@ -11,8 +11,7 @@ use uv_build::{SourceBuild, SourceBuildContext};
use uv_cache::{Cache, CacheArgs};
use uv_client::RegistryClientBuilder;
use uv_configuration::{
BuildKind, BuildOptions, Concurrency, ConfigSettings, IndexStrategy, SetupPyStrategy,
SourceStrategy,
BuildKind, BuildOptions, Concurrency, ConfigSettings, IndexStrategy, SourceStrategy,
};
use uv_dispatch::BuildDispatch;
use uv_git::GitResolver;
@ -67,7 +66,6 @@ pub(crate) async fn build(args: BuildArgs) -> Result<PathBuf> {
let index = InMemoryIndex::default();
let index_urls = IndexLocations::default();
let index_strategy = IndexStrategy::default();
let setup_py = SetupPyStrategy::default();
let sources = SourceStrategy::default();
let python = PythonEnvironment::find(
&PythonRequest::default(),
@ -88,7 +86,6 @@ pub(crate) async fn build(args: BuildArgs) -> Result<PathBuf> {
&git,
&in_flight,
index_strategy,
setup_py,
&config_settings,
BuildIsolation::Isolated,
install_wheel_rs::linker::LinkMode::default(),
@ -105,7 +102,6 @@ pub(crate) async fn build(args: BuildArgs) -> Result<PathBuf> {
&build_dispatch,
SourceBuildContext::default(),
args.sdist.display().to_string(),
setup_py,
config_settings.clone(),
BuildIsolation::Isolated,
build_kind,

View File

@ -18,8 +18,7 @@ use uv_cache::Cache;
use uv_client::RegistryClient;
use uv_configuration::Concurrency;
use uv_configuration::{
BuildKind, BuildOptions, ConfigSettings, Constraints, IndexStrategy, Reinstall,
SetupPyStrategy, SourceStrategy,
BuildKind, BuildOptions, ConfigSettings, Constraints, IndexStrategy, Reinstall, SourceStrategy,
};
use uv_distribution::DistributionDatabase;
use uv_git::GitResolver;
@ -44,7 +43,6 @@ pub struct BuildDispatch<'a> {
index: &'a InMemoryIndex,
git: &'a GitResolver,
in_flight: &'a InFlight,
setup_py: SetupPyStrategy,
build_isolation: BuildIsolation<'a>,
link_mode: install_wheel_rs::linker::LinkMode,
build_options: &'a BuildOptions,
@ -68,7 +66,6 @@ impl<'a> BuildDispatch<'a> {
git: &'a GitResolver,
in_flight: &'a InFlight,
index_strategy: IndexStrategy,
setup_py: SetupPyStrategy,
config_settings: &'a ConfigSettings,
build_isolation: BuildIsolation<'a>,
link_mode: install_wheel_rs::linker::LinkMode,
@ -88,7 +85,6 @@ impl<'a> BuildDispatch<'a> {
git,
in_flight,
index_strategy,
setup_py,
config_settings,
build_isolation,
link_mode,
@ -326,7 +322,6 @@ impl<'a> BuildContext for BuildDispatch<'a> {
self,
self.source_build_context.clone(),
version_id.to_string(),
self.setup_py,
self.config_settings.clone(),
self.build_isolation,
build_kind,

View File

@ -948,16 +948,6 @@ pub struct PipOptions {
"#
)]
pub generate_hashes: Option<bool>,
/// Use legacy `setuptools` behavior when building source distributions without a
/// `pyproject.toml`.
#[option(
default = "false",
value_type = "bool",
example = r#"
legacy-setup-py = true
"#
)]
pub legacy_setup_py: Option<bool>,
/// Settings to pass to the [PEP 517](https://peps.python.org/pep-0517/) build backend,
/// specified as `KEY=VALUE` pairs.
#[option(

View File

@ -16,7 +16,7 @@ use uv_cache::Cache;
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{
BuildOptions, Concurrency, ConfigSettings, ExtrasSpecification, IndexStrategy, NoBinary,
NoBuild, Reinstall, SetupPyStrategy, SourceStrategy, Upgrade,
NoBuild, Reinstall, SourceStrategy, Upgrade,
};
use uv_configuration::{KeyringProviderType, TargetTriple};
use uv_dispatch::BuildDispatch;
@ -73,7 +73,6 @@ pub(crate) async fn pip_compile(
index_locations: IndexLocations,
index_strategy: IndexStrategy,
keyring_provider: KeyringProviderType,
setup_py: SetupPyStrategy,
config_settings: ConfigSettings,
connectivity: Connectivity,
no_build_isolation: bool,
@ -322,7 +321,6 @@ pub(crate) async fn pip_compile(
&git,
&in_flight,
index_strategy,
setup_py,
&config_settings,
build_isolation,
link_mode,

View File

@ -14,7 +14,7 @@ use uv_cache::Cache;
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{
BuildOptions, Concurrency, ConfigSettings, ExtrasSpecification, HashCheckingMode,
IndexStrategy, Reinstall, SetupPyStrategy, SourceStrategy, Upgrade,
IndexStrategy, Reinstall, SourceStrategy, Upgrade,
};
use uv_configuration::{KeyringProviderType, TargetTriple};
use uv_dispatch::BuildDispatch;
@ -57,7 +57,6 @@ pub(crate) async fn pip_install(
link_mode: LinkMode,
compile: bool,
hash_checking: Option<HashCheckingMode>,
setup_py: SetupPyStrategy,
connectivity: Connectivity,
config_settings: &ConfigSettings,
no_build_isolation: bool,
@ -312,7 +311,6 @@ pub(crate) async fn pip_install(
&state.git,
&state.in_flight,
index_strategy,
setup_py,
config_settings,
build_isolation,
link_mode,

View File

@ -13,7 +13,7 @@ use uv_cache::Cache;
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{
BuildOptions, Concurrency, ConfigSettings, ExtrasSpecification, HashCheckingMode,
IndexStrategy, Reinstall, SetupPyStrategy, SourceStrategy, Upgrade,
IndexStrategy, Reinstall, SourceStrategy, Upgrade,
};
use uv_configuration::{KeyringProviderType, TargetTriple};
use uv_dispatch::BuildDispatch;
@ -48,7 +48,6 @@ pub(crate) async fn pip_sync(
index_locations: IndexLocations,
index_strategy: IndexStrategy,
keyring_provider: KeyringProviderType,
setup_py: SetupPyStrategy,
allow_empty_requirements: bool,
connectivity: Connectivity,
config_settings: &ConfigSettings,
@ -258,7 +257,6 @@ pub(crate) async fn pip_sync(
&state.git,
&state.in_flight,
index_strategy,
setup_py,
config_settings,
build_isolation,
link_mode,

View File

@ -11,7 +11,7 @@ use tracing::debug;
use uv_auth::{store_credentials_from_url, Credentials};
use uv_cache::Cache;
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{Concurrency, ExtrasSpecification, SetupPyStrategy, SourceStrategy};
use uv_configuration::{Concurrency, ExtrasSpecification, SourceStrategy};
use uv_dispatch::BuildDispatch;
use uv_distribution::DistributionDatabase;
use uv_fs::{Simplified, CWD};
@ -234,7 +234,6 @@ pub(crate) async fn add(
let python_version = None;
let python_platform = None;
let hasher = HashStrategy::default();
let setup_py = SetupPyStrategy::default();
let build_isolation = BuildIsolation::default();
// Determine the environment for the resolution.
@ -279,7 +278,6 @@ pub(crate) async fn add(
&state.git,
&state.in_flight,
settings.index_strategy,
setup_py,
&settings.config_setting,
build_isolation,
settings.link_mode,

View File

@ -14,7 +14,7 @@ use pypi_types::Requirement;
use uv_auth::store_credentials_from_url;
use uv_cache::Cache;
use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{Concurrency, ExtrasSpecification, Reinstall, SetupPyStrategy, Upgrade};
use uv_configuration::{Concurrency, ExtrasSpecification, Reinstall, Upgrade};
use uv_dispatch::BuildDispatch;
use uv_distribution::DistributionDatabase;
use uv_fs::CWD;
@ -383,7 +383,6 @@ async fn do_lock(
// optional on the downstream APIs.
let build_constraints = [];
let extras = ExtrasSpecification::default();
let setup_py = SetupPyStrategy::default();
// Resolve the flat indexes from `--find-links`.
let flat_index = {
@ -404,7 +403,6 @@ async fn do_lock(
&state.git,
&state.in_flight,
index_strategy,
setup_py,
config_setting,
build_isolation,
link_mode,

View File

@ -11,7 +11,7 @@ use pypi_types::Requirement;
use uv_auth::store_credentials_from_url;
use uv_cache::Cache;
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{Concurrency, ExtrasSpecification, Reinstall, SetupPyStrategy, Upgrade};
use uv_configuration::{Concurrency, ExtrasSpecification, Reinstall, Upgrade};
use uv_dispatch::BuildDispatch;
use uv_distribution::DistributionDatabase;
use uv_fs::Simplified;
@ -451,7 +451,6 @@ pub(crate) async fn resolve_names(
// TODO(charlie): These are all default values. We should consider whether we want to make them
// optional on the downstream APIs.
let hasher = HashStrategy::default();
let setup_py = SetupPyStrategy::default();
let flat_index = FlatIndex::default();
let build_constraints = [];
@ -467,7 +466,6 @@ pub(crate) async fn resolve_names(
&state.git,
&state.in_flight,
*index_strategy,
setup_py,
config_setting,
build_isolation,
*link_mode,
@ -576,7 +574,6 @@ pub(crate) async fn resolve_environment<'a>(
let extras = ExtrasSpecification::default();
let hasher = HashStrategy::default();
let preferences = Vec::default();
let setup_py = SetupPyStrategy::default();
let build_constraints = [];
// When resolving from an interpreter, we assume an empty environment, so reinstalls and
@ -603,7 +600,6 @@ pub(crate) async fn resolve_environment<'a>(
&state.git,
&state.in_flight,
index_strategy,
setup_py,
config_setting,
build_isolation,
link_mode,
@ -705,7 +701,6 @@ pub(crate) async fn sync_environment(
let build_constraints = [];
let dry_run = false;
let hasher = HashStrategy::default();
let setup_py = SetupPyStrategy::default();
// Resolve the flat indexes from `--find-links`.
let flat_index = {
@ -726,7 +721,6 @@ pub(crate) async fn sync_environment(
&state.git,
&state.in_flight,
index_strategy,
setup_py,
config_setting,
build_isolation,
link_mode,
@ -899,7 +893,6 @@ pub(crate) async fn update_environment(
let extras = ExtrasSpecification::default();
let hasher = HashStrategy::default();
let preferences = Vec::default();
let setup_py = SetupPyStrategy::default();
// Resolve the flat indexes from `--find-links`.
let flat_index = {
@ -920,7 +913,6 @@ pub(crate) async fn update_environment(
&state.git,
&state.in_flight,
*index_strategy,
setup_py,
config_setting,
build_isolation,
*link_mode,

View File

@ -4,7 +4,7 @@ use pep508_rs::MarkerTree;
use uv_auth::store_credentials_from_url;
use uv_cache::Cache;
use uv_client::{Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{Concurrency, ExtrasSpecification, HashCheckingMode, SetupPyStrategy};
use uv_configuration::{Concurrency, ExtrasSpecification, HashCheckingMode};
use uv_dispatch::BuildDispatch;
use uv_fs::CWD;
use uv_installer::SitePackages;
@ -216,7 +216,6 @@ pub(super) async fn do_sync(
// optional on the downstream APIs.
let build_constraints = [];
let dry_run = false;
let setup_py = SetupPyStrategy::default();
// Extract the hashes from the lockfile.
let hasher = HashStrategy::from_resolution(&resolution, HashCheckingMode::Verify)?;
@ -240,7 +239,6 @@ pub(super) async fn do_sync(
&state.git,
&state.in_flight,
index_strategy,
setup_py,
config_setting,
build_isolation,
link_mode,

View File

@ -17,7 +17,7 @@ use uv_cache::Cache;
use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder};
use uv_configuration::{
BuildOptions, Concurrency, ConfigSettings, IndexStrategy, KeyringProviderType, NoBinary,
NoBuild, SetupPyStrategy, SourceStrategy,
NoBuild, SourceStrategy,
};
use uv_dispatch::BuildDispatch;
use uv_fs::{Simplified, CWD};
@ -274,7 +274,6 @@ async fn venv_impl(
// For seed packages, assume a bunch of default settings are sufficient.
let build_constraints = [];
let config_settings = ConfigSettings::default();
let setup_py = SetupPyStrategy::default();
let sources = SourceStrategy::Disabled;
// Do not allow builds
@ -292,7 +291,6 @@ async fn venv_impl(
&state.git,
&state.in_flight,
index_strategy,
setup_py,
&config_settings,
BuildIsolation::Isolated,
link_mode,

View File

@ -306,7 +306,6 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
args.settings.index_locations,
args.settings.index_strategy,
args.settings.keyring_provider,
args.settings.setup_py,
args.settings.config_setting,
globals.connectivity,
args.settings.no_build_isolation,
@ -373,7 +372,6 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
args.settings.index_locations,
args.settings.index_strategy,
args.settings.keyring_provider,
args.settings.setup_py,
args.settings.allow_empty_requirements,
globals.connectivity,
&args.settings.config_setting,
@ -461,7 +459,6 @@ async fn run(cli: Cli) -> Result<ExitStatus> {
args.settings.link_mode,
args.settings.compile_bytecode,
args.settings.hash_checking,
args.settings.setup_py,
globals.connectivity,
&args.settings.config_setting,
args.settings.no_build_isolation,

View File

@ -23,8 +23,8 @@ use uv_cli::{
use uv_client::Connectivity;
use uv_configuration::{
BuildOptions, Concurrency, ConfigSettings, ExtrasSpecification, HashCheckingMode,
IndexStrategy, KeyringProviderType, NoBinary, NoBuild, PreviewMode, Reinstall, SetupPyStrategy,
SourceStrategy, TargetTriple, Upgrade,
IndexStrategy, KeyringProviderType, NoBinary, NoBuild, PreviewMode, Reinstall, SourceStrategy,
TargetTriple, Upgrade,
};
use uv_normalize::PackageName;
use uv_python::{Prefix, PythonDownloads, PythonPreference, PythonVersion, Target};
@ -937,8 +937,6 @@ impl PipCompileSettings {
no_system,
generate_hashes,
no_generate_hashes,
legacy_setup_py,
no_legacy_setup_py,
no_build,
build,
no_binary,
@ -1023,7 +1021,6 @@ impl PipCompileSettings {
no_header: flag(no_header, header),
custom_compile_command,
generate_hashes: flag(generate_hashes, no_generate_hashes),
legacy_setup_py: flag(legacy_setup_py, no_legacy_setup_py),
python_version,
python_platform,
universal: flag(universal, no_universal),
@ -1076,8 +1073,6 @@ impl PipSyncSettings {
prefix,
allow_empty_requirements,
no_allow_empty_requirements,
legacy_setup_py,
no_legacy_setup_py,
no_build,
build,
no_binary,
@ -1118,7 +1113,6 @@ impl PipSyncSettings {
allow_empty_requirements,
no_allow_empty_requirements,
),
legacy_setup_py: flag(legacy_setup_py, no_legacy_setup_py),
python_version,
python_platform,
strict: flag(strict, no_strict),
@ -1175,8 +1169,6 @@ impl PipInstallSettings {
no_break_system_packages,
target,
prefix,
legacy_setup_py,
no_legacy_setup_py,
no_build,
build,
no_binary,
@ -1251,7 +1243,6 @@ impl PipInstallSettings {
extra,
all_extras: flag(all_extras, no_all_extras),
no_deps: flag(no_deps, deps),
legacy_setup_py: flag(legacy_setup_py, no_legacy_setup_py),
python_version,
python_platform,
require_hashes: flag(require_hashes, no_require_hashes),
@ -1839,7 +1830,6 @@ pub(crate) struct PipSettings {
pub(crate) no_header: bool,
pub(crate) custom_compile_command: Option<String>,
pub(crate) generate_hashes: bool,
pub(crate) setup_py: SetupPyStrategy,
pub(crate) config_setting: ConfigSettings,
pub(crate) python_version: Option<PythonVersion>,
pub(crate) python_platform: Option<TargetTriple>,
@ -1898,7 +1888,6 @@ impl PipSettings {
no_header,
custom_compile_command,
generate_hashes,
legacy_setup_py,
config_settings,
python_version,
python_platform,
@ -2025,15 +2014,6 @@ impl PipSettings {
.allow_empty_requirements
.combine(allow_empty_requirements)
.unwrap_or_default(),
setup_py: if args
.legacy_setup_py
.combine(legacy_setup_py)
.unwrap_or_default()
{
SetupPyStrategy::Setuptools
} else {
SetupPyStrategy::Pep517
},
no_build_isolation: args
.no_build_isolation
.combine(no_build_isolation)

View File

@ -4119,7 +4119,7 @@ fn trailing_slash() -> Result<()> {
Ok(())
}
/// Resolve a project without a `pyproject.toml`, using the PEP 517 build backend (default).
/// Resolve a project without a `pyproject.toml`, using the PEP 517 build backend.
#[test]
fn compile_legacy_sdist_pep_517() -> Result<()> {
let context = TestContext::new("3.12");
@ -4150,38 +4150,6 @@ fn compile_legacy_sdist_pep_517() -> Result<()> {
Ok(())
}
/// Resolve a project without a `pyproject.toml`, using `setuptools` directly.
#[test]
fn compile_legacy_sdist_setuptools() -> Result<()> {
let context = TestContext::new("3.12");
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("flake8 @ https://files.pythonhosted.org/packages/66/53/3ad4a3b74d609b3b9008a10075c40e7c8909eae60af53623c3888f7a529a/flake8-6.0.0.tar.gz")?;
uv_snapshot!(context.filters(), context.pip_compile()
.arg("requirements.in")
.arg("--legacy-setup-py"), @r###"
success: true
exit_code: 0
----- stdout -----
# This file was autogenerated by uv via the following command:
# uv pip compile --cache-dir [CACHE_DIR] requirements.in --legacy-setup-py
flake8 @ https://files.pythonhosted.org/packages/66/53/3ad4a3b74d609b3b9008a10075c40e7c8909eae60af53623c3888f7a529a/flake8-6.0.0.tar.gz
# via -r requirements.in
mccabe==0.7.0
# via flake8
pycodestyle==2.10.0
# via flake8
pyflakes==3.0.1
# via flake8
----- stderr -----
Resolved 4 packages in [TIME]
"###
);
Ok(())
}
/// Include hashes from the registry in the generated output.
#[test]
fn generate_hashes_registry() -> Result<()> {

View File

@ -2610,7 +2610,7 @@ fn incompatible_wheel() -> Result<()> {
Ok(())
}
/// Install a project without a `pyproject.toml`, using the PEP 517 build backend (default).
/// Install a project without a `pyproject.toml`, using the PEP 517 build backend.
#[test]
fn sync_legacy_sdist_pep_517() -> Result<()> {
let context = TestContext::new("3.12");
@ -2635,32 +2635,6 @@ fn sync_legacy_sdist_pep_517() -> Result<()> {
Ok(())
}
/// Install a project without a `pyproject.toml`, using `setuptools` directly.
#[test]
fn sync_legacy_sdist_setuptools() -> Result<()> {
let context = TestContext::new("3.12");
let requirements_in = context.temp_dir.child("requirements.in");
requirements_in.write_str("flake8 @ https://files.pythonhosted.org/packages/66/53/3ad4a3b74d609b3b9008a10075c40e7c8909eae60af53623c3888f7a529a/flake8-6.0.0.tar.gz")?;
uv_snapshot!(context.pip_sync()
.arg("requirements.in")
.arg("--legacy-setup-py"), @r###"
success: true
exit_code: 0
----- stdout -----
----- stderr -----
Resolved 1 package in [TIME]
Prepared 1 package in [TIME]
Installed 1 package in [TIME]
+ flake8==6.0.0 (from https://files.pythonhosted.org/packages/66/53/3ad4a3b74d609b3b9008a10075c40e7c8909eae60af53623c3888f7a529a/flake8-6.0.0.tar.gz)
"###
);
Ok(())
}
/// Sync using `--find-links` with a local directory.
#[test]
fn find_links() -> Result<()> {

View File

@ -143,7 +143,6 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: true,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -279,7 +278,6 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: true,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -416,7 +414,6 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -585,7 +582,6 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: true,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -700,7 +696,6 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -847,7 +842,6 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: true,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -1031,7 +1025,6 @@ fn resolve_index_url() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -1214,7 +1207,6 @@ fn resolve_index_url() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -1375,7 +1367,6 @@ fn resolve_find_links() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -1512,7 +1503,6 @@ fn resolve_top_level() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -1687,7 +1677,6 @@ fn resolve_top_level() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -1845,7 +1834,6 @@ fn resolve_top_level() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -1982,7 +1970,6 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -2102,7 +2089,6 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: true,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -2222,7 +2208,6 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -2344,7 +2329,6 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -2636,7 +2620,6 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -2807,7 +2790,6 @@ fn resolve_both() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: true,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -2970,7 +2952,6 @@ fn resolve_config_file() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: true,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -3185,7 +3166,6 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),
@ -3308,7 +3288,6 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
no_header: false,
custom_compile_command: None,
generate_hashes: false,
setup_py: Pep517,
config_setting: ConfigSettings(
{},
),

View File

@ -3678,8 +3678,6 @@ uv pip compile [OPTIONS] <SRC_FILE>...
<li><code>subprocess</code>: Use the <code>keyring</code> command for credential lookup</li>
</ul>
</dd><dt><code>--legacy-setup-py</code></dt><dd><p>Use legacy <code>setuptools</code> behavior when building source distributions without a <code>pyproject.toml</code></p>
</dd><dt><code>--link-mode</code> <i>link-mode</i></dt><dd><p>The method to use when installing packages from the global cache.</p>
<p>This option is only used when building source distributions.</p>
@ -4021,8 +4019,6 @@ uv pip sync [OPTIONS] <SRC_FILE>...
<li><code>subprocess</code>: Use the <code>keyring</code> command for credential lookup</li>
</ul>
</dd><dt><code>--legacy-setup-py</code></dt><dd><p>Use legacy <code>setuptools</code> behavior when building source distributions without a <code>pyproject.toml</code></p>
</dd><dt><code>--link-mode</code> <i>link-mode</i></dt><dd><p>The method to use when installing packages from the global cache.</p>
<p>Defaults to <code>clone</code> (also known as Copy-on-Write) on macOS, and <code>hardlink</code> on Linux and Windows.</p>
@ -4320,8 +4316,6 @@ uv pip install [OPTIONS] <PACKAGE|--requirement <REQUIREMENT>|--editable <EDITAB
<li><code>subprocess</code>: Use the <code>keyring</code> command for credential lookup</li>
</ul>
</dd><dt><code>--legacy-setup-py</code></dt><dd><p>Use legacy <code>setuptools</code> behavior when building source distributions without a <code>pyproject.toml</code></p>
</dd><dt><code>--link-mode</code> <i>link-mode</i></dt><dd><p>The method to use when installing packages from the global cache.</p>
<p>Defaults to <code>clone</code> (also known as Copy-on-Write) on macOS, and <code>hardlink</code> on Linux and Windows.</p>

View File

@ -1625,33 +1625,6 @@ use the `keyring` CLI to handle authentication.
---
#### [`legacy-setup-py`](#pip_legacy-setup-py) {: #pip_legacy-setup-py }
<span id="legacy-setup-py"></span>
Use legacy `setuptools` behavior when building source distributions without a
`pyproject.toml`.
**Default value**: `false`
**Type**: `bool`
**Example usage**:
=== "pyproject.toml"
```toml
[tool.uv.pip]
legacy-setup-py = true
```
=== "uv.toml"
```toml
[pip]
legacy-setup-py = true
```
---
#### [`link-mode`](#pip_link-mode) {: #pip_link-mode }
<span id="link-mode"></span>

7
uv.schema.json generated
View File

@ -721,13 +721,6 @@
}
]
},
"legacy-setup-py": {
"description": "Use legacy `setuptools` behavior when building source distributions without a `pyproject.toml`.",
"type": [
"boolean",
"null"
]
},
"link-mode": {
"description": "The method to use when installing packages from the global cache.\n\nDefaults to `clone` (also known as Copy-on-Write) on macOS, and `hardlink` on Linux and Windows.",
"anyOf": [