@@ -150,9 +150,9 @@ def __init__(self, Target=None):
150
150
"requires_dist" : requires ,
151
151
"wanted_per" : [],
152
152
"description" : meta ["Description" ] if "Description" in meta else "" ,
153
- "provides" : provides ,
154
- "provided" : provided ,
155
- }
153
+ "provides" : provides , # extras of the package: 'array' for dask because dask['array'] defines some extra
154
+ "provided" : provided , # extras from other package: 'test' for pytest because dask['test'] wants pytest
155
+ }
156
156
157
157
# On a second pass, complement distro in reverse mode with 'wanted-per':
158
158
# - get all downward links in 'requires_dist' of each package
@@ -166,10 +166,16 @@ def __init__(self, Target=None):
166
166
for r in self .distro [p ]["requires_dist" ]:
167
167
if r ["req_key" ] in self .distro :
168
168
want_add = {
169
- "req_key" : p ,
169
+ "req_key" : p , # p is a string
170
170
"req_version" : r ["req_version" ],
171
171
"req_extra" : r ["req_extra" ],
172
172
} # req_key_extra
173
+
174
+ # provided = extras in upper packages that triggers the need for this package,
175
+ # like 'pandas[test]->Pytest', so 'test' in distro['pytest']['provided']['test']
176
+ # corner-cases: 'dask[dataframe]' -> dask[array]'
177
+ # 'dask-image ->dask[array]
178
+
173
179
if "req_marker" in r :
174
180
want_add ["req_marker" ] = r ["req_marker" ] # req_key_extra
175
181
if 'extra == ' in r ["req_marker" ]:
@@ -187,7 +193,7 @@ def _downraw(self, pp, extra="", version_req="", depth=20, path=[], verbose=Fals
187
193
188
194
ret_all = []
189
195
if p + "[" + extra + "]" in path : # for dask[complete]->dask[array,test,..]
190
- print ("cycle!" , "->" .join (path + [p ]))
196
+ print ("cycle!" , "->" .join (path + [p + "[" + extra + "]" ]))
191
197
elif p in self .distro and len (path ) <= depth :
192
198
for extra in extras : # several extras request management
193
199
envi = {"extra" : extra , ** self .environment }
@@ -213,29 +219,35 @@ def _downraw(self, pp, extra="", version_req="", depth=20, path=[], verbose=Fals
213
219
return ret_all
214
220
215
221
def _upraw (self , pp , extra = "" , version_req = "" , depth = 20 , path = [], verbose = False ):
216
- """build a nested list of user packages with given extra and depth"""
222
+ """build a nested list of user packages with given extra and depth
223
+ from direct dependancies like dask-image <--dask['array']
224
+ or indirect like Pytest['test'] <-- pandas['test']"""
225
+
226
+ remove_list = {ord ("'" ):None , ord ('"' ):None } # to clean-up req_extra
217
227
envi = {"extra" : extra , ** self .environment }
218
228
p = normalize (pp )
229
+ pe = normalize (f'{ pp } [{ extra } ]' )
219
230
ret_all = []
220
- if p in path :
221
- print ("cycle!" , "->" .join (path + [p ]))
231
+ if pe in path :
232
+ print ("cycle!" , "->" .join (path + [pe ]))
222
233
elif p in self .distro and len (path ) <= depth :
223
234
summary = f' { self .distro [p ]["summary" ]} ' if verbose else ''
224
235
if extra == "&
8000
quot; :
225
236
ret_all = [f'{ p } =={ self .distro [p ]["version" ]} { version_req } { summary } ' ]
226
- elif extra in self .distro [p ]["provided" ]:
237
+ elif extra in set ( self .distro [p ]["provided" ]). union ( set ( self . distro [ p ][ "provides" ])): # so that -r pytest[test] gives
227
238
ret_all = [f'{ p } [{ extra } ]=={ self .distro [p ]["version" ]} { version_req } { summary } ' ]
228
239
else :
229
240
return []
230
241
ret = []
231
242
for r in self .distro [p ]["wanted_per" ]:
232
- if r ["req_key" ] in self .distro and r ["req_key" ] not in path :
233
- if ("req_marker" not in r and extra == "" ) or (extra != "" and "req_marker" in r and extra in r ["req_marker" ] and Marker (r ["req_marker" ]).evaluate (
234
- environment = envi
235
- )):
243
+ up_req = (r ["req_marker" ].split ('extra == ' )+ ["" ])[1 ].translate (remove_list ) if "req_marker" in r else ""
244
+ if r ["req_key" ] in self .distro and r ["req_key" ]+ "[" + up_req + "]" not in path : # avoids circular links on dask[array]
245
+ # must be no extra dependancy, optionnal extra in the package, or provided extra per upper packages
246
+ if ("req_marker" not in r and extra == "" ) or (extra != "" and extra == up_req and r ["req_key" ]!= p ) or (extra != "" and "req_marker" in r and extra + ',' in r ["req_extra" ]+ ',' #bingo1346 contourpy[test-no-images]
247
+ ):
236
248
ret += self ._upraw (
237
249
r ["req_key" ],
238
- "" ,
250
+ up_req , # pydask[array] going upwards will look for pydask[dataframe]
239
251
f"[requires: { p } "
240
252
+ (
241
253
"[" + r ["req_extra" ] + "]"
@@ -244,7 +256,7 @@ def _upraw(self, pp, extra="", version_req="", depth=20, path=[], verbose=False)
244
256
)
245
257
+ f'{ r ["req_version" ]} ]' ,
246
258
depth ,
247
- path + [p ],
259
+ path + [pe ],
248
260
verbose = verbose ,
249
261
)
250
262
if not ret == []:
@@ -291,7 +303,7 @@ def up(self, pp, extra="", depth=99, indent=5, version_req="", verbose=False):
291
303
else :
292
304
if pp in self .distro :
293
305
r = []
294
- for one_extra in sorted (self .distro [pp ]["provided" ]):
306
+ for one_extra in sorted (set ( self .distro [pp ]["provided" ]). union ( set ( self . distro [ pp ][ "provides" ]))): #direct and from-upward tags
295
307
s = self .up (pp , one_extra , depth , indent , version_req , verbose = verbose )
296
308
if s != '' : r += [s ]
297
309
return '\n ' .join ([i for i in r if i != '' ])
0 commit comments