1414import argparse
1515import collections
1616import contextlib
17+ import dataclasses
1718import difflib
1819import functools
1920import importlib .machinery
@@ -109,9 +110,14 @@ class InvalidLicenseExpression(Exception): # type: ignore[no-redef]
109110}
110111
111112
112- def _map_to_wheel (sources : Dict [str , Dict [str , Any ]]) -> DefaultDict [str , List [Tuple [pathlib .Path , str ]]]:
113+ class Entry (typing .NamedTuple ):
114+ dst : pathlib .Path
115+ src : str
116+
117+
118+ def _map_to_wheel (sources : Dict [str , Dict [str , Any ]]) -> DefaultDict [str , List [Entry ]]:
113119 """Map files to the wheel, organized by wheel installation directory."""
114- wheel_files : DefaultDict [str , List [Tuple [ pathlib . Path , str ] ]] = collections .defaultdict (list )
120+ wheel_files : DefaultDict [str , List [Entry ]] = collections .defaultdict (list )
115121 packages : Dict [str , str ] = {}
116122
117123 for key , group in sources .items ():
@@ -129,7 +135,8 @@ def _map_to_wheel(sources: Dict[str, Dict[str, Any]]) -> DefaultDict[str, List[T
129135 other = packages .setdefault (package , path )
130136 if other != path :
131137 this = os .fspath (pathlib .Path (path , * destination .parts [1 :]))
132- that = os .fspath (other / next (d for d , s in wheel_files [other ] if d .parts [0 ] == destination .parts [1 ]))
138+ module = next (entry .dst for entry in wheel_files [other ] if entry .dst .parts [0 ] == destination .parts [1 ])
139+ that = os .fspath (other / module )
133140 raise BuildError (
134141 f'The { package } package is split between { path } and { other } : '
135142 f'{ this !r} and { that !r} , a "pure: false" argument may be missing in meson.build. '
@@ -152,9 +159,9 @@ def _map_to_wheel(sources: Dict[str, Dict[str, Any]]) -> DefaultDict[str, List[T
152159 if relpath in exclude_files :
153160 continue
154161 filedst = dst / relpath
155- wheel_files [path ].append ((filedst , filesrc ))
162+ wheel_files [path ].append (Entry (filedst , filesrc ))
156163 else :
157- wheel_files [path ].append ((dst , src ))
164+ wheel_files [path ].append (Entry (dst , src ))
158165
159166 return wheel_files
160167
@@ -301,20 +308,14 @@ def _is_native(file: Path) -> bool:
301308 return f .read (4 ) == b'\x7f ELF' # ELF
302309
303310
311+ @dataclasses .dataclass
304312class _WheelBuilder ():
305313 """Helper class to build wheels from projects."""
306314
307- def __init__ (
308- self ,
309- metadata : Metadata ,
310- manifest : Dict [str , List [Tuple [pathlib .Path , str ]]],
311- limited_api : bool ,
312- allow_windows_shared_libs : bool ,
313- ) -> None :
314- self ._metadata = metadata
315- self ._manifest = manifest
316- self ._limited_api = limited_api
317- self ._allow_windows_shared_libs = allow_windows_shared_libs
315+ _metadata : Metadata
316+ _manifest : Dict [str , List [Entry ]]
317+ _limited_api : bool
318+ _allow_windows_shared_libs : bool
318319
319320 @property
320321 def _has_internal_libs (self ) -> bool :
@@ -330,8 +331,8 @@ def _pure(self) -> bool:
330331 """Whether the wheel is architecture independent"""
331332 if self ._manifest ['platlib' ] or self ._manifest ['mesonpy-libs' ]:
332333 return False
333- for _ , file in self ._manifest ['scripts' ]:
334- if _is_native (file ):
334+ for entry in self ._manifest ['scripts' ]:
335+ if _is_native (entry . src ):
335336 return False
336337 return True
337338
@@ -408,14 +409,14 @@ def _stable_abi(self) -> Optional[str]:
408409 # in {platlib} that look like extension modules, and raise
409410 # an exception if any of them has a Python version
410411 # specific extension filename suffix ABI tag.
411- for path , _ in self ._manifest ['platlib' ]:
412- match = _EXTENSION_SUFFIX_REGEX .match (path .name )
412+ for entry in self ._manifest ['platlib' ]:
413+ match = _EXTENSION_SUFFIX_REGEX .match (entry . dst .name )
413414 if match :
414415 abi = match .group ('abi' )
415416 if abi is not None and abi != 'abi3' :
416417 raise BuildError (
417418 f'The package declares compatibility with Python limited API but extension '
418- f'module { os .fspath (path )!r} is tagged for a specific Python version.' )
419+ f'module { os .fspath (entry . dst )!r} is tagged for a specific Python version.' )
419420 return 'abi3'
420421 return None
421422
@@ -497,8 +498,8 @@ class _EditableWheelBuilder(_WheelBuilder):
497498 def _top_level_modules (self ) -> Collection [str ]:
498499 modules = set ()
499500 for type_ in self ._manifest :
500- for path , _ in self ._manifest [type_ ]:
501- name , dot , ext = path .parts [0 ].partition ('.' )
501+ for entry in self ._manifest [type_ ]:
502+ name , dot , ext = entry . dst .parts [0 ].partition ('.' )
502503 if dot :
503504 # module
504505 suffix = dot + ext
@@ -854,7 +855,7 @@ def _info(self, name: str) -> Any:
854855 return json .loads (info .read_text (encoding = 'utf-8' ))
855856
856857 @property
857- def _manifest (self ) -> DefaultDict [str , List [Tuple [ pathlib . Path , str ] ]]:
858+ def _manifest (self ) -> DefaultDict [str , List [Entry ]]:
858859 """The files to be added to the wheel, organized by wheel path."""
859860
860861 # Obtain the list of files Meson would install.
0 commit comments