Don't pollute the global namespace when using mjpython.
Fixes #2265 PiperOrigin-RevId: 713442833 Change-Id: If155d9f57d4deef8b848478ebd8077a00417d5c5
This commit is contained in:
committed by
Copybara-Service
parent
357ea024c0
commit
40ef08c8ed
@@ -12,6 +12,7 @@ Python bindings
|
|||||||
the computation. The thread pool can be reused across calls, but then the function cannot be called simultaneously
|
the computation. The thread pool can be reused across calls, but then the function cannot be called simultaneously
|
||||||
from multiple threads. To run multiple threaded rollouts simultaneously, use the new class ``Rollout`` which
|
from multiple threads. To run multiple threaded rollouts simultaneously, use the new class ``Rollout`` which
|
||||||
encapsulates the thread pool. Contribution by :github:user:`aftersomemath`.
|
encapsulates the thread pool. Contribution by :github:user:`aftersomemath`.
|
||||||
|
- Fix global namespace pollution when using ``mjpython`` (:github:issue:`2265`).
|
||||||
|
|
||||||
General
|
General
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|||||||
@@ -86,15 +86,33 @@ void* mjpython_pymain(void* vargs) {
|
|||||||
|
|
||||||
// Set up the condition variable to pass control back to the macOS main thread.
|
// Set up the condition variable to pass control back to the macOS main thread.
|
||||||
gil = cpython.PyGILState_Ensure();
|
gil = cpython.PyGILState_Ensure();
|
||||||
cpython.PyRun_SimpleStringFlags("import threading; cond = threading.Condition()", nullptr);
|
cpython.PyRun_SimpleStringFlags(R"(
|
||||||
|
def _mjpython_make_cond():
|
||||||
|
# Don't pollute the global namespace.
|
||||||
|
global _mjpython_make_cond
|
||||||
|
del _mjpython_make_cond
|
||||||
|
|
||||||
|
import threading
|
||||||
|
|
||||||
|
global cond
|
||||||
|
cond = threading.Condition()
|
||||||
|
|
||||||
|
_mjpython_make_cond()
|
||||||
|
)", nullptr);
|
||||||
py_initialized.store(true);
|
py_initialized.store(true);
|
||||||
|
|
||||||
// Wait until GLFW is initialized on macOS main thread, set up the queue and an atexit hook
|
// Wait until GLFW is initialized on macOS main thread, set up the queue and an atexit hook
|
||||||
// to enqueue a termination flag upon exit.
|
// to enqueue a termination flag upon exit.
|
||||||
cpython.PyRun_SimpleStringFlags(R"(
|
cpython.PyRun_SimpleStringFlags(R"(
|
||||||
import atexit
|
def _mjpython_init():
|
||||||
|
# Don't pollute the global namespace.
|
||||||
|
global _mjpython_init
|
||||||
|
del _mjpython_init
|
||||||
|
|
||||||
# The mujoco.viewer module should only be imported here after glfw.init() in the macOS main thread.
|
import atexit
|
||||||
|
import threading
|
||||||
|
|
||||||
|
# The mujoco.viewer module should only be imported after glfw.init() in the macOS main thread.
|
||||||
with cond:
|
with cond:
|
||||||
cond.wait()
|
cond.wait()
|
||||||
import mujoco.viewer
|
import mujoco.viewer
|
||||||
@@ -170,11 +188,11 @@ class _MjPythonImpl(mujoco.viewer._MjPythonBase):
|
|||||||
|
|
||||||
mujoco.viewer._MJPYTHON = _MjPythonImpl()
|
mujoco.viewer._MJPYTHON = _MjPythonImpl()
|
||||||
atexit.register(mujoco.viewer._MJPYTHON.terminate)
|
atexit.register(mujoco.viewer._MJPYTHON.terminate)
|
||||||
del _MjPythonImpl # Don't pollute globals for user script.
|
|
||||||
|
|
||||||
with cond:
|
with cond:
|
||||||
cond.notify()
|
cond.notify()
|
||||||
del cond # Don't pollute globals for user script.
|
|
||||||
|
_mjpython_init()
|
||||||
)", nullptr);
|
)", nullptr);
|
||||||
|
|
||||||
// Run the Python interpreter main loop.
|
// Run the Python interpreter main loop.
|
||||||
@@ -283,6 +301,11 @@ int main(int argc, char** argv) {
|
|||||||
// to finish setting up _MJPYTHON, then serve incoming viewer launch requests.
|
// to finish setting up _MJPYTHON, then serve incoming viewer launch requests.
|
||||||
PyGILState_STATE gil = cpython.PyGILState_Ensure();
|
PyGILState_STATE gil = cpython.PyGILState_Ensure();
|
||||||
cpython.PyRun_SimpleStringFlags(R"(
|
cpython.PyRun_SimpleStringFlags(R"(
|
||||||
|
def _mjpython_main():
|
||||||
|
# Don't pollute the global namespace.
|
||||||
|
global _mjpython_main
|
||||||
|
del _mjpython_main
|
||||||
|
|
||||||
import ctypes
|
import ctypes
|
||||||
|
|
||||||
# GLFW must be initialized on the OS main thread (i.e. here).
|
# GLFW must be initialized on the OS main thread (i.e. here).
|
||||||
@@ -294,9 +317,11 @@ glfw.poll_events()
|
|||||||
ctypes.CDLL(None).mjpython_hide_dock_icon()
|
ctypes.CDLL(None).mjpython_hide_dock_icon()
|
||||||
|
|
||||||
# Wait for Python main thread to finish setting up _MJPYTHON
|
# Wait for Python main thread to finish setting up _MJPYTHON
|
||||||
|
global cond
|
||||||
with cond:
|
with cond:
|
||||||
cond.notify()
|
cond.notify()
|
||||||
cond.wait()
|
cond.wait()
|
||||||
|
del cond
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
@@ -324,6 +349,8 @@ while True:
|
|||||||
|
|
||||||
finally:
|
finally:
|
||||||
mujoco.viewer._MJPYTHON.done()
|
mujoco.viewer._MJPYTHON.done()
|
||||||
|
|
||||||
|
_mjpython_main()
|
||||||
)", nullptr);
|
)", nullptr);
|
||||||
cpython.PyGILState_Release(gil);
|
cpython.PyGILState_Release(gil);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user