mirror of https://github.com/astral-sh/uv
Move warnings for conflicting modules into preview (#15253)
This commit is contained in:
parent
2c54d3929c
commit
b8049eaa20
|
|
@ -5443,6 +5443,7 @@ dependencies = [
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"tracing",
|
"tracing",
|
||||||
"uv-cache-info",
|
"uv-cache-info",
|
||||||
|
"uv-configuration",
|
||||||
"uv-distribution-filename",
|
"uv-distribution-filename",
|
||||||
"uv-fs",
|
"uv-fs",
|
||||||
"uv-normalize",
|
"uv-normalize",
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ bitflags::bitflags! {
|
||||||
const ADD_BOUNDS = 1 << 4;
|
const ADD_BOUNDS = 1 << 4;
|
||||||
const PACKAGE_CONFLICTS = 1 << 5;
|
const PACKAGE_CONFLICTS = 1 << 5;
|
||||||
const EXTRA_BUILD_DEPENDENCIES = 1 << 6;
|
const EXTRA_BUILD_DEPENDENCIES = 1 << 6;
|
||||||
|
const DETECT_MODULE_CONFLICTS = 1 << 7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,6 +33,7 @@ impl PreviewFeatures {
|
||||||
Self::ADD_BOUNDS => "add-bounds",
|
Self::ADD_BOUNDS => "add-bounds",
|
||||||
Self::PACKAGE_CONFLICTS => "package-conflicts",
|
Self::PACKAGE_CONFLICTS => "package-conflicts",
|
||||||
Self::EXTRA_BUILD_DEPENDENCIES => "extra-build-dependencies",
|
Self::EXTRA_BUILD_DEPENDENCIES => "extra-build-dependencies",
|
||||||
|
Self::DETECT_MODULE_CONFLICTS => "detect-module-conflicts",
|
||||||
_ => panic!("`flag_as_str` can only be used for exactly one feature flag"),
|
_ => panic!("`flag_as_str` can only be used for exactly one feature flag"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -76,6 +78,7 @@ impl FromStr for PreviewFeatures {
|
||||||
"add-bounds" => Self::ADD_BOUNDS,
|
"add-bounds" => Self::ADD_BOUNDS,
|
||||||
"package-conflicts" => Self::PACKAGE_CONFLICTS,
|
"package-conflicts" => Self::PACKAGE_CONFLICTS,
|
||||||
"extra-build-dependencies" => Self::EXTRA_BUILD_DEPENDENCIES,
|
"extra-build-dependencies" => Self::EXTRA_BUILD_DEPENDENCIES,
|
||||||
|
"detect-module-conflicts" => Self::DETECT_MODULE_CONFLICTS,
|
||||||
_ => {
|
_ => {
|
||||||
warn_user_once!("Unknown preview feature: `{part}`");
|
warn_user_once!("Unknown preview feature: `{part}`");
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -246,6 +249,10 @@ mod tests {
|
||||||
PreviewFeatures::EXTRA_BUILD_DEPENDENCIES.flag_as_str(),
|
PreviewFeatures::EXTRA_BUILD_DEPENDENCIES.flag_as_str(),
|
||||||
"extra-build-dependencies"
|
"extra-build-dependencies"
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
PreviewFeatures::DETECT_MODULE_CONFLICTS.flag_as_str(),
|
||||||
|
"detect-module-conflicts"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -390,7 +390,7 @@ impl BuildContext for BuildDispatch<'_> {
|
||||||
if wheels.len() == 1 { "" } else { "s" },
|
if wheels.len() == 1 { "" } else { "s" },
|
||||||
wheels.iter().map(ToString::to_string).join(", ")
|
wheels.iter().map(ToString::to_string).join(", ")
|
||||||
);
|
);
|
||||||
wheels = Installer::new(venv)
|
wheels = Installer::new(venv, self.preview)
|
||||||
.with_link_mode(self.link_mode)
|
.with_link_mode(self.link_mode)
|
||||||
.with_cache(self.cache)
|
.with_cache(self.cache)
|
||||||
.install(wheels)
|
.install(wheels)
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ name = "uv_install_wheel"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
uv-cache-info = { workspace = true }
|
uv-cache-info = { workspace = true }
|
||||||
|
uv-configuration = { workspace = true }
|
||||||
uv-distribution-filename = { workspace = true }
|
uv-distribution-filename = { workspace = true }
|
||||||
uv-fs = { workspace = true }
|
uv-fs = { workspace = true }
|
||||||
uv-normalize = { workspace = true }
|
uv-normalize = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -10,20 +10,33 @@ use std::sync::{Arc, Mutex};
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use tempfile::tempdir_in;
|
use tempfile::tempdir_in;
|
||||||
use tracing::{debug, instrument, trace};
|
use tracing::{debug, instrument, trace};
|
||||||
|
use uv_configuration::{Preview, PreviewFeatures};
|
||||||
use uv_distribution_filename::WheelFilename;
|
use uv_distribution_filename::WheelFilename;
|
||||||
use uv_fs::Simplified;
|
use uv_fs::Simplified;
|
||||||
use uv_warnings::{warn_user, warn_user_once};
|
use uv_warnings::{warn_user, warn_user_once};
|
||||||
use walkdir::WalkDir;
|
use walkdir::WalkDir;
|
||||||
|
|
||||||
|
#[allow(clippy::struct_field_names)]
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub struct Locks {
|
pub struct Locks {
|
||||||
/// The parent directory of a file in a synchronized copy
|
/// The parent directory of a file in a synchronized copy
|
||||||
copy_dir_locks: Mutex<FxHashMap<PathBuf, Arc<Mutex<()>>>>,
|
copy_dir_locks: Mutex<FxHashMap<PathBuf, Arc<Mutex<()>>>>,
|
||||||
/// Top level modules (excluding namespaces) we write to.
|
/// Top level modules (excluding namespaces) we write to.
|
||||||
modules: Mutex<FxHashMap<OsString, WheelFilename>>,
|
modules: Mutex<FxHashMap<OsString, WheelFilename>>,
|
||||||
|
/// Preview settings for feature flags.
|
||||||
|
preview: Preview,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Locks {
|
impl Locks {
|
||||||
|
/// Create a new Locks instance with the given preview settings.
|
||||||
|
pub fn new(preview: Preview) -> Self {
|
||||||
|
Self {
|
||||||
|
copy_dir_locks: Mutex::new(FxHashMap::default()),
|
||||||
|
modules: Mutex::new(FxHashMap::default()),
|
||||||
|
preview,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Warn when a module exists in multiple packages.
|
/// Warn when a module exists in multiple packages.
|
||||||
fn warn_module_conflict(&self, module: &OsStr, wheel_a: &WheelFilename) {
|
fn warn_module_conflict(&self, module: &OsStr, wheel_a: &WheelFilename) {
|
||||||
if let Some(wheel_b) = self
|
if let Some(wheel_b) = self
|
||||||
|
|
@ -32,6 +45,14 @@ impl Locks {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert(module.to_os_string(), wheel_a.clone())
|
.insert(module.to_os_string(), wheel_a.clone())
|
||||||
{
|
{
|
||||||
|
// Only warn if the preview feature is enabled
|
||||||
|
if !self
|
||||||
|
.preview
|
||||||
|
.is_enabled(PreviewFeatures::DETECT_MODULE_CONFLICTS)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Sort for consistent output, at least with two packages
|
// Sort for consistent output, at least with two packages
|
||||||
let (wheel_a, wheel_b) = if wheel_b.name > wheel_a.name {
|
let (wheel_a, wheel_b) = if wheel_b.name > wheel_a.name {
|
||||||
(&wheel_b, wheel_a)
|
(&wheel_b, wheel_a)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use tokio::sync::oneshot;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use uv_cache::Cache;
|
use uv_cache::Cache;
|
||||||
use uv_configuration::RAYON_INITIALIZE;
|
use uv_configuration::{Preview, RAYON_INITIALIZE};
|
||||||
use uv_distribution_types::CachedDist;
|
use uv_distribution_types::CachedDist;
|
||||||
use uv_install_wheel::{Layout, LinkMode};
|
use uv_install_wheel::{Layout, LinkMode};
|
||||||
use uv_python::PythonEnvironment;
|
use uv_python::PythonEnvironment;
|
||||||
|
|
@ -21,11 +21,13 @@ pub struct Installer<'a> {
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
/// The metadata associated with the [`Installer`].
|
/// The metadata associated with the [`Installer`].
|
||||||
metadata: bool,
|
metadata: bool,
|
||||||
|
/// Preview settings for the installer.
|
||||||
|
preview: Preview,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Installer<'a> {
|
impl<'a> Installer<'a> {
|
||||||
/// Initialize a new installer.
|
/// Initialize a new installer.
|
||||||
pub fn new(venv: &'a PythonEnvironment) -> Self {
|
pub fn new(venv: &'a PythonEnvironment, preview: Preview) -> Self {
|
||||||
Self {
|
Self {
|
||||||
venv,
|
venv,
|
||||||
link_mode: LinkMode::default(),
|
link_mode: LinkMode::default(),
|
||||||
|
|
@ -33,6 +35,7 @@ impl<'a> Installer<'a> {
|
||||||
reporter: None,
|
reporter: None,
|
||||||
name: Some("uv".to_string()),
|
name: Some("uv".to_string()),
|
||||||
metadata: true,
|
metadata: true,
|
||||||
|
preview,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -88,6 +91,7 @@ impl<'a> Installer<'a> {
|
||||||
reporter,
|
reporter,
|
||||||
name: installer_name,
|
name: installer_name,
|
||||||
metadata: installer_metadata,
|
metadata: installer_metadata,
|
||||||
|
preview,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
if cache.is_some_and(Cache::is_temporary) {
|
if cache.is_some_and(Cache::is_temporary) {
|
||||||
|
|
@ -113,6 +117,7 @@ impl<'a> Installer<'a> {
|
||||||
reporter.as_ref(),
|
reporter.as_ref(),
|
||||||
relocatable,
|
relocatable,
|
||||||
installer_metadata,
|
installer_metadata,
|
||||||
|
preview,
|
||||||
);
|
);
|
||||||
|
|
||||||
// This may fail if the main task was cancelled.
|
// This may fail if the main task was cancelled.
|
||||||
|
|
@ -143,6 +148,7 @@ impl<'a> Installer<'a> {
|
||||||
self.reporter.as_ref(),
|
self.reporter.as_ref(),
|
||||||
self.venv.relocatable(),
|
self.venv.relocatable(),
|
||||||
self.metadata,
|
self.metadata,
|
||||||
|
self.preview,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -157,10 +163,11 @@ fn install(
|
||||||
reporter: Option<&Arc<dyn Reporter>>,
|
reporter: Option<&Arc<dyn Reporter>>,
|
||||||
relocatable: bool,
|
relocatable: bool,
|
||||||
installer_metadata: bool,
|
installer_metadata: bool,
|
||||||
|
preview: Preview,
|
||||||
) -> Result<Vec<CachedDist>> {
|
) -> Result<Vec<CachedDist>> {
|
||||||
// Initialize the threadpool with the user settings.
|
// Initialize the threadpool with the user settings.
|
||||||
LazyLock::force(&RAYON_INITIALIZE);
|
LazyLock::force(&RAYON_INITIALIZE);
|
||||||
let locks = uv_install_wheel::Locks::default();
|
let locks = uv_install_wheel::Locks::new(preview);
|
||||||
wheels.par_iter().try_for_each(|wheel| {
|
wheels.par_iter().try_for_each(|wheel| {
|
||||||
uv_install_wheel::install_wheel(
|
uv_install_wheel::install_wheel(
|
||||||
layout,
|
layout,
|
||||||
|
|
|
||||||
|
|
@ -611,6 +611,7 @@ pub(crate) async fn pip_install(
|
||||||
installer_metadata,
|
installer_metadata,
|
||||||
dry_run,
|
dry_run,
|
||||||
printer,
|
printer,
|
||||||
|
preview,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -450,6 +450,7 @@ pub(crate) async fn install(
|
||||||
installer_metadata: bool,
|
installer_metadata: bool,
|
||||||
dry_run: DryRun,
|
dry_run: DryRun,
|
||||||
printer: Printer,
|
printer: Printer,
|
||||||
|
preview: uv_configuration::Preview,
|
||||||
) -> Result<Changelog, Error> {
|
) -> Result<Changelog, Error> {
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
|
|
||||||
|
|
@ -571,7 +572,7 @@ pub(crate) async fn install(
|
||||||
let mut installs = wheels.into_iter().chain(cached).collect::<Vec<_>>();
|
let mut installs = wheels.into_iter().chain(cached).collect::<Vec<_>>();
|
||||||
if !installs.is_empty() {
|
if !installs.is_empty() {
|
||||||
let start = std::time::Instant::now();
|
let start = std::time::Instant::now();
|
||||||
installs = uv_installer::Installer::new(venv)
|
installs = uv_installer::Installer::new(venv, preview)
|
||||||
.with_link_mode(link_mode)
|
.with_link_mode(link_mode)
|
||||||
.with_cache(cache)
|
.with_cache(cache)
|
||||||
.with_installer_metadata(installer_metadata)
|
.with_installer_metadata(installer_metadata)
|
||||||
|
|
|
||||||
|
|
@ -550,6 +550,7 @@ pub(crate) async fn pip_sync(
|
||||||
installer_metadata,
|
installer_metadata,
|
||||||
dry_run,
|
dry_run,
|
||||||
printer,
|
printer,
|
||||||
|
preview,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2173,6 +2173,7 @@ pub(crate) async fn sync_environment(
|
||||||
installer_metadata,
|
installer_metadata,
|
||||||
dry_run,
|
dry_run,
|
||||||
printer,
|
printer,
|
||||||
|
preview,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
@ -2434,6 +2435,7 @@ pub(crate) async fn update_environment(
|
||||||
installer_metadata,
|
installer_metadata,
|
||||||
dry_run,
|
dry_run,
|
||||||
printer,
|
printer,
|
||||||
|
preview,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -809,6 +809,7 @@ pub(super) async fn do_sync(
|
||||||
installer_metadata,
|
installer_metadata,
|
||||||
dry_run,
|
dry_run,
|
||||||
printer,
|
printer,
|
||||||
|
preview,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12486,7 +12486,7 @@ fn overlapping_packages_warning() -> Result<()> {
|
||||||
.child("__init__.py")
|
.child("__init__.py")
|
||||||
.touch()?;
|
.touch()?;
|
||||||
|
|
||||||
// Check that overlapping packages show a warning
|
// Check that overlapping packages don't show a warning by default
|
||||||
uv_snapshot!(context.filters(), context.pip_install()
|
uv_snapshot!(context.filters(), context.pip_install()
|
||||||
.arg("--no-deps")
|
.arg("--no-deps")
|
||||||
.arg(&built_by_uv)
|
.arg(&built_by_uv)
|
||||||
|
|
@ -12495,6 +12495,29 @@ fn overlapping_packages_warning() -> Result<()> {
|
||||||
exit_code: 0
|
exit_code: 0
|
||||||
----- stdout -----
|
----- stdout -----
|
||||||
|
|
||||||
|
----- stderr -----
|
||||||
|
Resolved 2 packages in [TIME]
|
||||||
|
Prepared 2 packages in [TIME]
|
||||||
|
Installed 2 packages in [TIME]
|
||||||
|
+ also-built-by-uv==0.1.0 (from file://[TEMP_DIR]/also-built-by-uv)
|
||||||
|
+ built-by-uv==0.1.0 (from file://[WORKSPACE]/scripts/packages/built-by-uv)
|
||||||
|
"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Clean up for the next test
|
||||||
|
context.venv().arg("--clear").assert().success();
|
||||||
|
|
||||||
|
// Check that overlapping packages show a warning when preview feature is enabled
|
||||||
|
uv_snapshot!(context.filters(), context.pip_install()
|
||||||
|
.arg("--no-deps")
|
||||||
|
.arg("--preview-features")
|
||||||
|
.arg("detect-module-conflicts")
|
||||||
|
.arg(&built_by_uv)
|
||||||
|
.arg(also_build_by_uv.path()), @r"
|
||||||
|
success: true
|
||||||
|
exit_code: 0
|
||||||
|
----- stdout -----
|
||||||
|
|
||||||
----- stderr -----
|
----- stderr -----
|
||||||
Resolved 2 packages in [TIME]
|
Resolved 2 packages in [TIME]
|
||||||
Prepared 2 packages in [TIME]
|
Prepared 2 packages in [TIME]
|
||||||
|
|
|
||||||
|
|
@ -7720,7 +7720,7 @@ fn preview_features() {
|
||||||
show_settings: true,
|
show_settings: true,
|
||||||
preview: Preview {
|
preview: Preview {
|
||||||
flags: PreviewFeatures(
|
flags: PreviewFeatures(
|
||||||
PYTHON_INSTALL_DEFAULT | PYTHON_UPGRADE | JSON_OUTPUT | PYLOCK | ADD_BOUNDS | PACKAGE_CONFLICTS | EXTRA_BUILD_DEPENDENCIES,
|
PYTHON_INSTALL_DEFAULT | PYTHON_UPGRADE | JSON_OUTPUT | PYLOCK | ADD_BOUNDS | PACKAGE_CONFLICTS | EXTRA_BUILD_DEPENDENCIES | DETECT_MODULE_CONFLICTS,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
python_preference: Managed,
|
python_preference: Managed,
|
||||||
|
|
@ -7946,7 +7946,7 @@ fn preview_features() {
|
||||||
show_settings: true,
|
show_settings: true,
|
||||||
preview: Preview {
|
preview: Preview {
|
||||||
flags: PreviewFeatures(
|
flags: PreviewFeatures(
|
||||||
PYTHON_INSTALL_DEFAULT | PYTHON_UPGRADE | JSON_OUTPUT | PYLOCK | ADD_BOUNDS | PACKAGE_CONFLICTS | EXTRA_BUILD_DEPENDENCIES,
|
PYTHON_INSTALL_DEFAULT | PYTHON_UPGRADE | JSON_OUTPUT | PYLOCK | ADD_BOUNDS | PACKAGE_CONFLICTS | EXTRA_BUILD_DEPENDENCIES | DETECT_MODULE_CONFLICTS,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
python_preference: Managed,
|
python_preference: Managed,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue