@@ -176,53 +176,6 @@ def write_flags(self) -> Iterator[str]:
176176 if emitted :
177177 yield ""
178178
179- def _get_json (
180- self ,
181- ireq : InstallRequirement ,
182- line : str ,
183- hashes : dict [InstallRequirement , set [str ]] | None = None ,
184- unsafe : bool = False ,
185- ) -> dict [str , str ]:
186- """Get a JSON representation for an ``InstallRequirement``."""
187- output_hashes = []
188- if hashes :
189- ireq_hashes = hashes .get (ireq )
190- if ireq_hashes :
191- assert isinstance (ireq_hashes , set )
192- output_hashes = list (ireq_hashes )
193- hashable = True
194- if ireq .link :
195- if ireq .link .is_vcs or (ireq .link .is_file and ireq .link .is_existing_dir ()):
196- hashable = False
197- markers = ""
198- if ireq .markers :
199- markers = str (ireq .markers )
200- # Retrieve parent requirements from constructed line
201- splitted_line = [m .strip () for m in unstyle (line ).split ("#" )]
202- try :
203- via = splitted_line [splitted_line .index ("via" ) + 1 :]
204- except ValueError :
205- via = [splitted_line [- 1 ][len ("via " ) :]]
206- if via [0 ].startswith ("-r" ):
207- req_files = re .split (r"\s|," , via [0 ])
208- del req_files [0 ]
209- via = ["-r" ]
210- for req_file in req_files :
211- via .append (os .path .abspath (req_file ))
212- ireq_json = {
213- "name" : ireq .name ,
214- "version" : str (ireq .specifier ).lstrip ("==" ),
215- "requirement" : str (ireq .req ),
216- "via" : via ,
217- "line" : unstyle (line ),
218- "hashable" : hashable ,
219- "editable" : ireq .editable ,
220- "hashes" : output_hashes ,
221- "markers" : markers ,
222- "unsafe" : unsafe ,
223- }
224- return ireq_json
225-
226179 def _iter_ireqs (
227180 self ,
228181 results : set [InstallRequirement ],
@@ -258,10 +211,10 @@ def _iter_ireqs(
258211 if has_hashes and not hashes .get (ireq ):
259212 yield MESSAGE_UNHASHED_PACKAGE , {}
260213 warn_uninstallable = True
261- line = self ._format_requirement (
214+ line , json = self ._format_requirement (
262215 ireq , markers .get (key_from_ireq (ireq )), hashes = hashes
263216 )
264- yield line , self . _get_json ( ireq , line , hashes = hashes )
217+ yield line , json
265218 yielded = True
266219
267220 if unsafe_requirements :
@@ -278,10 +231,10 @@ def _iter_ireqs(
278231 if not self .allow_unsafe :
279232 yield comment (f"# { ireq_key } " ), {}
280233 else :
281- line = self ._format_requirement (
234+ line , json = self ._format_requirement (
282235 ireq , marker = markers .get (ireq_key ), hashes = hashes
283236 )
284- yield line , self . _get_json ( ireq , line , unsafe = True )
237+ yield line , json
285238
286239 # Yield even when there's no real content, so that blank files are written
287240 if not yielded :
@@ -331,16 +284,14 @@ def _format_requirement(
331284 ireq : InstallRequirement ,
332285 marker : Marker | None = None ,
333286 hashes : dict [InstallRequirement , set [str ]] | None = None ,
334- ) -> str :
287+ unsafe : bool = False ,
288+ ) -> tuple [str , dict [str , str | list [str ]]]:
335289 ireq_hashes = (hashes if hashes is not None else {}).get (ireq )
336290
337291 line = format_requirement (ireq , marker = marker , hashes = ireq_hashes )
338292 if self .strip_extras :
339293 line = strip_extras (line )
340294
341- if not self .annotate :
342- return line
343-
344295 # Annotate what packages or reqs-ins this package is required by
345296 required_by = set ()
346297 if hasattr (ireq , "_source_ireqs" ):
@@ -372,6 +323,39 @@ def _format_requirement(
372323 annotation = strip_extras (annotation )
373324 # 24 is one reasonable column size to use here, that we've used in the past
374325 lines = f"{ line :24} { sep } { comment (annotation )} " .splitlines ()
375- line = "\n " .join (ln .rstrip () for ln in lines )
326+ if self .annotate :
327+ line = "\n " .join (ln .rstrip () for ln in lines )
328+
329+ hashable = True
330+ if ireq .link :
331+ if ireq .link .is_vcs or (ireq .link .is_file and ireq .link .is_existing_dir ()):
332+ hashable = False
333+ output_marker = ""
334+ if marker :
335+ output_marker = str (marker )
336+ via = []
337+ for parent_req in required_by :
338+ if parent_req .startswith ("-r " ):
339+ # Ensure paths to requirements files given are absolute
340+ reqs_in_path = os .path .abspath (parent_req [len ("-r " ) :])
341+ via .append (f"-r { reqs_in_path } " )
342+ else :
343+ via .append (parent_req )
344+ output_hashes = []
345+ if ireq_hashes :
346+ output_hashes = list (ireq_hashes )
347+
348+ ireq_json = {
349+ "name" : ireq .name ,
350+ "version" : str (ireq .specifier ).lstrip ("==" ),
351+ "requirement" : str (ireq .req ),
352+ "via" : via ,
353+ "line" : unstyle (line ),
354+ "hashable" : hashable ,
355+ "editable" : ireq .editable ,
356+ "hashes" : output_hashes ,
357+ "marker" : output_marker ,
358+ "unsafe" : unsafe ,
359+ }
376360
377- return line
361+ return line , ireq_json
0 commit comments