@@ -44,7 +44,8 @@ use crate::commands::pip::loggers::{
4444use crate :: commands:: pip:: operations:: Modifications ;
4545use crate :: commands:: project:: lock:: LockMode ;
4646use crate :: commands:: project:: {
47- init_script_python_requirement, validate_script_requires_python, ProjectError , ScriptPython ,
47+ init_script_python_requirement, validate_script_requires_python, ProjectError ,
48+ ProjectInterpreter , ScriptPython ,
4849} ;
4950use crate :: commands:: reporters:: { PythonDownloadReporter , ResolverReporter } ;
5051use crate :: commands:: { diagnostics, pip, project, ExitStatus , SharedState } ;
@@ -214,22 +215,43 @@ pub(crate) async fn add(
214215 }
215216 }
216217
217- // Discover or create the virtual environment.
218- let venv = project:: get_or_init_environment (
219- project. workspace ( ) ,
220- python. as_deref ( ) . map ( PythonRequest :: parse) ,
221- python_preference,
222- python_downloads,
223- connectivity,
224- native_tls,
225- allow_insecure_host,
226- no_config,
227- cache,
228- printer,
229- )
230- . await ?;
218+ if frozen || no_sync {
219+ // Discover the interpreter.
220+ let interpreter = ProjectInterpreter :: discover (
221+ project. workspace ( ) ,
222+ project_dir,
223+ python. as_deref ( ) . map ( PythonRequest :: parse) ,
224+ python_preference,
225+ python_downloads,
226+ connectivity,
227+ native_tls,
228+ allow_insecure_host,
229+ no_config,
230+ cache,
231+ printer,
232+ )
233+ . await ?
234+ . into_interpreter ( ) ;
235+
236+ Target :: Project ( project, Box :: new ( PythonTarget :: Interpreter ( interpreter) ) )
237+ } else {
238+ // Discover or create the virtual environment.
239+ let venv = project:: get_or_init_environment (
240+ project. workspace ( ) ,
241+ python. as_deref ( ) . map ( PythonRequest :: parse) ,
242+ python_preference,
243+ python_downloads,
244+ connectivity,
245+ native_tls,
246+ allow_insecure_host,
247+ no_config,
248+ cache,
249+ printer,
250+ )
251+ . await ?;
231252
232- Target :: Project ( project, venv)
253+ Target :: Project ( project, Box :: new ( PythonTarget :: Environment ( venv) ) )
254+ }
233255 } ;
234256
235257 let client_builder = BaseClientBuilder :: new ( )
@@ -576,8 +598,8 @@ pub(crate) async fn add(
576598 }
577599 } ;
578600
579- let ( project, venv ) = match target {
580- Target :: Project ( project, venv ) => ( project, venv ) ,
601+ let ( project, environment ) = match target {
602+ Target :: Project ( project, environment ) => ( project, environment ) ,
581603 // If `--script`, exit early. There's no reason to lock and sync.
582604 Target :: Script ( script, _) => {
583605 writeln ! (
@@ -627,10 +649,9 @@ pub(crate) async fn add(
627649 project,
628650 & mut toml,
629651 & edits,
630- & venv ,
652+ & environment ,
631653 state,
632654 locked,
633- no_sync,
634655 & dependency_type,
635656 raw_sources,
636657 settings. as_ref ( ) ,
@@ -688,10 +709,9 @@ async fn lock_and_sync(
688709 mut project : VirtualProject ,
689710 toml : & mut PyProjectTomlMut ,
690711 edits : & [ DependencyEdit ] ,
691- venv : & PythonEnvironment ,
712+ environment : & PythonTarget ,
692713 state : SharedState ,
693714 locked : bool ,
694- no_sync : bool ,
695715 dependency_type : & DependencyType ,
696716 raw_sources : bool ,
697717 settings : ResolverInstallerSettingsRef < ' _ > ,
@@ -704,9 +724,9 @@ async fn lock_and_sync(
704724 printer : Printer ,
705725) -> Result < ( ) , ProjectError > {
706726 let mode = if locked {
707- LockMode :: Locked ( venv . interpreter ( ) )
727+ LockMode :: Locked ( environment . interpreter ( ) )
708728 } else {
709- LockMode :: Write ( venv . interpreter ( ) )
729+ LockMode :: Write ( environment . interpreter ( ) )
710730 } ;
711731
712732 let mut lock = project:: lock:: do_safe_lock (
@@ -846,9 +866,10 @@ async fn lock_and_sync(
846866 }
847867 }
848868
849- if no_sync {
869+ let PythonTarget :: Environment ( venv) = environment else {
870+ // If we're not syncing, exit early.
850871 return Ok ( ( ) ) ;
851- }
872+ } ;
852873
853874 // Sync the environment.
854875 let ( extras, dev) = match dependency_type {
@@ -1024,8 +1045,9 @@ fn resolve_requirement(
10241045enum Target {
10251046 /// A PEP 723 script, with inline metadata.
10261047 Script ( Pep723Script , Box < Interpreter > ) ,
1048+
10271049 /// A project with a `pyproject.toml`.
1028- Project ( VirtualProject , PythonEnvironment ) ,
1050+ Project ( VirtualProject , Box < PythonTarget > ) ,
10291051}
10301052
10311053impl Target {
@@ -1038,6 +1060,24 @@ impl Target {
10381060 }
10391061}
10401062
1063+ /// A Python [`Interpreter`] or [`PythonEnvironment`] for a project.
1064+ #[ derive( Debug ) ]
1065+ #[ allow( clippy:: large_enum_variant) ]
1066+ enum PythonTarget {
1067+ Interpreter ( Interpreter ) ,
1068+ Environment ( PythonEnvironment ) ,
1069+ }
1070+
1071+ impl PythonTarget {
1072+ /// Return the [`Interpreter`] for the project.
1073+ fn interpreter ( & self ) -> & Interpreter {
1074+ match self {
1075+ Self :: Interpreter ( interpreter) => interpreter,
1076+ Self :: Environment ( venv) => venv. interpreter ( ) ,
1077+ }
1078+ }
1079+ }
1080+
10411081#[ derive( Debug , Clone ) ]
10421082struct DependencyEdit {
10431083 dependency_type : DependencyType ,
0 commit comments