From f791dc8648e1f6ec33f402d679b6b116a76d4e1b Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Tue, 19 Oct 2021 14:39:29 -0400 Subject: [PATCH] fix: deprecate make_simple_namespace, fix Python 3.11 (#3374) * fix: deprecate make_simple_namespace, fix Python 3.11 * docs: update links --- docs/advanced/pycpp/object.rst | 13 +++---------- docs/changelog.rst | 8 ++++++-- docs/upgrade.rst | 13 ++++++++++++- include/pybind11/cast.h | 10 ---------- include/pybind11/pybind11.h | 9 +++++++++ tests/test_pytypes.cpp | 2 +- 6 files changed, 31 insertions(+), 24 deletions(-) diff --git a/docs/advanced/pycpp/object.rst b/docs/advanced/pycpp/object.rst index 8bffb83e1..93e1a94d8 100644 --- a/docs/advanced/pycpp/object.rst +++ b/docs/advanced/pycpp/object.rst @@ -41,24 +41,17 @@ A tuple of python objects can be instantiated using :func:`py::make_tuple`: Each element is converted to a supported Python type. A `simple namespace`_ can be instantiated using -:func:`py::make_simple_namespace`: .. code-block:: cpp - using namespace pybind11::literals; // to bring in the `_a` literal - py::object ns = py::make_simple_namespace("spam"_a=py::none(), "eggs"_a=42); + using namespace pybind11::literals; // to bring in the `_a` literal + py::object SimpleNamespace = py::module_::import("types").attr("SimpleNamespace"); + py::object ns = SimpleNamespace("spam"_a=py::none(), "eggs"_a=42); Attributes on a namespace can be modified with the :func:`py::delattr`, :func:`py::getattr`, and :func:`py::setattr` functions. Simple namespaces can be useful as lightweight stand-ins for class instances. -.. note:: - - ``make_simple_namespace`` is not available in Python 2. - -.. versionchanged:: 2.8 - ``make_simple_namespace`` added. - .. _simple namespace: https://docs.python.org/3/library/types.html#types.SimpleNamespace .. _casting_back_and_forth: diff --git a/docs/changelog.rst b/docs/changelog.rst index 0721020db..ee79a1871 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -10,6 +10,10 @@ Starting with version 1.8.0, pybind11 releases use a `semantic versioning IN DEVELOPMENT -------------- +* The simple namespace creation shortcut added in 2.8.0 was deprecated due to + usage of CPython internal API, and will be removed soon. Use + ``py::module_::import("types").attr("SimpleNamespace")``. + `#3374 `_ v2.8.0 (Oct 4, 2021) @@ -25,10 +29,10 @@ New features: ``register_local_exception_translator(ExceptionTranslator&& translator)`` instead of ``register_exception_translator(ExceptionTranslator&& translator)`` to keep your exception remapping code local to the module. - `#2650 `_ + `#2650 `_ * Add ``make_simple_namespace`` function for instantiating Python - ``SimpleNamespace`` objects. + ``SimpleNamespace`` objects. **Deprecated in 2.8.1.** `#2840 `_ * ``pybind11::scoped_interpreter`` and ``initialize_interpreter`` have new diff --git a/docs/upgrade.rst b/docs/upgrade.rst index b2b6b1245..69609ca28 100644 --- a/docs/upgrade.rst +++ b/docs/upgrade.rst @@ -8,7 +8,17 @@ to a new version. But it goes into more detail. This includes things like deprecated APIs and their replacements, build system changes, general code modernization and other useful information. -.. _upgrade-guide-2.6: +.. _upgrade-guide-2.9: + +v2.9 +==== + +* Any usage of the recently added ``py::make_simple_namespace`` should be + converted to using ``py::module_::import("types").attr("SimpleNamespace")`` + instead. + + +.. _upgrade-guide-2.7: v2.7 ==== @@ -34,6 +44,7 @@ to be common: careful review and custom fixes. +.. _upgrade-guide-2.6: v2.6 ==== diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 1ec2080f8..20fbb3258 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -1036,16 +1036,6 @@ template = 0x03030000 -template ()>> -object make_simple_namespace(Args&&... args_) { - PyObject *ns = _PyNamespace_New(dict(std::forward(args_)...).ptr()); - if (!ns) throw error_already_set(); - return reinterpret_steal(ns); -} -#endif - /// \ingroup annotations /// Annotation for arguments struct arg { diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 285f3b18c..095efd9c3 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -1124,6 +1124,15 @@ inline dict globals() { return reinterpret_borrow(p ? p : module_::import("__main__").attr("__dict__").ptr()); } +#if PY_VERSION_HEX >= 0x03030000 +template ()>> +PYBIND11_DEPRECATED("make_simple_namespace should be replaced with py::module_::import(\"types\").attr(\"SimpleNamespace\") ") +object make_simple_namespace(Args&&... args_) { + return module_::import("types").attr("SimpleNamespace")(std::forward(args_)...); +} +#endif + PYBIND11_NAMESPACE_BEGIN(detail) /// Generic support for creating new Python heap types class generic_type : public object { diff --git a/tests/test_pytypes.cpp b/tests/test_pytypes.cpp index 2157dc097..9a1e91881 100644 --- a/tests/test_pytypes.cpp +++ b/tests/test_pytypes.cpp @@ -84,7 +84,7 @@ TEST_SUBMODULE(pytypes, m) { #if PY_VERSION_HEX >= 0x03030000 // test_simple_namespace m.def("get_simple_namespace", []() { - auto ns = py::make_simple_namespace("attr"_a=42, "x"_a="foo", "wrong"_a=1); + auto ns = py::module_::import("types").attr("SimpleNamespace")("attr"_a=42, "x"_a="foo", "wrong"_a=1); py::delattr(ns, "wrong"); py::setattr(ns, "right", py::int_(2)); return ns;