Skip to content

Commit d5f12ec

Browse files
dnicolodirgommers
authored andcommitted
MAINT: restructure how the contents list is passed to wheel builder
This is an attempt at making the interface between the wheel builder class and the class representing the meson project a bit easier to understand. Ideally we should be able to just pass the manifest and the metadata to the wheel builder class. This will require some more restructuring to achieve.
1 parent 51ddc7d commit d5f12ec

File tree

2 files changed

+24
-27
lines changed

2 files changed

+24
-27
lines changed

mesonpy/__init__.py

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def _init_colors() -> Dict[str, str]:
128128

129129

130130
def _map_to_wheel(sources: Dict[str, Dict[str, Any]]) -> DefaultDict[str, List[Tuple[pathlib.Path, str]]]:
131-
"""Map files to the wheel, organized by wheel installation directrory."""
131+
"""Map files to the wheel, organized by wheel installation directory."""
132132
wheel_files: DefaultDict[str, List[Tuple[pathlib.Path, str]]] = collections.defaultdict(list)
133133
packages: Dict[str, str] = {}
134134

@@ -259,26 +259,22 @@ def __init__(
259259
metadata: Metadata,
260260
source_dir: pathlib.Path,
261261
build_dir: pathlib.Path,
262-
sources: Dict[str, Dict[str, Any]],
262+
manifest: Dict[str, List[Tuple[pathlib.Path, str]]],
263263
) -> None:
264264
self._project = project
265265
self._metadata = metadata
266266
self._source_dir = source_dir
267267
self._build_dir = build_dir
268-
self._sources = sources
269-
270-
@cached_property
271-
def _wheel_files(self) -> DefaultDict[str, List[Tuple[pathlib.Path, str]]]:
272-
return _map_to_wheel(self._sources)
268+
self._manifest = manifest
273269

274270
@property
275271
def _has_internal_libs(self) -> bool:
276-
return bool(self._wheel_files.get('mesonpy-libs'))
272+
return bool(self._manifest.get('mesonpy-libs'))
277273

278274
@property
279275
def _has_extension_modules(self) -> bool:
280276
# Assume that all code installed in {platlib} is Python ABI dependent.
281-
return bool(self._wheel_files.get('platlib'))
277+
return bool(self._manifest.get('platlib'))
282278

283279
@property
284280
def normalized_name(self) -> str:
@@ -322,9 +318,9 @@ def is_pure(self) -> bool:
322318
# non-pure, but I think it's better that we evaluate use-cases as they
323319
# arise and make sure allowing the user to override this is indeed the
324320
# best option for the use-case.
325-
if self._wheel_files['platlib']:
321+
if self._manifest['platlib']:
326322
return False
327-
for _, file in self._wheel_files['scripts']:
323+
for _, file in self._manifest['scripts']:
328324
if self._is_native(file):
329325
return False
330326
return True
@@ -368,7 +364,7 @@ def _stable_abi(self) -> Optional[str]:
368364
# in {platlib} that look like extension modules, and raise
369365
# an exception if any of them has a Python version
370366
# specific extension filename suffix ABI tag.
371-
for path, _ in self._wheel_files['platlib']:
367+
for path, _ in self._manifest['platlib']:
372368
match = _EXTENSION_SUFFIX_REGEX.match(path.name)
373369
if match:
374370
abi = match.group('abi')
@@ -382,8 +378,8 @@ def _stable_abi(self) -> Optional[str]:
382378
@property
383379
def top_level_modules(self) -> Collection[str]:
384380
modules = set()
385-
for type_ in self._wheel_files:
386-
for path, _ in self._wheel_files[type_]:
381+
for type_ in self._manifest:
382+
for path, _ in self._manifest[type_]:
387383
name, dot, ext = path.parts[0].partition('.')
388384
if dot:
389385
# module
@@ -461,11 +457,11 @@ def build(self, directory: Path) -> pathlib.Path:
461457
with mesonpy._wheelfile.WheelFile(wheel_file, 'w') as whl:
462458
self._wheel_write_metadata(whl)
463459

464-
with mesonpy._util.cli_counter(sum(len(x) for x in self._wheel_files.values())) as counter:
460+
with mesonpy._util.cli_counter(sum(len(x) for x in self._manifest.values())) as counter:
465461

466462
root = 'purelib' if self.is_pure else 'platlib'
467463

468-
for path, entries in self._wheel_files.items():
464+
for path, entries in self._manifest.items():
469465
for dst, src in entries:
470466
counter.update(src)
471467

@@ -761,7 +757,7 @@ def _wheel_builder(self) -> _WheelBuilder:
761757
self._metadata,
762758
self._source_dir,
763759
self._build_dir,
764-
self._install_plan,
760+
self._manifest,
765761
)
766762

767763
@property
@@ -791,31 +787,33 @@ def _info(self, name: str) -> Any:
791787
return json.loads(info.read_text())
792788

793789
@property
794-
def _install_plan(self) -> Dict[str, Dict[str, Dict[str, str]]]:
795-
"""Meson install_plan metadata."""
790+
def _manifest(self) -> DefaultDict[str, List[Tuple[pathlib.Path, str]]]:
791+
"""The files to be added to the wheel, organized by wheel path."""
792+
793+
# Obtain the list of files Meson would install.
796794
install_plan = self._info('intro-install_plan')
797795

798-
# parse install args to extract --tags and --skip-subprojects
796+
# Parse the 'meson install' args to extract --tags and --skip-subprojects
799797
parser = argparse.ArgumentParser()
800798
parser.add_argument('--tags')
801799
parser.add_argument('--skip-subprojects', nargs='?', const='*', default='')
802800
args, _ = parser.parse_known_args(self._meson_args['install'])
803801
install_tags = {t.strip() for t in args.tags.split(',')} if args.tags else None
804802
skip_subprojects = {p for p in (p.strip() for p in args.skip_subprojects.split(',')) if p}
805803

806-
manifest: DefaultDict[str, Dict[str, Dict[str, str]]] = collections.defaultdict(dict)
807-
808-
# filter install_plan accordingly
804+
# Filter the install plan accordingly.
805+
sources: DefaultDict[str, Dict[str, Dict[str, str]]] = collections.defaultdict(dict)
809806
for key, targets in install_plan.items():
810807
for target, details in targets.items():
811808
if install_tags is not None and details['tag'] not in install_tags:
812809
continue
813810
subproject = details.get('subproject')
814811
if subproject is not None and (subproject in skip_subprojects or '*' in skip_subprojects):
815812
continue
816-
manifest[key][target] = details
813+
sources[key][target] = details
817814

818-
return manifest
815+
# Map Meson installation locations to wheel paths.
816+
return _map_to_wheel(sources)
819817

820818
@property
821819
def _meson_name(self) -> str:

tests/test_tags.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,9 @@ def test_python_host_platform(monkeypatch):
6565
def wheel_builder_test_factory(monkeypatch, content, limited_api=False):
6666
files = defaultdict(list)
6767
files.update({key: [(pathlib.Path(x), os.path.join('build', x)) for x in value] for key, value in content.items()})
68-
monkeypatch.setattr(mesonpy._WheelBuilder, '_wheel_files', files)
6968
class Project:
7069
_limited_api = limited_api
71-
return mesonpy._WheelBuilder(Project(), None, pathlib.Path(), pathlib.Path(), pathlib.Path())
70+
return mesonpy._WheelBuilder(Project(), None, pathlib.Path(), pathlib.Path(), files)
7271

7372

7473
def test_tag_empty_wheel(monkeypatch):

0 commit comments

Comments
 (0)