Skip to content

Commit

Permalink
ENH: in editable mode raise ImportError when the build command fails
Browse files Browse the repository at this point in the history
  • Loading branch information
lesteve authored and dnicolodi committed Aug 17, 2024
1 parent 691d312 commit 9043123
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 14 deletions.
31 changes: 17 additions & 14 deletions mesonpy/_editable.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,20 +327,23 @@ def _work_to_do(self, env: dict[str, str]) -> bool:

@functools.lru_cache(maxsize=1)
def _rebuild(self) -> Node:
# skip editable wheel lookup during rebuild: during the build
# the module we are rebuilding might be imported causing a
# rebuild loop.
env = os.environ.copy()
env[MARKER] = os.pathsep.join((env.get(MARKER, ''), self._build_path))

if self._verbose or bool(env.get(VERBOSE, '')):
# We want to show some output only if there is some work to do
if self._work_to_do(env):
build_command = ' '.join(self._build_cmd)
print(f'meson-python: building {self._name}: {build_command}', flush=True)
subprocess.run(self._build_cmd, cwd=self._build_path, env=env)
else:
subprocess.run(self._build_cmd, cwd=self._build_path, env=env, stdout=subprocess.DEVNULL)
try:
# Skip editable wheel lookup during rebuild: during the build
# the module we are rebuilding might be imported causing a
# rebuild loop.
env = os.environ.copy()
env[MARKER] = os.pathsep.join((env.get(MARKER, ''), self._build_path))

if self._verbose or bool(env.get(VERBOSE, '')):
# We want to show some output only if there is some work to do.
if self._work_to_do(env):
build_command = ' '.join(self._build_cmd)
print(f'meson-python: building {self._name}: {build_command}', flush=True)
subprocess.run(self._build_cmd, cwd=self._build_path, env=env, check=True)
else:
subprocess.run(self._build_cmd, cwd=self._build_path, env=env, stdout=subprocess.DEVNULL, check=True)
except subprocess.CalledProcessError as exc:
raise ImportError(f're-building the {self._name} meson-python editable wheel package failed') from exc

install_plan_path = os.path.join(self._build_path, 'meson-info', 'intro-install_plan.json')
with open(install_plan_path, 'r', encoding='utf8') as f:
Expand Down
32 changes: 32 additions & 0 deletions tests/test_editable.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,35 @@ def test_editable_verbose(venv, package_complex, editable_complex, monkeypatch):

# Another import without file changes should not show any output
assert venv.python('-c', 'import complex') == ''


@pytest.mark.parametrize('verbose', [False, True], ids=('', 'verbose'))
def test_editable_rebuild_error(package_purelib_and_platlib, tmp_path, verbose):
with mesonpy._project({'builddir': os.fspath(tmp_path)}) as project:

finder = _editable.MesonpyMetaFinder(
project._metadata.name, {'plat', 'pure'},
os.fspath(tmp_path), project._build_command,
verbose=verbose,
)
path = package_purelib_and_platlib / 'plat.c'
code = path.read_text()

try:
# Install editable hooks
sys.meta_path.insert(0, finder)

# Insert invalid code in the extension module source code
path.write_text('return')

# Import module and trigger rebuild: the build fails and ImportErrror is raised
stdout = io.StringIO()
with redirect_stdout(stdout):
with pytest.raises(ImportError, match='re-building the purelib-and-platlib meson-python editable wheel package failed'):
import plat
assert not verbose or stdout.getvalue().startswith('meson-python: building ')

finally:
del sys.meta_path[0]
sys.modules.pop('pure', None)
path.write_text(code)

0 comments on commit 9043123

Please sign in to comment.