Skip to content

Commit 5fe9908

Browse files
dean0x7dwjakob
authored andcommitted
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.
1 parent 5637af7 commit 5fe9908

File tree

2 files changed

+9
-22
lines changed

2 files changed

+9
-22
lines changed

include/pybind11/pybind11.h

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,29 +1177,10 @@ template <typename Type> class enum_ : public class_<Type> {
11771177

11781178
/// Export enumeration entries into the parent scope
11791179
enum_ &export_values() {
1180-
#if !defined(PYPY_VERSION)
1181-
PyObject *dict = ((PyTypeObject *) this->m_ptr)->tp_dict;
1182-
PyObject *key, *value;
1183-
ssize_t pos = 0;
1184-
1185-
while (PyDict_Next(dict, &pos, &key, &value)) {
1186-
if (PyObject_IsInstance(value, this->m_ptr))
1187-
m_parent.attr(key) = value;
1180+
for (auto item : reinterpret_borrow<dict>(((PyTypeObject *) this->m_ptr)->tp_dict)) {
1181+
if (isinstance(item.second, this->m_ptr))
1182+
m_parent.attr(item.first) = item.second;
11881183
}
1189-
#else
1190-
/* PyPy's cpyext still has difficulties with the above
1191-
CPython API calls; emulate using Python code. */
1192-
dict d; d["t"] = *this; d["p"] = m_parent;
1193-
PyObject *result = PyRun_String(
1194-
"for k, v in t.__dict__.items():\n"
1195-
" if isinstance(v, t):\n"
1196-
" setattr(p, k, v)\n",
1197-
Py_file_input, d.ptr(), d.ptr());
1198-
if (result == nullptr)
1199-
throw error_already_set();
1200-
Py_DECREF(result);
1201-
#endif
1202-
12031184
return *this;
12041185
}
12051186

include/pybind11/pytypes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,8 +613,14 @@ class dict_readonly {
613613
};
614614
NAMESPACE_END(iterator_policies)
615615

616+
#if !defined(PYPY_VERSION)
616617
using tuple_iterator = generic_iterator<iterator_policies::sequence_fast_readonly>;
617618
using list_iterator = generic_iterator<iterator_policies::sequence_fast_readonly>;
619+
#else
620+
using tuple_iterator = generic_iterator<iterator_policies::sequence_slow_readwrite>;
621+
using list_iterator = generic_iterator<iterator_policies::sequence_slow_readwrite>;
622+
#endif
623+
618624
using sequence_iterator = generic_iterator<iterator_policies::sequence_slow_readwrite>;
619625
using dict_iterator = generic_iterator<iterator_policies::dict_readonly>;
620626

0 commit comments

Comments
 (0)