Conversation
luhenry
added a commit
that referenced
this pull request
Sep 10, 2026
cp312/cp313/cp314t all hung at the exact same point (render_test.py's setUp creating a second mujoco.GLContext via GLFW) and were killed only by the 360-minute job timeout - not a slow build, a genuine hang, as each build had already reached the test phase within ~70 minutes. Upstream's own CI sets MUJOCO_GL: disable for its "Test Python bindings" step precisely to skip GLContext-dependent tests on headless runners; mirroring that here removes the hang instead of masking it with a bigger timeout.
auditwheel was mangling libmujoco.so.<ver> into mujoco.libs/ only for the mujoco/plugin/*.so files (their RPATH didn't already resolve it the way $ORIGIN does for the main extension modules in mujoco/), producing two independent loaded copies of libmujoco.so in the same process. Since MuJoCo's plugin registry is a global inside libmujoco.so, the plugin .so's registered elasticity/pid/etc. into a copy the main bindings never see, so any XML referencing a plugin failed with "plugin ... not found" - reproduced identically across all four interpreters. The real published PyPI wheel never grafts libmujoco.so at all (verified by inspecting mujoco-3.12.0-cp313-cp313-manylinux_2_27_x86_64...whl): all consumers keep the same unmangled libmujoco.so.<ver> SONAME, so the dynamic loader reuses the one already loaded by the first extension module imported. --exclude reproduces that here.
python/mujoco/__init__.py extends its __path__ via pkgutil.extend_path (so mujoco-mjx can contribute to the same namespace package), and `python -m pytest` prepends cwd to sys.path. Running pytest from /mujoco/python made it resolve `mujoco` to the checkout's package dir (found on sys.path ahead of site-packages) instead of the installed wheel: the compiled extension submodules still resolved fine through the merged __path__, so almost the whole suite passed, but PLUGINS_DIR - derived from that shadowing __file__ - pointed at a python/mujoco/plugin/ that doesn't exist in the checkout, so zero bundled plugins loaded and every plugin XML test failed with "XML Error: plugin ... not found". Confirmed via a temporary in-CI diagnostic (since removed): mjp_pluginCount() and mjs_activatePlugin() are both thin wrappers around the exact same GlobalTable<mjpPlugin> singleton compiled into the one libmujoco.so, so a real per-process registry bug was never plausible once the checkout-shadowing mechanism was found. Upstream's own CI (build_steps.sh:test_python_bindings) runs pytest with no working-directory override at all (i.e. from the repo root, which has no top-level mujoco/ to shadow) - mirror that here.
luhenry
added a commit
that referenced
this pull request
Sep 11, 2026
Root-caused and fixed the 5 plugin-test failures blocking CI: pytest was run from a cd-ed /mujoco/python, and python -m pytest's cwd-prepended sys.path let mujoco's pkgutil.extend_path-based __init__.py resolve to the checkout's python/mujoco/ package (no plugin/ subdirectory there) instead of the installed wheel, so no bundled plugins loaded. Fixed by running pytest from the repo root, matching upstream's own CI.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
mujoco3.12.0Compiles the MuJoCo physics engine plus its pybind11 Python bindings, using upstream's own two-stage CMake flow (core library, then bindings against it) rather than cibuildwheel. Upstream publishes no riscv64 wheel.
Mirrors upstream's
.github/workflows/build.yml/build_steps.sh(configure_mujoco/build_mujoco/install_mujoco, thenbuild_python_bindingsagainstMUJOCO_PATH).Differs from upstream
mujoco.viewer) kept, mirroring the already-publishedglfwriscv64 port's X11/Wayland dnf packages.Testing
pytest --pyargs mujoco), plus anmj_stepsmoke test.License: OK - Apache-2.0, wheel carries upstream's
LICENSEandLICENSES_THIRD_PARTY.md.CI running; will update with pass/skip counts once the first build completes.