Skip to content

Commit d491766

Browse files
committed
ENH: do not use the 'meson compile' indirection to build the project
meson-python already assumes that the meson build backed is ninja, thus there is no advantage in going through the backend agnostic meson compile command. Invoking ninja directly saves about 200 ms on an average system. This is relevant for editable wheel installations, where the project rebuild is triggered on import. Fixes #324.
1 parent 0d3580d commit d491766

File tree

2 files changed

+19
-26
lines changed

2 files changed

+19
-26
lines changed

mesonpy/__init__.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -681,9 +681,10 @@ def __init__( # noqa: C901
681681
self._env = os.environ.copy()
682682

683683
# prepare environment
684-
ninja_path = _env_ninja_command()
685-
if ninja_path is not None:
686-
self._env.setdefault('NINJA', str(ninja_path))
684+
self._ninja = _env_ninja_command()
685+
if self._ninja is None:
686+
raise ConfigError(f'Could not find ninja version {_NINJA_REQUIRED_VERSION} or newer.')
687+
self._env.setdefault('NINJA', self._ninja)
687688

688689
# setuptools-like ARCHFLAGS environment variable support
689690
if sysconfig.get_platform().startswith('macosx-'):
@@ -857,8 +858,9 @@ def _wheel_builder(self) -> _WheelBuilder:
857858
)
858859

859860
def build_commands(self, install_dir: Optional[pathlib.Path] = None) -> Sequence[Sequence[str]]:
861+
assert self._ninja is not None # help mypy out
860862
return (
861-
('meson', 'compile', *self._meson_args['compile'],),
863+
(self._ninja, *self._meson_args['compile'],),
862864
(
863865
'meson',
864866
'install',

tests/test_project.py

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,7 @@
22
#
33
# SPDX-License-Identifier: MIT
44

5-
import contextlib
65
import platform
7-
import subprocess
8-
import sys
96

107
import pytest
118

@@ -52,35 +49,29 @@ def test_unsupported_python_version(package_unsupported_python_version):
5249
pass
5350

5451

55-
@pytest.mark.skipif(
56-
sys.version_info < (3, 8),
57-
reason="unittest.mock doesn't support the required APIs for this test",
58-
)
59-
def test_user_args(package_user_args, mocker, tmp_path_session):
60-
mocker.patch('mesonpy.Project._meson')
52+
def test_user_args(package_user_args, tmp_path, monkeypatch):
53+
project_run = mesonpy.Project._run
54+
call_args_list = []
6155

62-
def last_two_meson_args():
63-
return [call.args[-2:] for call in mesonpy.Project._meson.call_args_list]
56+
def wrapper(self, cmd):
57+
# intercept and filter out test arguments and forward the call
58+
call_args_list.append(tuple(cmd))
59+
return project_run(self, [x for x in cmd if not x.startswith(('config-', 'cli-'))])
60+
61+
monkeypatch.setattr(mesonpy.Project, '_run', wrapper)
6462

65-
# create the build directory ourselves because Project._meson is mocked
66-
builddir = str(tmp_path_session / 'build')
63+
def last_two_meson_args():
64+
return [args[-2:] for args in call_args_list]
6765

6866
config_settings = {
69-
'builddir': builddir, # use the build directory we created
7067
'dist-args': ('cli-dist',),
7168
'setup-args': ('cli-setup',),
7269
'compile-args': ('cli-compile',),
7370
'install-args': ('cli-install',),
7471
}
7572

76-
with contextlib.suppress(FileNotFoundError):
77-
mesonpy.build_sdist(tmp_path_session / 'dist', config_settings)
78-
79-
# run setup ourselves because Project._meson is mocked
80-
subprocess.run(['meson', 'setup', '.', builddir], check=True)
81-
82-
with contextlib.suppress(FileNotFoundError):
83-
mesonpy.build_wheel(tmp_path_session / 'dist', config_settings)
73+
mesonpy.build_sdist(tmp_path, config_settings)
74+
mesonpy.build_wheel(tmp_path, config_settings)
8475

8576
assert last_two_meson_args() == [
8677
# sdist: calls to 'meson setup' and 'meson dist'

0 commit comments

Comments
 (0)