From f0a9ebd9cd384ac554312247526b120102563e53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nico=20Schl=C3=B6mer?= Date: Fri, 6 Oct 2023 12:25:21 +0200 Subject: [PATCH] added ``nb::globals()`` function wrapping ``PyEval_GetGlobals()`` (#311) --- docs/changelog.rst | 6 ++++++ include/nanobind/nb_misc.h | 7 +++++++ tests/test_eval.cpp | 10 ++++++++++ tests/test_eval.py | 11 +++++++++++ 4 files changed, 34 insertions(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index c50a8bfb..6123508f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -15,6 +15,12 @@ case, both modules must use the same nanobind ABI version, or they will be isolated from each other. Releases that don't explicitly mention an ABI version below inherit that of the preceding release. +Version 1.7.0 (TBA) +------------------- + +* Added :cpp:func:`nb::globals() `. (PR `#311 + `__). + Version 1.6.2 (Oct 3, 2023) ------------------- diff --git a/include/nanobind/nb_misc.h b/include/nanobind/nb_misc.h index 9f93a7b2..319fbda6 100644 --- a/include/nanobind/nb_misc.h +++ b/include/nanobind/nb_misc.h @@ -39,6 +39,13 @@ inline void set_implicit_cast_warnings(bool value) noexcept { detail::set_implicit_cast_warnings(value); } +inline dict globals() { + PyObject *p = PyEval_GetGlobals(); + if (!p) + detail::raise("nanobind::globals(): no frame is currently executing!"); + return borrow(p); +} + inline bool is_alive() noexcept { return detail::is_alive(); } diff --git a/tests/test_eval.cpp b/tests/test_eval.cpp index 69bbd79a..599e6fed 100644 --- a/tests/test_eval.cpp +++ b/tests/test_eval.cpp @@ -74,4 +74,14 @@ NB_MODULE(test_eval_ext, m) { local); return std::make_pair(global, local); }); + + m.def("globals_contains_a", []() { + return nb::globals().contains("a"); + }); + + m.def("globals_add_b", []() { + auto globals = nb::globals(); + globals["b"] = 123; + return globals; + }); } diff --git a/tests/test_eval.py b/tests/test_eval.py index f050b7e7..7c669a0b 100644 --- a/tests/test_eval.py +++ b/tests/test_eval.py @@ -31,3 +31,14 @@ def test_eval_closure(): assert "func_local" not in global_ with pytest.raises(NameError): local["func_local"]() + +a = 1 + +def test_read_globals(): + assert m.globals_contains_a() + + +def test_write_globals(): + assert "b" not in globals() + m.globals_add_b() + assert globals()["b"] == 123