7
7
8
8
9
9
def dependencies_with_extras (deps : list [Requirement ], extras : set [str ], package_name : str ) -> list [Requirement ]:
10
- deps = _normalize_req (deps )
10
+ deps_with_markers = extract_extra_markers (deps )
11
11
result : list [Requirement ] = []
12
12
found : set [str ] = set ()
13
13
todo : set [str | None ] = extras | {None }
14
14
visited : set [str | None ] = set ()
15
15
while todo :
16
16
new_extras : set [str | None ] = set ()
17
- for req in deps :
18
- if todo & ( req . extras or { None }): # type: ignore[arg-type]
17
+ for req , extra_markers in deps_with_markers :
18
+ if todo & extra_markers :
19
19
if req .name == package_name : # support for recursive extras
20
20
new_extras .update (req .extras or set ())
21
21
else :
22
- req = deepcopy (req )
23
- req .extras .clear () # strip the extra part as the installation will invoke it without
24
22
req_str = str (req )
25
23
if req_str not in found :
26
24
found .add (req_str )
@@ -30,26 +28,27 @@ def dependencies_with_extras(deps: list[Requirement], extras: set[str], package_
30
28
return result
31
29
32
30
33
- def _normalize_req (deps : list [Requirement ]) -> list [Requirement ]:
31
+ def extract_extra_markers (deps : list [Requirement ]) -> list [tuple [ Requirement , set [ str | None ]] ]:
34
32
# extras might show up as markers, move them into extras property
35
- result : list [Requirement ] = []
33
+ result : list [tuple [ Requirement , set [ str | None ]] ] = []
36
34
for req in deps :
37
35
req = deepcopy (req )
38
36
markers : list [str | tuple [Variable , Variable , Variable ]] = getattr (req .marker , "_markers" , []) or []
39
37
_at : int | None = None
38
+ extra_markers = set ()
40
39
for _at , (marker_key , op , marker_value ) in (
41
40
(_at_marker , marker )
42
41
for _at_marker , marker in enumerate (markers )
43
42
if isinstance (marker , tuple ) and len (marker ) == 3
44
43
):
45
44
if marker_key .value == "extra" and op .value == "==" : # pragma: no branch
46
- req . extras .add (marker_value .value )
45
+ extra_markers .add (marker_value .value )
47
46
del markers [_at ]
48
47
_at -= 1
49
48
if _at > 0 and (isinstance (markers [_at ], str ) and markers [_at ] in ("and" , "or" )):
50
49
del markers [_at ]
51
50
if len (markers ) == 0 :
52
51
req .marker = None
53
52
break
54
- result .append (req )
53
+ result .append (( req , extra_markers or { None }) )
55
54
return result
0 commit comments