@@ -194,53 +194,6 @@ def write_flags(self) -> Iterator[str]:
194194 if emitted :
195195 yield ""
196196
197- def _get_json (
198- self ,
199- ireq : InstallRequirement ,
200- line : str ,
201- hashes : dict [InstallRequirement , set [str ]] | None = None ,
202- unsafe : bool = False ,
203- ) -> dict [str , str ]:
204- """Get a JSON representation for an ``InstallRequirement``."""
205- output_hashes = []
206- if hashes :
207- ireq_hashes = hashes .get (ireq )
208- if ireq_hashes :
209- assert isinstance (ireq_hashes , set )
210- output_hashes = list (ireq_hashes )
211- hashable = True
212- if ireq .link :
213- if ireq .link .is_vcs or (ireq .link .is_file and ireq .link .is_existing_dir ()):
214- hashable = False
215- markers = ""
216- if ireq .markers :
217- markers = str (ireq .markers )
218- # Retrieve parent requirements from constructed line
219- splitted_line = [m .strip () for m in unstyle (line ).split ("#" )]
220- try :
221- via = splitted_line [splitted_line .index ("via" ) + 1 :]
222- except ValueError :
223- via = [splitted_line [- 1 ][len ("via " ) :]]
224- if via [0 ].startswith ("-r" ):
225- req_files = re .split (r"\s|," , via [0 ])
226- del req_files [0 ]
227- via = ["-r" ]
228- for req_file in req_files :
229- via .append (os .path .abspath (req_file ))
230- ireq_json = {
231- "name" : ireq .name ,
232- "version" : str (ireq .specifier ).lstrip ("==" ),
233- "requirement" : str (ireq .req ),
234- "via" : via ,
235- "line" : unstyle (line ),
236- "hashable" : hashable ,
237- "editable" : ireq .editable ,
238- "hashes" : output_hashes ,
239- "markers" : markers ,
240- "unsafe" : unsafe ,
241- }
242- return ireq_json
243-
244197 def _iter_ireqs (
245198 self ,
246199 results : set [InstallRequirement ],
@@ -276,10 +229,10 @@ def _iter_ireqs(
276229 if has_hashes and not hashes .get (ireq ):
277230 yield MESSAGE_UNHASHED_PACKAGE , {}
278231 warn_uninstallable = True
279- line = self ._format_requirement (
232+ line , json = self ._format_requirement (
280233 ireq , markers .get (key_from_ireq (ireq )), hashes = hashes
281234 )
282- yield line , self . _get_json ( ireq , line , hashes = hashes )
235+ yield line , json
283236 yielded = True
284237
285238 if unsafe_requirements :
@@ -296,10 +249,10 @@ def _iter_ireqs(
296249 if not self .allow_unsafe :
297250 yield comment (f"# { ireq_key } " ), {}
298251 else :
299- line = self ._format_requirement (
252+ line , json = self ._format_requirement (
300253 ireq , marker = markers .get (ireq_key ), hashes = hashes
301254 )
302- yield line , self . _get_json ( ireq , line , unsafe = True )
255+ yield line , json
303256
304257 # Yield even when there's no real content, so that blank files are written
305258 if not yielded :
@@ -349,16 +302,14 @@ def _format_requirement(
349302 ireq : InstallRequirement ,
350303 marker : Marker | None = None ,
351304 hashes : dict [InstallRequirement , set [str ]] | None = None ,
352- ) -> str :
305+ unsafe : bool = False ,
306+ ) -> tuple [str , dict [str , str | list [str ]]]:
353307 ireq_hashes = (hashes if hashes is not None else {}).get (ireq )
354308
355309 line = format_requirement (ireq , marker = marker , hashes = ireq_hashes )
356310 if self .strip_extras :
357311 line = strip_extras (line )
358312
359- if not self .annotate :
360- return line
361-
362313 # Annotate what packages or reqs-ins this package is required by
363314 required_by = set ()
364315 if hasattr (ireq , "_source_ireqs" ):
@@ -390,6 +341,39 @@ def _format_requirement(
390341 annotation = strip_extras (annotation )
391342 # 24 is one reasonable column size to use here, that we've used in the past
392343 lines = f"{ line :24} { sep } { comment (annotation )} " .splitlines ()
393- line = "\n " .join (ln .rstrip () for ln in lines )
344+ if self .annotate :
345+ line = "\n " .join (ln .rstrip () for ln in lines )
346+
347+ hashable = True
348+ if ireq .link :
349+ if ireq .link .is_vcs or (ireq .link .is_file and ireq .link .is_existing_dir ()):
350+ hashable = False
351+ output_marker = ""
352+ if marker :
353+ output_marker = str (marker )
354+ via = []
355+ for parent_req in required_by :
356+ if parent_req .startswith ("-r " ):
357+ # Ensure paths to requirements files given are absolute
358+ reqs_in_path = os .path .abspath (parent_req [len ("-r " ) :])
359+ via .append (f"-r { reqs_in_path } " )
360+ else :
361+ via .append (parent_req )
362+ output_hashes = []
363+ if ireq_hashes :
364+ output_hashes = list (ireq_hashes )
365+
366+ ireq_json = {
367+ "name" : ireq .name ,
368+ "version" : str (ireq .specifier ).lstrip ("==" ),
369+ "requirement" : str (ireq .req ),
370+ "via" : via ,
371+ "line" : unstyle (line ),
372+ "hashable" : hashable ,
373+ "editable" : ireq .editable ,
374+ "hashes" : output_hashes ,
375+ "marker" : output_marker ,
376+ "unsafe" : unsafe ,
377+ }
394378
395- return line
379+ return line , ireq_json
0 commit comments