@@ -17,26 +17,15 @@ def __init__(self, stderr, output_file):
17
17
# by looking at the directory structure.
18
18
def dig_wheel (self , whl ):
19
19
mapping = {}
20
- wheel_name = get_wheel_name (whl )
21
20
with zipfile .ZipFile (whl , "r" ) as zip_file :
22
21
for path in zip_file .namelist ():
23
22
if is_metadata (path ):
24
- continue
25
- ext = pathlib .Path (path ).suffix
26
- if ext == ".py" or ext == ".so" :
27
- # Note the '/' here means that the __init__.py is not in the
28
- # root of the wheel, therefore we can index the directory
29
- # where this file is as an importable package.
30
- if path .endswith ("/__init__.py" ):
31
- module = path [: - len ("/__init__.py" )].replace ("/" , "." )
32
- mapping [module ] = wheel_name
33
- # Always index the module file.
34
- if ext == ".so" :
35
- # Also remove extra metadata that is embeded as part of
36
- # the file name as an extra extension.
37
- ext = "" .join (pathlib .Path (path ).suffixes )
38
- module = path [: - len (ext )].replace ("/" , "." )
39
- mapping [module ] = wheel_name
23
+ if data_has_purelib_or_platlib (path ):
24
+ module_for_path (path , whl , mapping )
25
+ else :
26
+ continue
27
+ else :
28
+ module_for_path (path , whl , mapping )
40
29
return mapping
41
30
42
31
# run is the entrypoint for the generator.
@@ -73,6 +62,44 @@ def is_metadata(path):
73
62
return top_level .endswith (".dist-info" ) or top_level .endswith (".data" )
74
63
75
64
65
+ # The .data is allowed to contain a full purelib or platlib directory
66
+ # These get unpacked into site-packages, so require indexing too.
67
+ # This is the same if "Root-Is-Purelib: true" is set and the files are at the root.
68
+ # Ref: https://peps.python.org/pep-0427/#what-s-the-deal-with-purelib-vs-platlib
69
+ def data_has_purelib_or_platlib (path ):
70
+ maybe_lib = path .split ("/" )[1 ].lower ()
71
+ return is_metadata (path ) and (
72
+ maybe_lib == "purelib" or maybe_lib == "platlib"
73
+ )
74
+
75
+
76
+
77
+ def module_for_path (path , whl , mapping ):
78
+ ext = pathlib .Path (path ).suffix
79
+ if ext == ".py" or ext == ".so" :
80
+ if "purelib" in path or "platlib" in path :
81
+ root = "/" .join (path .split ("/" )[2 :])
82
+ else :
83
+ root = path
84
+
85
+ wheel_name = get_wheel_name (whl )
86
+
87
+ if root .endswith ("/__init__.py" ):
88
+ # Note the '/' here means that the __init__.py is not in the
89
+ # root of the wheel, therefore we can index the directory
90
+ # where this file is as an importable package.
91
+ module = root [: - len ("/__init__.py" )].replace ("/" , "." )
92
+ mapping [module ] = wheel_name
93
+
94
+ # Always index the module file.
95
+ if ext == ".so" :
96
+ # Also remove extra metadata that is embeded as part of
97
+ # the file name as an extra extension.
98
+ ext = '' .join (pathlib .Path (root ).suffixes )
99
+ module = root [: - len (ext )].replace ("/" , "." )
100
+ mapping [module ] = wheel_name
101
+
102
+
76
103
if __name__ == "__main__" :
77
104
output_file = sys .argv [1 ]
78
105
wheels = sys .argv [2 :]
0 commit comments