@@ -135,6 +135,59 @@ def test_it_should_remove_installed_packages_if_required() -> None:
135135 )
136136
137137
138+ def test_it_should_not_remove_system_site_packages () -> None :
139+ """
140+ Different types of uninstalls:
141+ - c: tracked but not required
142+ - e: not tracked
143+ - f: root extra that is not requested
144+ """
145+ extra_name = canonicalize_name ("foo" )
146+ package = ProjectPackage ("root" , "1.0" )
147+ dep_f = Dependency ("f" , "1" , optional = True )
148+ dep_f ._in_extras = [extra_name ]
149+ package .add_dependency (dep_f )
150+ package .extras = {extra_name : [dep_f ]}
151+ opt_f = Package ("f" , "6.0.0" )
152+ opt_f .optional = True
153+ transaction = Transaction (
154+ [Package ("a" , "1.0.0" ), Package ("b" , "2.0.0" ), Package ("c" , "3.0.0" )],
155+ {
156+ Package ("a" , "1.0.0" ): get_transitive_info (1 ),
157+ Package ("b" , "2.1.0" ): get_transitive_info (2 ),
158+ Package ("d" , "4.0.0" ): get_transitive_info (0 ),
159+ opt_f : get_transitive_info (0 ),
160+ },
161+ installed_packages = [
162+ Package ("a" , "1.0.0" ),
163+ Package ("b" , "2.0.0" ),
164+ Package ("c" , "3.0.0" ),
165+ Package ("e" , "5.0.0" ),
166+ Package ("f" , "6.0.0" ),
167+ ],
168+ root_package = package ,
169+ )
170+
171+ check_operations (
172+ transaction .calculate_operations (
173+ synchronize = True ,
174+ extras = set (),
175+ system_site_packages = {
176+ canonicalize_name (name ) for name in ("a" , "b" , "c" , "e" , "f" )
177+ },
178+ ),
179+ [
180+ {
181+ "job" : "update" ,
182+ "from" : Package ("b" , "2.0.0" ),
183+ "to" : Package ("b" , "2.1.0" ),
184+ },
185+ {"job" : "install" , "package" : Package ("a" , "1.0.0" ), "skipped" : True },
186+ {"job" : "install" , "package" : Package ("d" , "4.0.0" )},
187+ ],
188+ )
189+
190+
138191def test_it_should_not_remove_installed_packages_that_are_in_result () -> None :
139192 transaction = Transaction (
140193 [],
@@ -236,7 +289,9 @@ def test_calculate_operations_with_groups(
236289 for name in sorted ({"a" , "b" , "c" }.difference (expected ), reverse = True ):
237290 expected_ops .insert (0 , {"job" : "remove" , "package" : Package (name , "1" )})
238291
239- check_operations (transaction .calculate_operations (sync ), expected_ops )
292+ check_operations (
293+ transaction .calculate_operations (with_uninstalls = sync ), expected_ops
294+ )
240295
241296
242297@pytest .mark .parametrize (
@@ -273,7 +328,9 @@ def test_calculate_operations_with_markers(
273328 for name in sorted ({"a" , "b" }.difference (expected ), reverse = True ):
274329 expected_ops .insert (0 , {"job" : "remove" , "package" : Package (name , "1" )})
275330
276- check_operations (transaction .calculate_operations (sync ), expected_ops )
331+ check_operations (
332+ transaction .calculate_operations (with_uninstalls = sync ), expected_ops
333+ )
277334
278335
279336@pytest .mark .parametrize (
@@ -366,8 +423,8 @@ def test_calculate_operations_extras(
366423
367424 check_operations (
368425 transaction .calculate_operations (
369- with_uninstalls ,
370- sync ,
426+ with_uninstalls = with_uninstalls ,
427+ synchronize = sync ,
371428 extras = {extra_name } if extras else set (),
372429 ),
373430 ops ,
0 commit comments