Skip to content

Commit d68c896

Browse files
committed
EHN: add tool.meson-python.wheel.exclude setting
1 parent cd44214 commit d68c896

File tree

5 files changed

+46
-2
lines changed

5 files changed

+46
-2
lines changed

docs/reference/pyproject-settings.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,21 @@ use them and examples.
6363

6464
Extra arguments to be passed to the ``meson install`` command.
6565

66+
.. option:: tool.meson-python.wheel.exclude
67+
68+
List of glob patterns matching paths of files that must be excluded from
69+
the Python wheel. The accepted glob patterns are the ones implemented by
70+
the Python :mod:`fnmatch` with case sensitive matching. The paths to be
71+
matched are as they appear in the Meson introspection data, namely they are
72+
rooted in one of the Meson install locations: ``{bindir}``, ``{datadir}``,
73+
``{includedir}``, ``{libdir_shared}``, ``{libdir_static}``, et cetera.
74+
75+
This configuration setting is measure of last resort to exclude installed
76+
files from a Python wheel. It is to be used when the project includes
77+
subprojects that do not allow fine control on the installed files. Better
78+
solutions include the use of Meson install tags and excluding subprojects
79+
to be installed via :option:`tool.meson-python.args.install`.
80+
6681

6782
__ https://docs.python.org/3/c-api/stable.html?highlight=limited%20api#stable-application-binary-interface
6883
__ https://mesonbuild.com/Python-module.html#extension_module

mesonpy/__init__.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import contextlib
1717
import copy
1818
import difflib
19+
import fnmatch
1920
import functools
2021
import importlib.machinery
2122
import io
@@ -111,13 +112,27 @@ 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+
def _compile_patterns(patterns: List[str]) -> Callable[[str], bool]:
116+
if not patterns:
117+
return lambda x: False
118+
func = re.compile('|'.join(fnmatch.translate(os.path.normpath(p)) for p in patterns)).match
119+
return typing.cast('Callable[[str], bool]', func)
120+
121+
122+
def _map_to_wheel(
123+
sources: Dict[str, Dict[str, Any]],
124+
exclude: List[str]
125+
) -> DefaultDict[str, List[Tuple[pathlib.Path, str]]]:
115126
"""Map files to the wheel, organized by wheel installation directory."""
116127
wheel_files: DefaultDict[str, List[Tuple[pathlib.Path, str]]] = collections.defaultdict(list)
117128
packages: Dict[str, str] = {}
129+
excluded = _compile_patterns(exclude)
118130

119131
for key, group in sources.items():
120132
for src, target in group.items():
133+
if excluded(target['destination']):
134+
continue
135+
121136
destination = pathlib.Path(target['destination'])
122137
anchor = destination.parts[0]
123138
dst = pathlib.Path(*destination.parts[1:])
@@ -581,6 +596,9 @@ def _string_or_path(value: Any, name: str) -> str:
581596
'args': _table({
582597
name: _strings for name in _MESON_ARGS_KEYS
583598
}),
599+
'wheel': _table({
600+
'exclude': _strings,
601+
}),
584602
})
585603

586604
table = pyproject.get('tool', {}).get('meson-python', {})
@@ -823,6 +841,9 @@ def __init__(
823841
# from the package, make sure the developers acknowledge this.
824842
self._allow_windows_shared_libs = pyproject_config.get('allow-windows-internal-shared-libs', False)
825843

844+
# Files to be excluded from the wheel
845+
self._excluded_files = pyproject_config.get('wheel', {}).get('exclude', [])
846+
826847
def _run(self, cmd: Sequence[str]) -> None:
827848
"""Invoke a subprocess."""
828849
# Flush the line to ensure that the log line with the executed
@@ -906,7 +927,7 @@ def _manifest(self) -> DefaultDict[str, List[Tuple[pathlib.Path, str]]]:
906927
sources[key][target] = details
907928

908929
# Map Meson installation locations to wheel paths.
909-
return _map_to_wheel(sources)
930+
return _map_to_wheel(sources, self._excluded_files)
910931

911932
@property
912933
def _meson_name(self) -> str:

tests/packages/subproject/pyproject.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,8 @@
55
[build-system]
66
build-backend = 'mesonpy'
77
requires = ['meson-python']
8+
9+
[tool.meson-python.wheel]
10+
# Meson versions before 1.3.0 install data files in {datadir}/{project name}/,
11+
# later versions install in the more correct {datadir}/{dubproject name}/
12+
exclude = ['{datadir}/*/data.txt']
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
excluded via tool.meson-python.wheel.exclude

tests/packages/subproject/subprojects/dep/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ project('dep')
77
py = import('python').find_installation()
88

99
py.install_sources('dep.py')
10+
11+
install_data('data.txt')

0 commit comments

Comments
 (0)