Use relocatable virtual environments by default (#17770)

Under the `relocatable-envs-default` preview feature

See #13994
This commit is contained in:
Zanie Blue
2026-02-04 08:30:34 -06:00
committed by GitHub
parent 7c06784271
commit d44e65e9ed
6 changed files with 74 additions and 2 deletions
+8 -1
View File
@@ -3170,9 +3170,16 @@ pub struct VenvArgs {
/// absolute paths), the entrypoints and scripts themselves will _not_ be relocatable. In other
/// words, copying those entrypoints and scripts to a location outside the environment will not
/// work, as they reference paths relative to the environment itself.
#[arg(long)]
#[arg(long, overrides_with("no_relocatable"))]
pub relocatable: bool,
/// Don't make the virtual environment relocatable.
///
/// Disables the default relocatable behavior when the `relocatable-envs-default` preview
/// feature is enabled.
#[arg(long, overrides_with("relocatable"), hide = true)]
pub no_relocatable: bool,
#[command(flatten)]
pub index_args: IndexArgs,
+7
View File
@@ -36,6 +36,7 @@ pub enum PreviewFeature {
GcsEndpoint = 1 << 21,
AdjustUlimit = 1 << 22,
SpecialCondaEnvNames = 1 << 23,
RelocatableEnvsDefault = 1 << 24,
}
impl PreviewFeature {
@@ -66,6 +67,7 @@ impl PreviewFeature {
Self::GcsEndpoint => "gcs-endpoint",
Self::AdjustUlimit => "adjust-ulimit",
Self::SpecialCondaEnvNames => "special-conda-env-names",
Self::RelocatableEnvsDefault => "relocatable-envs-default",
}
}
}
@@ -109,6 +111,7 @@ impl FromStr for PreviewFeature {
"metadata-json" => Self::MetadataJson,
"adjust-ulimit" => Self::AdjustUlimit,
"special-conda-env-names" => Self::SpecialCondaEnvNames,
"relocatable-envs-default" => Self::RelocatableEnvsDefault,
_ => return Err(PreviewFeatureParseError),
})
}
@@ -336,5 +339,9 @@ mod tests {
PreviewFeature::SpecialCondaEnvNames.as_str(),
"special-conda-env-names"
);
assert_eq!(
PreviewFeature::RelocatableEnvsDefault.as_str(),
"relocatable-envs-default"
);
}
}
+5 -1
View File
@@ -1247,7 +1247,11 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
args.no_project,
&cache,
printer,
args.relocatable,
args.relocatable
|| (globals
.preview
.is_enabled(PreviewFeature::RelocatableEnvsDefault)
&& !args.no_relocatable),
globals.preview,
)
.await
+3
View File
@@ -3347,6 +3347,7 @@ pub(crate) struct VenvSettings {
pub(crate) prompt: Option<String>,
pub(crate) system_site_packages: bool,
pub(crate) relocatable: bool,
pub(crate) no_relocatable: bool,
pub(crate) no_project: bool,
pub(crate) refresh: Refresh,
pub(crate) settings: PipSettings,
@@ -3371,6 +3372,7 @@ impl VenvSettings {
prompt,
system_site_packages,
relocatable,
no_relocatable,
index_args,
index_strategy,
keyring_provider,
@@ -3396,6 +3398,7 @@ impl VenvSettings {
system_site_packages,
no_project,
relocatable,
no_relocatable,
refresh: Refresh::from(refresh),
settings: PipSettings::combine(
PipOptions {
+2
View File
@@ -7931,6 +7931,7 @@ fn preview_features() {
GcsEndpoint,
AdjustUlimit,
SpecialCondaEnvNames,
RelocatableEnvsDefault,
],
},
python_preference: Managed,
@@ -8190,6 +8191,7 @@ fn preview_features() {
GcsEndpoint,
AdjustUlimit,
SpecialCondaEnvNames,
RelocatableEnvsDefault,
],
},
python_preference: Managed,
+49
View File
@@ -1304,6 +1304,55 @@ fn verify_pyvenv_cfg_relocatable() {
));
}
/// With `relocatable-envs-default` preview feature, venvs are relocatable by default.
#[test]
fn relocatable_envs_default_preview() {
let context = TestContext::new("3.12");
// Create a virtual environment with the preview feature enabled.
context
.venv()
.arg(context.venv.as_os_str())
.arg("--clear")
.arg("--python")
.arg("3.12")
.arg("--preview-features")
.arg("relocatable-envs-default")
.assert()
.success();
let pyvenv_cfg = context.venv.child("pyvenv.cfg");
pyvenv_cfg.assert(predicates::path::is_file());
// Relocatable flag is set by default under preview.
pyvenv_cfg.assert(predicates::str::contains("relocatable = true"));
}
/// With `relocatable-envs-default` preview feature, `--no-relocatable` opts out.
#[test]
fn relocatable_envs_default_no_relocatable() {
let context = TestContext::new("3.12");
// Create a virtual environment with the preview feature but opt out.
context
.venv()
.arg(context.venv.as_os_str())
.arg("--clear")
.arg("--python")
.arg("3.12")
.arg("--preview-features")
.arg("relocatable-envs-default")
.arg("--no-relocatable")
.assert()
.success();
let pyvenv_cfg = context.venv.child("pyvenv.cfg");
pyvenv_cfg.assert(predicates::path::is_file());
// Relocatable flag is NOT set because of --no-relocatable.
pyvenv_cfg.assert(predicates::str::contains("relocatable").not());
}
/// Ensure that a nested virtual environment uses the same `home` directory as the parent.
#[test]
fn verify_nested_pyvenv_cfg() -> Result<()> {