mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-21 20:55:11 +00:00
chore: drop support for PyPy < 7.3.1 and clean up old PyPy workarounds (#2456)
* Remove code inside 'PYPY_VERSION_NUM < 0x06000000' preprocessor if branch * fix: more cleanup * Remove more references to PyPy 5.7 and 5.9 in the docs * Update comment on PyUnicode_UTF* in PyPy Co-authored-by: Henry Schreiner <henryschreineriii@gmail.com>
This commit is contained in:
parent
b70894df52
commit
1411207711
@ -68,7 +68,7 @@ Goodies
|
|||||||
In addition to the core functionality, pybind11 provides some extra
|
In addition to the core functionality, pybind11 provides some extra
|
||||||
goodies:
|
goodies:
|
||||||
|
|
||||||
- Python 2.7, 3.5+, and PyPy (tested on 7.3) are supported with an
|
- Python 2.7, 3.5+, and PyPy/PyPy3 7.3 are supported with an
|
||||||
implementation-agnostic interface.
|
implementation-agnostic interface.
|
||||||
|
|
||||||
- It is possible to bind C++11 lambda functions with captured
|
- It is possible to bind C++11 lambda functions with captured
|
||||||
|
@ -223,7 +223,7 @@ avoids this issue involves weak reference with a cleanup callback:
|
|||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
|
||||||
// Register a callback function that is invoked when the BaseClass object is colelcted
|
// Register a callback function that is invoked when the BaseClass object is collected
|
||||||
py::cpp_function cleanup_callback(
|
py::cpp_function cleanup_callback(
|
||||||
[](py::handle weakref) {
|
[](py::handle weakref) {
|
||||||
// perform cleanup here -- this function is called with the GIL held
|
// perform cleanup here -- this function is called with the GIL held
|
||||||
@ -237,9 +237,9 @@ avoids this issue involves weak reference with a cleanup callback:
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
PyPy (at least version 5.9) does not garbage collect objects when the
|
PyPy does not garbage collect objects when the interpreter exits. An alternative
|
||||||
interpreter exits. An alternative approach (which also works on CPython) is to use
|
approach (which also works on CPython) is to use the :py:mod:`atexit` module [#f7]_,
|
||||||
the :py:mod:`atexit` module [#f7]_, for example:
|
for example:
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
|
|
||||||
|
@ -1277,10 +1277,8 @@ private:
|
|||||||
UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) :
|
UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) :
|
||||||
PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr);
|
PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr);
|
||||||
#else
|
#else
|
||||||
// PyPy seems to have multiple problems related to PyUnicode_UTF*: the UTF8 version
|
// PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as well),
|
||||||
// sometimes segfaults for unknown reasons, while the UTF16 and 32 versions require a
|
// so bypass the whole thing by just passing the encoding as a string value, which works properly:
|
||||||
// non-const char * arguments, which is also a nuisance, so bypass the whole thing by just
|
|
||||||
// passing the encoding as a string value, which works properly:
|
|
||||||
return PyUnicode_Decode(buffer, nbytes, UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr);
|
return PyUnicode_Decode(buffer, nbytes, UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -478,10 +478,6 @@ extern "C" inline int pybind11_clear(PyObject *self) {
|
|||||||
/// Give instances of this type a `__dict__` and opt into garbage collection.
|
/// Give instances of this type a `__dict__` and opt into garbage collection.
|
||||||
inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
|
inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
|
||||||
auto type = &heap_type->ht_type;
|
auto type = &heap_type->ht_type;
|
||||||
#if defined(PYPY_VERSION) && (PYPY_VERSION_NUM < 0x06000000)
|
|
||||||
pybind11_fail(get_fully_qualified_tp_name(type) + ": dynamic attributes are currently not "
|
|
||||||
"supported in conjunction with PyPy!");
|
|
||||||
#endif
|
|
||||||
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
|
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
|
||||||
type->tp_dictoffset = type->tp_basicsize; // place dict at the end
|
type->tp_dictoffset = type->tp_basicsize; // place dict at the end
|
||||||
type->tp_basicsize += (ssize_t)sizeof(PyObject *); // and allocate enough space for it
|
type->tp_basicsize += (ssize_t)sizeof(PyObject *); // and allocate enough space for it
|
||||||
|
@ -66,7 +66,7 @@ void exec(const char (&s)[N], object global = globals(), object local = object()
|
|||||||
eval<eval_statements>(s, global, local);
|
eval<eval_statements>(s, global, local);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x3000000
|
#if defined(PYPY_VERSION) && PY_VERSION_HEX >= 0x03000000
|
||||||
template <eval_mode mode = eval_statements>
|
template <eval_mode mode = eval_statements>
|
||||||
object eval_file(str, object, object) {
|
object eval_file(str, object, object) {
|
||||||
pybind11_fail("eval_file not supported in PyPy3. Use eval");
|
pybind11_fail("eval_file not supported in PyPy3. Use eval");
|
||||||
|
@ -193,14 +193,12 @@ TEST_SUBMODULE(multiple_inheritance, m) {
|
|||||||
.def_readwrite_static("static_value", &VanillaStaticMix2::static_value);
|
.def_readwrite_static("static_value", &VanillaStaticMix2::static_value);
|
||||||
|
|
||||||
|
|
||||||
#if !(defined(PYPY_VERSION) && (PYPY_VERSION_NUM < 0x06000000))
|
|
||||||
struct WithDict { };
|
struct WithDict { };
|
||||||
struct VanillaDictMix1 : Vanilla, WithDict { };
|
struct VanillaDictMix1 : Vanilla, WithDict { };
|
||||||
struct VanillaDictMix2 : WithDict, Vanilla { };
|
struct VanillaDictMix2 : WithDict, Vanilla { };
|
||||||
py::class_<WithDict>(m, "WithDict", py::dynamic_attr()).def(py::init<>());
|
py::class_<WithDict>(m, "WithDict", py::dynamic_attr()).def(py::init<>());
|
||||||
py::class_<VanillaDictMix1, Vanilla, WithDict>(m, "VanillaDictMix1").def(py::init<>());
|
py::class_<VanillaDictMix1, Vanilla, WithDict>(m, "VanillaDictMix1").def(py::init<>());
|
||||||
py::class_<VanillaDictMix2, WithDict, Vanilla>(m, "VanillaDictMix2").def(py::init<>());
|
py::class_<VanillaDictMix2, WithDict, Vanilla>(m, "VanillaDictMix2").def(py::init<>());
|
||||||
#endif
|
|
||||||
|
|
||||||
// test_diamond_inheritance
|
// test_diamond_inheritance
|
||||||
// Issue #959: segfault when constructing diamond inheritance instance
|
// Issue #959: segfault when constructing diamond inheritance instance
|
||||||
|
Loading…
Reference in New Issue
Block a user