Skip to content

Commit 0e89b14

Browse files
committed
Workaround difference between CPython and PyPy's different PyIndex_Check (unnoticed because we currently don't have PyPy >= 3.8)
1 parent 3609fe5 commit 0e89b14

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

include/pybind11/cast.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1020,14 +1020,22 @@ struct type_caster<T, enable_if_t<std::is_arithmetic<T>::value && !is_std_char_t
10201020
if (!src)
10211021
return false;
10221022

1023+
#if !defined(PYPY_VERSION)
1024+
auto index_check = [](PyObject *o) { return PyIndex_Check(o); };
1025+
#else
1026+
// In PyPy 7.3.3, `PyIndex_Check` is implemented by calling `__index__`,
1027+
// while CPython only considers the existence of `nb_index`/`__index__`.
1028+
auto index_check = [](PyObject *o) { return hasattr(o, "__index__"); };
1029+
#endif
1030+
10231031
if (std::is_floating_point<T>::value) {
10241032
if (convert || PyFloat_Check(src.ptr()))
10251033
py_value = (py_type) PyFloat_AsDouble(src.ptr());
10261034
else
10271035
return false;
10281036
} else if (PyFloat_Check(src.ptr())) {
10291037
return false;
1030-
} else if (!convert && !PyIndex_Check(src.ptr()) && !PYBIND11_LONG_CHECK(src.ptr())) {
1038+
} else if (!convert && !index_check(src.ptr()) && !PYBIND11_LONG_CHECK(src.ptr())) {
10311039
return false;
10321040
} else if (std::is_unsigned<py_type>::value) {
10331041
py_value = as_unsigned<py_type>(src.ptr());

0 commit comments

Comments
 (0)