Skip to content

Commit 69c9255

Browse files
committed
Show an interpreter-focused message for --target and --prefix
1 parent 1343b16 commit 69c9255

File tree

8 files changed

+165
-96
lines changed

8 files changed

+165
-96
lines changed

crates/uv/src/commands/pip/install.rs

+27-16
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ use uv_installer::{SatisfiesResult, SitePackages};
2222
use uv_pep508::PackageName;
2323
use uv_pypi_types::{Conflicts, Requirement};
2424
use uv_python::{
25-
EnvironmentPreference, Prefix, PythonEnvironment, PythonRequest, PythonVersion, Target,
25+
EnvironmentPreference, Prefix, PythonEnvironment, PythonInstallation, PythonPreference,
26+
PythonRequest, PythonVersion, Target,
2627
};
2728
use uv_requirements::{RequirementsSource, RequirementsSpecification};
2829
use uv_resolver::{
@@ -32,8 +33,8 @@ use uv_resolver::{
3233
use uv_types::{BuildIsolation, HashStrategy};
3334

3435
use crate::commands::pip::loggers::{DefaultInstallLogger, DefaultResolveLogger, InstallLogger};
35-
use crate::commands::pip::operations::report_target_environment;
3636
use crate::commands::pip::operations::Modifications;
37+
use crate::commands::pip::operations::{report_interpreter, report_target_environment};
3738
use crate::commands::pip::{operations, resolution_markers, resolution_tags};
3839
use crate::commands::{diagnostics, ExitStatus, SharedState};
3940
use crate::printer::Printer;
@@ -76,6 +77,7 @@ pub(crate) async fn pip_install(
7677
break_system_packages: bool,
7778
target: Option<Target>,
7879
prefix: Option<Prefix>,
80+
python_preference: PythonPreference,
7981
concurrency: Concurrency,
8082
native_tls: bool,
8183
allow_insecure_host: &[TrustedHost],
@@ -138,22 +140,31 @@ pub(crate) async fn pip_install(
138140
)
139141
.collect();
140142

141-
// Determine whether we're modifying the discovered environment, or a separate target.
142-
let mutable = !(target.is_some() || prefix.is_some());
143-
144143
// Detect the current Python interpreter.
145-
let environment = PythonEnvironment::find(
146-
&python
147-
.as_deref()
148-
.map(PythonRequest::parse)
149-
.unwrap_or_default(),
150-
EnvironmentPreference::from_system_flag(system, mutable),
151-
&cache,
152-
)?;
153-
154-
if mutable {
144+
let environment = if target.is_some() || prefix.is_some() {
145+
let installation = PythonInstallation::find(
146+
&python
147+
.as_deref()
148+
.map(PythonRequest::parse)
149+
.unwrap_or_default(),
150+
EnvironmentPreference::from_system_flag(system, false),
151+
python_preference,
152+
&cache,
153+
)?;
154+
report_interpreter(&installation, true, printer)?;
155+
PythonEnvironment::from_installation(installation)
156+
} else {
157+
let environment = PythonEnvironment::find(
158+
&python
159+
.as_deref()
160+
.map(PythonRequest::parse)
161+
.unwrap_or_default(),
162+
EnvironmentPreference::from_system_flag(system, true),
163+
&cache,
164+
)?;
155165
report_target_environment(&environment, &cache, printer)?;
156-
}
166+
environment
167+
};
157168

158169
// Apply any `--target` or `--prefix` directories.
159170
let environment = if let Some(target) = target {

crates/uv/src/commands/pip/operations.rs

+59-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use uv_installer::{Plan, Planner, Preparer, SitePackages};
3030
use uv_normalize::{GroupName, PackageName};
3131
use uv_platform_tags::Tags;
3232
use uv_pypi_types::{Conflicts, ResolverMarkerEnvironment};
33-
use uv_python::PythonEnvironment;
33+
use uv_python::{PythonEnvironment, PythonInstallation};
3434
use uv_requirements::{
3535
LookaheadResolver, NamedRequirementsResolver, RequirementsSource, RequirementsSpecification,
3636
SourceTreeResolver,
@@ -566,14 +566,71 @@ pub(crate) async fn install(
566566
Ok(changelog)
567567
}
568568

569+
/// Display a message about the interpreter that was selected for the operation.
570+
pub(crate) fn report_interpreter(
571+
python: &PythonInstallation,
572+
dimmed: bool,
573+
printer: Printer,
574+
) -> Result<(), Error> {
575+
let managed = python.source().is_managed();
576+
let implementation = python.implementation();
577+
let interpreter = python.interpreter();
578+
579+
if dimmed {
580+
if managed {
581+
writeln!(
582+
printer.stderr(),
583+
"{}",
584+
format!(
585+
"Using {} {}",
586+
implementation.pretty(),
587+
interpreter.python_version()
588+
)
589+
.dimmed()
590+
)?;
591+
} else {
592+
writeln!(
593+
printer.stderr(),
594+
"{}",
595+
format!(
596+
"Using {} {} interpreter at: {}",
597+
implementation.pretty(),
598+
interpreter.python_version(),
599+
interpreter.sys_executable().user_display()
600+
)
601+
.dimmed()
602+
)?;
603+
}
604+
} else {
605+
if managed {
606+
writeln!(
607+
printer.stderr(),
608+
"Using {} {}",
609+
implementation.pretty(),
610+
interpreter.python_version().cyan()
611+
)?;
612+
} else {
613+
writeln!(
614+
printer.stderr(),
615+
"Using {} {} interpreter at: {}",
616+
implementation.pretty(),
617+
interpreter.python_version(),
618+
interpreter.sys_executable().user_display().cyan()
619+
)?;
620+
}
621+
}
622+
623+
Ok(())
624+
}
625+
569626
/// Display a message about the target environment for the operation.
570627
pub(crate) fn report_target_environment(
571628
env: &PythonEnvironment,
572629
cache: &Cache,
573630
printer: Printer,
574631
) -> Result<(), Error> {
575632
let message = format!(
576-
"Using Python {} environment at {}",
633+
"Using Python {} environment at: {}",
577634
env.interpreter().python_version(),
578635
env.root().user_display()
579636
);

crates/uv/src/commands/pip/sync.rs

+27-16
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use uv_installer::SitePackages;
1919
use uv_pep508::PackageName;
2020
use uv_pypi_types::Conflicts;
2121
use uv_python::{
22-
EnvironmentPreference, Prefix, PythonEnvironment, PythonRequest, PythonVersion, Target,
22+
EnvironmentPreference, Prefix, PythonEnvironment, PythonInstallation, PythonPreference,
23+
PythonRequest, PythonVersion, Target,
2324
};
2425
use uv_requirements::{RequirementsSource, RequirementsSpecification};
2526
use uv_resolver::{
@@ -29,8 +30,8 @@ use uv_resolver::{
2930
use uv_types::{BuildIsolation, HashStrategy};
3031

3132
use crate::commands::pip::loggers::{DefaultInstallLogger, DefaultResolveLogger};
32-
use crate::commands::pip::operations::report_target_environment;
3333
use crate::commands::pip::operations::Modifications;
34+
use crate::commands::pip::operations::{report_interpreter, report_target_environment};
3435
use crate::commands::pip::{operations, resolution_markers, resolution_tags};
3536
use crate::commands::{diagnostics, ExitStatus, SharedState};
3637
use crate::printer::Printer;
@@ -65,6 +66,7 @@ pub(crate) async fn pip_sync(
6566
target: Option<Target>,
6667
prefix: Option<Prefix>,
6768
sources: SourceStrategy,
69+
python_preference: PythonPreference,
6870
concurrency: Concurrency,
6971
native_tls: bool,
7072
allow_insecure_host: &[TrustedHost],
@@ -122,22 +124,31 @@ pub(crate) async fn pip_sync(
122124
}
123125
}
124126

125-
// Determine whether we're modifying the discovered environment, or a separate target.
126-
let mutable = !(target.is_some() || prefix.is_some());
127-
128127
// Detect the current Python interpreter.
129-
let environment = PythonEnvironment::find(
130-
&python
131-
.as_deref()
132-
.map(PythonRequest::parse)
133-
.unwrap_or_default(),
134-
EnvironmentPreference::from_system_flag(system, mutable),
135-
&cache,
136-
)?;
137-
138-
if mutable {
128+
let environment = if target.is_some() || prefix.is_some() {
129+
let installation = PythonInstallation::find(
130+
&python
131+
.as_deref()
132+
.map(PythonRequest::parse)
133+
.unwrap_or_default(),
134+
EnvironmentPreference::from_system_flag(system, false),
135+
python_preference,
136+
&cache,
137+
)?;
138+
report_interpreter(&installation, true, printer)?;
139+
PythonEnvironment::from_installation(installation)
140+
} else {
141+
let environment = PythonEnvironment::find(
142+
&python
143+
.as_deref()
144+
.map(PythonRequest::parse)
145+
.unwrap_or_default(),
146+
EnvironmentPreference::from_system_flag(system, true),
147+
&cache,
148+
)?;
139149
report_target_environment(&environment, &cache, printer)?;
140-
}
150+
environment
151+
};
141152

142153
// Apply any `--target` or `--prefix` directories.
143154
let environment = if let Some(target) = target {

crates/uv/src/commands/venv.rs

+18-37
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use uv_warnings::{warn_user, warn_user_once};
3131
use uv_workspace::{DiscoveryOptions, VirtualProject, WorkspaceError};
3232

3333
use crate::commands::pip::loggers::{DefaultInstallLogger, InstallLogger};
34-
use crate::commands::pip::operations::Changelog;
34+
use crate::commands::pip::operations::{report_interpreter, Changelog};
3535
use crate::commands::project::{validate_requires_python, WorkspacePython};
3636
use crate::commands::reporters::PythonDownloadReporter;
3737
use crate::commands::{ExitStatus, SharedState};
@@ -201,23 +201,23 @@ async fn venv_impl(
201201
.into_diagnostic()?;
202202

203203
// Locate the Python interpreter to use in the environment
204-
let python = PythonInstallation::find_or_download(
205-
python_request.as_ref(),
206-
EnvironmentPreference::OnlySystem,
207-
python_preference,
208-
python_downloads,
209-
&client_builder,
210-
cache,
211-
Some(&reporter),
212-
install_mirrors.python_install_mirror.as_deref(),
213-
install_mirrors.pypy_install_mirror.as_deref(),
214-
)
215-
.await
216-
.into_diagnostic()?;
217-
218-
let managed = python.source().is_managed();
219-
let implementation = python.implementation();
220-
let interpreter = python.into_interpreter();
204+
let interpreter = {
205+
let python = PythonInstallation::find_or_download(
206+
python_request.as_ref(),
207+
EnvironmentPreference::OnlySystem,
208+
python_preference,
209+
python_downloads,
210+
&client_builder,
211+
cache,
212+
Some(&reporter),
213+
install_mirrors.python_install_mirror.as_deref(),
214+
install_mirrors.pypy_install_mirror.as_deref(),
215+
)
216+
.await
217+
.into_diagnostic()?;
218+
report_interpreter(&python, false, printer).into_diagnostic()?;
219+
python.into_interpreter()
220+
};
221221

222222
// Add all authenticated sources to the cache.
223223
for index in index_locations.allowed_indexes() {
@@ -226,25 +226,6 @@ async fn venv_impl(
226226
}
227227
}
228228

229-
if managed {
230-
writeln!(
231-
printer.stderr(),
232-
"Using {} {}",
233-
implementation.pretty(),
234-
interpreter.python_version().cyan()
235-
)
236-
.into_diagnostic()?;
237-
} else {
238-
writeln!(
239-
printer.stderr(),
240-
"Using {} {} interpreter at: {}",
241-
implementation.pretty(),
242-
interpreter.python_version(),
243-
interpreter.sys_executable().user_display().cyan()
244-
)
245-
.into_diagnostic()?;
246-
}
247-
248229
// Check if the discovered Python version is incompatible with the current workspace
249230
if let Some(requires_python) = requires_python {
250231
match validate_requires_python(

crates/uv/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
438438
args.settings.target,
439439
args.settings.prefix,
440440
args.settings.sources,
441+
globals.python_preference,
441442
globals.concurrency,
442443
globals.native_tls,
443444
&globals.allow_insecure_host,
@@ -526,6 +527,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
526527
args.settings.break_system_packages,
527528
args.settings.target,
528529
args.settings.prefix,
530+
globals.python_preference,
529531
globals.concurrency,
530532
globals.native_tls,
531533
&globals.allow_insecure_host,

crates/uv/tests/it/export.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ fn relative_path() -> Result<()> {
759759
----- stdout -----
760760
761761
----- stderr -----
762-
Using Python 3.12.[X] environment at [VENV]/
762+
Using Python 3.12.[X] environment at: [VENV]/
763763
Resolved 3 packages in [TIME]
764764
Prepared 3 packages in [TIME]
765765
Installed 3 packages in [TIME]

0 commit comments

Comments
 (0)