15
15
import collections
16
16
import contextlib
17
17
import copy
18
+ import dataclasses
18
19
import difflib
19
20
import functools
20
21
import importlib .machinery
@@ -111,9 +112,14 @@ class InvalidLicenseExpression(Exception): # type: ignore[no-redef]
111
112
}
112
113
113
114
114
- def _map_to_wheel (sources : Dict [str , Dict [str , Any ]]) -> DefaultDict [str , List [Tuple [pathlib .Path , str ]]]:
115
+ class Entry (typing .NamedTuple ):
116
+ dst : pathlib .Path
117
+ src : str
118
+
119
+
120
+ def _map_to_wheel (sources : Dict [str , Dict [str , Any ]]) -> DefaultDict [str , List [Entry ]]:
115
121
"""Map files to the wheel, organized by wheel installation directory."""
116
- wheel_files : DefaultDict [str , List [Tuple [ pathlib . Path , str ] ]] = collections .defaultdict (list )
122
+ wheel_files : DefaultDict [str , List [Entry ]] = collections .defaultdict (list )
117
123
packages : Dict [str , str ] = {}
118
124
119
125
for key , group in sources .items ():
@@ -131,7 +137,8 @@ def _map_to_wheel(sources: Dict[str, Dict[str, Any]]) -> DefaultDict[str, List[T
131
137
other = packages .setdefault (package , path )
132
138
if other != path :
133
139
this = os .fspath (pathlib .Path (path , * destination .parts [1 :]))
134
- that = os .fspath (other / next (d for d , s in wheel_files [other ] if d .parts [0 ] == destination .parts [1 ]))
140
+ module = next (entry .dst for entry in wheel_files [other ] if entry .dst .parts [0 ] == destination .parts [1 ])
141
+ that = os .fspath (other / module )
135
142
raise BuildError (
136
143
f'The { package } package is split between { path } and { other } : '
137
144
f'{ this !r} and { that !r} , a "pure: false" argument may be missing in meson.build. '
@@ -154,9 +161,9 @@ def _map_to_wheel(sources: Dict[str, Dict[str, Any]]) -> DefaultDict[str, List[T
154
161
if relpath in exclude_files :
155
162
continue
156
163
filedst = dst / relpath
157
- wheel_files [path ].append ((filedst , filesrc ))
164
+ wheel_files [path ].append (Entry (filedst , filesrc ))
158
165
else :
159
- wheel_files [path ].append ((dst , src ))
166
+ wheel_files [path ].append (Entry (dst , src ))
160
167
161
168
return wheel_files
162
169
@@ -303,20 +310,14 @@ def _is_native(file: Path) -> bool:
303
310
return f .read (4 ) == b'\x7f ELF' # ELF
304
311
305
312
313
+ @dataclasses .dataclass
306
314
class _WheelBuilder ():
307
315
"""Helper class to build wheels from projects."""
308
316
309
- def __init__ (
310
- self ,
311
- metadata : Metadata ,
312
- manifest : Dict [str , List [Tuple [pathlib .Path , str ]]],
313
- limited_api : bool ,
314
- allow_windows_shared_libs : bool ,
315
- ) -> None :
316
- self ._metadata = metadata
317
- self ._manifest = manifest
318
- self ._limited_api = limited_api
319
- self ._allow_windows_shared_libs = allow_windows_shared_libs
317
+ _metadata : Metadata
318
+ _manifest : Dict [str , List [Entry ]]
319
+ _limited_api : bool
320
+ _allow_windows_shared_libs : bool
320
321
321
322
@property
322
323
def _has_internal_libs (self ) -> bool :
@@ -332,8 +333,8 @@ def _pure(self) -> bool:
332
333
"""Whether the wheel is architecture independent"""
333
334
if self ._manifest ['platlib' ] or self ._manifest ['mesonpy-libs' ]:
334
335
return False
335
- for _ , file in self ._manifest ['scripts' ]:
336
- if _is_native (file ):
336
+ for entry in self ._manifest ['scripts' ]:
337
+ if _is_native (entry . src ):
337
338
return False
338
339
return True
339
340
@@ -410,14 +411,14 @@ def _stable_abi(self) -> Optional[str]:
410
411
# in {platlib} that look like extension modules, and raise
411
412
# an exception if any of them has a Python version
412
413
# specific extension filename suffix ABI tag.
413
- for path , _ in self ._manifest ['platlib' ]:
414
- match = _EXTENSION_SUFFIX_REGEX .match (path .name )
414
+ for entry in self ._manifest ['platlib' ]:
415
+ match = _EXTENSION_SUFFIX_REGEX .match (entry . dst .name )
415
416
if match :
416
417
abi = match .group ('abi' )
417
418
if abi is not None and abi != 'abi3' :
418
419
raise BuildError (
419
420
f'The package declares compatibility with Python limited API but extension '
420
- f'module { os .fspath (path )!r} is tagged for a specific Python version.' )
421
+ f'module { os .fspath (entry . dst )!r} is tagged for a specific Python version.' )
421
422
return 'abi3'
422
423
return None
423
424
@@ -499,8 +500,8 @@ class _EditableWheelBuilder(_WheelBuilder):
499
500
def _top_level_modules (self ) -> Collection [str ]:
500
501
modules = set ()
501
502
for type_ in self ._manifest :
502
- for path , _ in self ._manifest [type_ ]:
503
- name , dot , ext = path .parts [0 ].partition ('.' )
503
+ for entry in self ._manifest [type_ ]:
504
+ name , dot , ext = entry . dst .parts [0 ].partition ('.' )
504
505
if dot :
505
506
# module
506
507
suffix = dot + ext
@@ -883,7 +884,7 @@ def _info(self, name: str) -> Any:
883
884
return json .loads (info .read_text (encoding = 'utf-8' ))
884
885
885
886
@property
886
- def _manifest (self ) -> DefaultDict [str , List [Tuple [ pathlib . Path , str ] ]]:
887
+ def _manifest (self ) -> DefaultDict [str , List [Entry ]]:
887
888
"""The files to be added to the wheel, organized by wheel path."""
888
889
889
890
# Obtain the list of files Meson would install.
0 commit comments