@@ -136,7 +136,7 @@ def resolve_fields(self, purl: PackageURL) -> None:
136136 logger .debug ("It has directories %s" , "," .join (os .listdir (pypi_package_json .wheel_path )))
137137 wheel_contents , metadata_contents = self .read_directory (pypi_package_json .wheel_path , purl )
138138 generator , version = self .read_generator_line (wheel_contents )
139- if generator != "" :
139+ if generator != "" and version != "" :
140140 parsed_build_requires [generator ] = "==" + version .replace (" " , "" )
141141 # Apply METADATA heuristics to determine setuptools version.
142142 elif "License-File" in metadata_contents :
@@ -302,5 +302,50 @@ def read_generator_line(self, wheel_contents: str) -> tuple[str, str]:
302302 if line .startswith ("Generator:" ):
303303 split_line = line .split (" " )
304304 if len (split_line ) > 2 :
305- return split_line [1 ], split_line [2 ]
305+ backend = split_line [1 ]
306+ match backend :
307+ case "bdist_wheel" :
308+ backend = "wheel"
309+ version = self .parse_generator_version (split_line [2 ])
310+ return backend , version
306311 return "" , ""
312+
313+ def parse_generator_version (self , literal_version_specification : str ) -> str :
314+ """
315+ Parse the generator's version.
316+
317+ Parameters
318+ ----------
319+ version_literal : str
320+ Version string corresponding to generator.
321+
322+ Returns
323+ -------
324+ str
325+ Sanitized and standardized version specifier.
326+
327+ Examples
328+ --------
329+ >>> spec = PyPIBuildSpec(None)
330+ >>> spec.parse_generator_version("(1.2.3)")
331+ '1.2.3'
332+ >>> spec.parse_generator_version("1.2.3")
333+ '1.2.3'
334+ >>> spec.parse_generator_version("a.b.c")
335+ ''
336+ >>> spec.parse_generator_version("1..2.3")
337+ ''
338+ >>> spec.parse_generator_version("(1..2.3)")
339+ ''
340+ """
341+ # Two patterns p1 and p2 rather than just one
342+ # (p1)|(p2) as the latter complicates the group to return
343+ pattern_plain = re .compile (r"^(\d(\.(\d)+)*)$" )
344+ plain_match = pattern_plain .match (literal_version_specification )
345+ pattern_parenthesis = re .compile (r"^\((\d(\.(\d)+)*)\)$" )
346+ parenthesis_match = pattern_parenthesis .match (literal_version_specification )
347+ if plain_match :
348+ return plain_match .group (1 )
349+ if parenthesis_match :
350+ return parenthesis_match .group (1 )
351+ return ""
0 commit comments