1515import collections
1616import contextlib
1717import copy
18+ import dataclasses
1819import difflib
1920import functools
2021import importlib .machinery
@@ -111,9 +112,14 @@ class InvalidLicenseExpression(Exception): # type: ignore[no-redef]
111112}
112113
113114
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 ]]:
115121 """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 )
117123 packages : Dict [str , str ] = {}
118124
119125 for key , group in sources .items ():
@@ -131,7 +137,8 @@ def _map_to_wheel(sources: Dict[str, Dict[str, Any]]) -> DefaultDict[str, List[T
131137 other = packages .setdefault (package , path )
132138 if other != path :
133139 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 )
135142 raise BuildError (
136143 f'The { package } package is split between { path } and { other } : '
137144 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
154161 if relpath in exclude_files :
155162 continue
156163 filedst = dst / relpath
157- wheel_files [path ].append ((filedst , filesrc ))
164+ wheel_files [path ].append (Entry (filedst , filesrc ))
158165 else :
159- wheel_files [path ].append ((dst , src ))
166+ wheel_files [path ].append (Entry (dst , src ))
160167
161168 return wheel_files
162169
@@ -303,20 +310,14 @@ def _is_native(file: Path) -> bool:
303310 return f .read (4 ) == b'\x7f ELF' # ELF
304311
305312
313+ @dataclasses .dataclass
306314class _WheelBuilder ():
307315 """Helper class to build wheels from projects."""
308316
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
320321
321322 @property
322323 def _has_internal_libs (self ) -> bool :
@@ -332,8 +333,8 @@ def _pure(self) -> bool:
332333 """Whether the wheel is architecture independent"""
333334 if self ._manifest ['platlib' ] or self ._manifest ['mesonpy-libs' ]:
334335 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 ):
337338 return False
338339 return True
339340
@@ -410,14 +411,14 @@ def _stable_abi(self) -> Optional[str]:
410411 # in {platlib} that look like extension modules, and raise
411412 # an exception if any of them has a Python version
412413 # 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 )
415416 if match :
416417 abi = match .group ('abi' )
417418 if abi is not None and abi != 'abi3' :
418419 raise BuildError (
419420 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.' )
421422 return 'abi3'
422423 return None
423424
@@ -499,8 +500,8 @@ class _EditableWheelBuilder(_WheelBuilder):
499500 def _top_level_modules (self ) -> Collection [str ]:
500501 modules = set ()
501502 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 ('.' )
504505 if dot :
505506 # module
506507 suffix = dot + ext
@@ -886,7 +887,7 @@ def _info(self, name: str) -> Any:
886887 return json .loads (info .read_text (encoding = 'utf-8' ))
887888
888889 @property
889- def _manifest (self ) -> DefaultDict [str , List [Tuple [ pathlib . Path , str ] ]]:
890+ def _manifest (self ) -> DefaultDict [str , List [Entry ]]:
890891 """The files to be added to the wheel, organized by wheel path."""
891892
892893 # Obtain the list of files Meson would install.
0 commit comments