77from packaging .utils import canonicalize_name
88
99from poetry .installation .executor import Executor
10- from poetry .installation .operations import Install
1110from poetry .installation .operations import Uninstall
1211from poetry .installation .operations import Update
1312from poetry .repositories import Repository
@@ -239,15 +238,17 @@ def _do_install(self) -> int:
239238 source_root = self ._env .path .joinpath ("src" )
240239 ):
241240 ops = solver .solve (use_latest = self ._whitelist ).calculate_operations ()
241+
242+ lockfile_repo = LockfileRepository ()
243+ self ._populate_lockfile_repo (lockfile_repo , ops )
244+
242245 else :
243246 self ._io .write_line ("<info>Installing dependencies from lock file</>" )
244247
245- locked_repository = self ._locker .locked_repository ()
246-
247248 if not self ._locker .is_fresh ():
248249 raise ValueError (
249- "pyproject.toml changed significantly since poetry.lock was last generated. "
250- "Run `poetry lock [--no-update]` to fix the lock file."
250+ "pyproject.toml changed significantly since poetry.lock was last"
251+ " generated. Run `poetry lock [--no-update]` to fix the lock file."
251252 )
252253
253254 locker_extras = {
@@ -258,30 +259,25 @@ def _do_install(self) -> int:
258259 if extra not in locker_extras :
259260 raise ValueError (f"Extra [{ extra } ] is not specified." )
260261
261- # If we are installing from lock
262- # Filter the operations by comparing it with what is
263- # currently installed
264- ops = self ._get_operations_from_lock (locked_repository )
265-
266- lockfile_repo = LockfileRepository ()
267- uninstalls = self ._populate_lockfile_repo (lockfile_repo , ops )
262+ locked_repository = self ._locker .locked_repository ()
263+ lockfile_repo = locked_repository
268264
269265 if not self .executor .enabled :
270266 # If we are only in lock mode, no need to go any further
271267 self ._write_lock_file (lockfile_repo )
272268 return 0
273269
274- if self ._groups is not None :
275- root = self ._package .with_dependency_groups (list (self ._groups ), only = True )
276- else :
277- root = self ._package .without_optional_dependency_groups ()
278-
279270 if self ._io .is_verbose ():
280271 self ._io .write_line ("" )
281272 self ._io .write_line (
282273 "<info>Finding the necessary packages for the current system</>"
283274 )
284275
276+ if self ._groups is not None :
277+ root = self ._package .with_dependency_groups (list (self ._groups ), only = True )
278+ else :
279+ root = self ._package .without_optional_dependency_groups ()
280+
285281 # We resolve again by only using the lock file
286282 packages = lockfile_repo .packages + locked_repository .packages
287283 pool = RepositoryPool .from_packages (packages , self ._config )
@@ -299,31 +295,12 @@ def _do_install(self) -> int:
299295
300296 with solver .use_environment (self ._env ):
301297 ops = solver .solve (use_latest = self ._whitelist ).calculate_operations (
302- with_uninstalls = self ._requires_synchronization ,
298+ with_uninstalls = self ._requires_synchronization or self . _update ,
303299 synchronize = self ._requires_synchronization ,
304300 skip_directory = self ._skip_directory ,
301+ extras = set (self ._extras ),
305302 )
306303
307- if not self ._requires_synchronization :
308- # If no packages synchronisation has been requested we need
309- # to calculate the uninstall operations
310- from poetry .puzzle .transaction import Transaction
311-
312- transaction = Transaction (
313- locked_repository .packages ,
314- [(package , 0 ) for package in lockfile_repo .packages ],
315- installed_packages = self ._installed_repository .packages ,
316- root_package = root ,
317- )
318-
319- ops = [
320- op
321- for op in transaction .calculate_operations (with_uninstalls = True )
322- if op .job_type == "uninstall"
323- ] + ops
324- else :
325- ops = uninstalls + ops
326-
327304 # We need to filter operations so that packages
328305 # not compatible with the current system,
329306 # or optional and not requested, are dropped
@@ -358,50 +335,15 @@ def _execute(self, operations: list[Operation]) -> int:
358335
359336 def _populate_lockfile_repo (
360337 self , repo : LockfileRepository , ops : Iterable [Operation ]
361- ) -> list [Uninstall ]:
362- uninstalls = []
338+ ) -> None :
363339 for op in ops :
364340 if isinstance (op , Uninstall ):
365- uninstalls .append (op )
366341 continue
367342
368343 package = op .target_package if isinstance (op , Update ) else op .package
369344 if not repo .has_package (package ):
370345 repo .add_package (package )
371346
372- return uninstalls
373-
374- def _get_operations_from_lock (
375- self , locked_repository : Repository
376- ) -> list [Operation ]:
377- installed_repo = self ._installed_repository
378- ops : list [Operation ] = []
379-
380- extra_packages = self ._get_extra_packages (locked_repository )
381- for locked in locked_repository .packages :
382- is_installed = False
383- for installed in installed_repo .packages :
384- if locked .name == installed .name :
385- is_installed = True
386- if locked .optional and locked .name not in extra_packages :
387- # Installed but optional and not requested in extras
388- ops .append (Uninstall (locked ))
389- elif locked .version != installed .version :
390- ops .append (Update (installed , locked ))
391-
392- # If it's optional and not in required extras
393- # we do not install
394- if locked .optional and locked .name not in extra_packages :
395- continue
396-
397- op = Install (locked )
398- if is_installed :
399- op .skip ("Already installed" )
400-
401- ops .append (op )
402-
403- return ops
404-
405347 def _filter_operations (self , ops : Iterable [Operation ], repo : Repository ) -> None :
406348 extra_packages = self ._get_extra_packages (repo )
407349 for op in ops :
@@ -425,19 +367,11 @@ def _get_extra_packages(self, repo: Repository) -> set[NormalizedName]:
425367
426368 Maybe we just let the solver handle it?
427369 """
428- extras : dict [NormalizedName , list [NormalizedName ]]
429- if self ._update :
430- extras = {k : [d .name for d in v ] for k , v in self ._package .extras .items ()}
431- else :
432- raw_extras = self ._locker .lock_data .get ("extras" , {})
433- extras = {
434- canonicalize_name (extra ): [
435- canonicalize_name (dependency ) for dependency in dependencies
436- ]
437- for extra , dependencies in raw_extras .items ()
438- }
439-
440- return get_extra_package_names (repo .packages , extras , self ._extras )
370+ return get_extra_package_names (
371+ repo .packages ,
372+ {k : [d .name for d in v ] for k , v in self ._package .extras .items ()},
373+ self ._extras ,
374+ )
441375
442376 def _get_installed (self ) -> InstalledRepository :
443377 return InstalledRepository .load (self ._env )
0 commit comments