@@ -4322,3 +4322,91 @@ def test_update_with_use_latest_vs_lock(
43224322 {"job" : "install" , "package" : package_a1 },
43234323 ],
43244324 )
4325+
4326+
4327+ @pytest .mark .parametrize ("with_extra" , [False , True ])
4328+ def test_solver_resolves_duplicate_dependency_in_extra (
4329+ package : ProjectPackage ,
4330+ pool : RepositoryPool ,
4331+ repo : Repository ,
4332+ io : NullIO ,
4333+ with_extra : bool ,
4334+ ) -> None :
4335+ """
4336+ Without extras, a newer version of B can be chosen than with extras.
4337+ See https://github.com/python-poetry/poetry/issues/8380.
4338+ """
4339+ constraint : dict [str , Any ] = {"version" : "*" }
4340+ if with_extra :
4341+ constraint ["extras" ] = ["foo" ]
4342+ package .add_dependency (Factory .create_dependency ("A" , constraint ))
4343+
4344+ package_a = get_package ("A" , "1.0" )
4345+ package_b1 = get_package ("B" , "1.0" )
4346+ package_b2 = get_package ("B" , "2.0" )
4347+
4348+ dep = get_dependency ("B" , ">=1.0" )
4349+ package_a .add_dependency (dep )
4350+
4351+ dep_extra = get_dependency ("B" , "^1.0" , optional = True )
4352+ dep_extra .marker = parse_marker ("extra == 'foo'" )
4353+ package_a .extras = {canonicalize_name ("foo" ): [dep_extra ]}
4354+ package_a .add_dependency (dep_extra )
4355+
4356+ repo .add_package (package_a )
4357+ repo .add_package (package_b1 )
4358+ repo .add_package (package_b2 )
4359+
4360+ solver = Solver (package , pool , [], [], io )
4361+ transaction = solver .solve ()
4362+
4363+ check_solver_result (
4364+ transaction ,
4365+ (
4366+ [
4367+ {"job" : "install" , "package" : package_b1 if with_extra else package_b2 },
4368+ {"job" : "install" , "package" : package_a },
4369+ ]
4370+ ),
4371+ )
4372+
4373+
4374+ def test_solver_resolves_duplicate_dependencies_with_restricted_extras (
4375+ package : ProjectPackage ,
4376+ pool : RepositoryPool ,
4377+ repo : Repository ,
4378+ io : NullIO ,
4379+ ) -> None :
4380+ package .add_dependency (
4381+ Factory .create_dependency ("A" , {"version" : "*" , "extras" : ["foo" ]})
4382+ )
4383+
4384+ package_a = get_package ("A" , "1.0" )
4385+ package_b1 = get_package ("B" , "1.0" )
4386+ package_b2 = get_package ("B" , "2.0" )
4387+
4388+ dep1 = get_dependency ("B" , "^1.0" , optional = True )
4389+ dep1 .marker = parse_marker ("sys_platform == 'win32' and extra == 'foo'" )
4390+ dep2 = get_dependency ("B" , "^2.0" , optional = True )
4391+ dep2 .marker = parse_marker ("sys_platform == 'linux' and extra == 'foo'" )
4392+ package_a .extras = {canonicalize_name ("foo" ): [dep1 , dep2 ]}
4393+ package_a .add_dependency (dep1 )
4394+ package_a .add_dependency (dep2 )
4395+
4396+ repo .add_package (package_a )
4397+ repo .add_package (package_b1 )
4398+ repo .add_package (package_b2 )
4399+
4400+ solver = Solver (package , pool , [], [], io )
4401+ transaction = solver .solve ()
4402+
4403+ check_solver_result (
4404+ transaction ,
4405+ (
4406+ [
4407+ {"job" : "install" , "package" : package_b1 },
4408+ {"job" : "install" , "package" : package_b2 },
4409+ {"job" : "install" , "package" : package_a },
4410+ ]
4411+ ),
4412+ )
0 commit comments