From 5fe9908b7a34e4f4e320e319a528c4f1bdf6a8e6 Mon Sep 17 00:00:00 2001 From: Dean Moldovan Date: Fri, 10 Feb 2017 12:20:24 +0100 Subject: [PATCH] Add and remove some PyPy iterator workarounds * The definition of `PySequence_Fast` is more restrictive on PyPy, so use the slow path instead. * `PyDict_Next` has been fixed in PyPy -> remove workaround. --- include/pybind11/pybind11.h | 25 +++---------------------- include/pybind11/pytypes.h | 6 ++++++ 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 97314332..242ae2af 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -1177,29 +1177,10 @@ public: /// Export enumeration entries into the parent scope enum_ &export_values() { -#if !defined(PYPY_VERSION) - PyObject *dict = ((PyTypeObject *) this->m_ptr)->tp_dict; - PyObject *key, *value; - ssize_t pos = 0; - - while (PyDict_Next(dict, &pos, &key, &value)) { - if (PyObject_IsInstance(value, this->m_ptr)) - m_parent.attr(key) = value; + for (auto item : reinterpret_borrow(((PyTypeObject *) this->m_ptr)->tp_dict)) { + if (isinstance(item.second, this->m_ptr)) + m_parent.attr(item.first) = item.second; } -#else - /* PyPy's cpyext still has difficulties with the above - CPython API calls; emulate using Python code. */ - dict d; d["t"] = *this; d["p"] = m_parent; - PyObject *result = PyRun_String( - "for k, v in t.__dict__.items():\n" - " if isinstance(v, t):\n" - " setattr(p, k, v)\n", - Py_file_input, d.ptr(), d.ptr()); - if (result == nullptr) - throw error_already_set(); - Py_DECREF(result); -#endif - return *this; } diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 998b2c23..e8780912 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -613,8 +613,14 @@ private: }; NAMESPACE_END(iterator_policies) +#if !defined(PYPY_VERSION) using tuple_iterator = generic_iterator; using list_iterator = generic_iterator; +#else +using tuple_iterator = generic_iterator; +using list_iterator = generic_iterator; +#endif + using sequence_iterator = generic_iterator; using dict_iterator = generic_iterator;