Skip to content

Commit 1517ffc

Browse files
committed
Show an interpreter-focused message for --target and --prefix
1 parent 8c8a1f0 commit 1517ffc

File tree

8 files changed

+166
-96
lines changed

8 files changed

+166
-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,
@@ -571,14 +571,71 @@ pub(crate) async fn install(
571571
Ok(changelog)
572572
}
573573

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

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
@@ -437,6 +437,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
437437
args.settings.target,
438438
args.settings.prefix,
439439
args.settings.sources,
440+
globals.python_preference,
440441
globals.concurrency,
441442
globals.native_tls,
442443
&globals.allow_insecure_host,
@@ -525,6 +526,7 @@ async fn run(mut cli: Cli) -> Result<ExitStatus> {
525526
args.settings.break_system_packages,
526527
args.settings.target,
527528
args.settings.prefix,
529+
globals.python_preference,
528530
globals.concurrency,
529531
globals.native_tls,
530532
&globals.allow_insecure_host,

crates/uv/tests/it/export.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,7 @@ fn relative_path() -> Result<()> {
864864
----- stdout -----
865865
866866
----- stderr -----
867-
Using Python 3.12.[X] environment at [VENV]/
867+
Using Python 3.12.[X] environment at: [VENV]/
868868
Resolved 3 packages in [TIME]
869869
Prepared 3 packages in [TIME]
870870
Installed 3 packages in [TIME]

0 commit comments

Comments
 (0)