Add support for GraalPy (#5380)

* Initial support for GraalPy

* Mark tests that currently fail on GraalPy with xfail

* Add graalpy to CI

* Limit test deps on graalpy to available binary wheels

* Skip cmake test installed_function on GraalPy

CMake won't find libpython on GraalPy, it either fails or silently picks
CPython's libpython.

* Factor out setting function docstrings into a macro

* Try to narrow down skipped tests
This commit is contained in:
Michael Šimáček
2024-10-07 23:12:04 +02:00
committed by GitHub
parent 7e418f4924
commit c4a05f9344
42 changed files with 211 additions and 66 deletions

View File

@@ -343,7 +343,7 @@ public:
#else
// Alternate approach for CPython: this does the same as the above, but optimized
// using the CPython API so as to avoid an unneeded attribute lookup.
else if (auto *tp_as_number = src.ptr()->ob_type->tp_as_number) {
else if (auto *tp_as_number = Py_TYPE(src.ptr())->tp_as_number) {
if (PYBIND11_NB_BOOL(tp_as_number)) {
res = (*PYBIND11_NB_BOOL(tp_as_number))(src.ptr());
}

View File

@@ -299,7 +299,7 @@ PYBIND11_WARNING_DISABLE_MSVC(4505)
# define PYBIND11_INTERNAL_NUMPY_1_ONLY_DETECTED
#endif
#if defined(PYPY_VERSION) && !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
#if (defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)) && !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
# define PYBIND11_SIMPLE_GIL_MANAGEMENT
#endif
@@ -387,6 +387,20 @@ PYBIND11_WARNING_POP
#define PYBIND11_CONCAT(first, second) first##second
#define PYBIND11_ENSURE_INTERNALS_READY pybind11::detail::get_internals();
#if !defined(GRAALVM_PYTHON)
# define PYBIND11_PYCFUNCTION_GET_DOC(func) ((func)->m_ml->ml_doc)
# define PYBIND11_PYCFUNCTION_SET_DOC(func, doc) \
do { \
(func)->m_ml->ml_doc = (doc); \
} while (0)
#else
# define PYBIND11_PYCFUNCTION_GET_DOC(func) (GraalPyCFunction_GetDoc((PyObject *) (func)))
# define PYBIND11_PYCFUNCTION_SET_DOC(func, doc) \
do { \
GraalPyCFunction_SetDoc((PyObject *) (func), (doc)); \
} while (0)
#endif
#define PYBIND11_CHECK_PYTHON_VERSION \
{ \
const char *compiled_ver \

View File

@@ -454,7 +454,7 @@ inline void translate_local_exception(std::exception_ptr p) {
inline object get_python_state_dict() {
object state_dict;
#if PYBIND11_INTERNALS_VERSION <= 4 || defined(PYPY_VERSION)
#if PYBIND11_INTERNALS_VERSION <= 4 || defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
state_dict = reinterpret_borrow<object>(PyEval_GetBuiltins());
#else
# if PY_VERSION_HEX < 0x03090000
@@ -727,7 +727,8 @@ const char *c_str(Args &&...args) {
}
inline const char *get_function_record_capsule_name() {
#if PYBIND11_INTERNALS_VERSION > 4
// On GraalPy, pointer equality of the names is currently not guaranteed
#if PYBIND11_INTERNALS_VERSION > 4 && !defined(GRAALVM_PYTHON)
return get_internals().function_record_capsule_name.c_str();
#else
return nullptr;

View File

@@ -459,7 +459,7 @@ PYBIND11_NOINLINE handle get_object_handle(const void *ptr, const detail::type_i
}
inline PyThreadState *get_thread_state_unchecked() {
#if defined(PYPY_VERSION)
#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
return PyThreadState_GET();
#elif PY_VERSION_HEX < 0x030D0000
return _PyThreadState_UncheckedGet();

View File

@@ -94,18 +94,18 @@ void exec(const char (&s)[N], object global = globals(), object local = object()
eval<eval_statements>(s, std::move(global), std::move(local));
}
#if defined(PYPY_VERSION)
#if defined(PYPY_VERSION) || defined(GRAALVM_PYTHON)
template <eval_mode mode = eval_statements>
object eval_file(str, object, object) {
pybind11_fail("eval_file not supported in PyPy3. Use eval");
pybind11_fail("eval_file not supported in this interpreter. Use eval");
}
template <eval_mode mode = eval_statements>
object eval_file(str, object) {
pybind11_fail("eval_file not supported in PyPy3. Use eval");
pybind11_fail("eval_file not supported in this interpreter. Use eval");
}
template <eval_mode mode = eval_statements>
object eval_file(str) {
pybind11_fail("eval_file not supported in PyPy3. Use eval");
pybind11_fail("eval_file not supported in this interpreter. Use eval");
}
#else
template <eval_mode mode = eval_statements>

View File

@@ -573,8 +573,7 @@ protected:
// chain.
chain_start = rec;
rec->next = chain;
auto rec_capsule
= reinterpret_borrow<capsule>(((PyCFunctionObject *) m_ptr)->m_self);
auto rec_capsule = reinterpret_borrow<capsule>(PyCFunction_GET_SELF(m_ptr));
rec_capsule.set_pointer(unique_rec.release());
guarded_strdup.release();
} else {
@@ -634,12 +633,11 @@ protected:
}
}
/* Install docstring */
auto *func = (PyCFunctionObject *) m_ptr;
std::free(const_cast<char *>(func->m_ml->ml_doc));
// Install docstring if it's non-empty (when at least one option is enabled)
func->m_ml->ml_doc
= signatures.empty() ? nullptr : PYBIND11_COMPAT_STRDUP(signatures.c_str());
auto *doc = signatures.empty() ? nullptr : PYBIND11_COMPAT_STRDUP(signatures.c_str());
std::free(const_cast<char *>(PYBIND11_PYCFUNCTION_GET_DOC(func)));
PYBIND11_PYCFUNCTION_SET_DOC(func, doc);
if (rec->is_method) {
m_ptr = PYBIND11_INSTANCE_METHOD_NEW(m_ptr, rec->scope.ptr());
@@ -2780,8 +2778,8 @@ get_type_override(const void *this_ptr, const type_info *this_type, const char *
}
/* Don't call dispatch code if invoked from overridden function.
Unfortunately this doesn't work on PyPy. */
#if !defined(PYPY_VERSION)
Unfortunately this doesn't work on PyPy and GraalPy. */
#if !defined(PYPY_VERSION) && !defined(GRAALVM_PYTHON)
# if PY_VERSION_HEX >= 0x03090000
PyFrameObject *frame = PyThreadState_GetFrame(PyThreadState_Get());
if (frame != nullptr) {

View File

@@ -643,7 +643,7 @@ struct error_fetch_and_normalize {
bool have_trace = false;
if (m_trace) {
#if !defined(PYPY_VERSION)
#if !defined(PYPY_VERSION) && !defined(GRAALVM_PYTHON)
auto *tb = reinterpret_cast<PyTracebackObject *>(m_trace.ptr());
// Get the deepest trace possible.
@@ -1356,7 +1356,7 @@ inline bool PyUnicode_Check_Permissive(PyObject *o) {
# define PYBIND11_STR_CHECK_FUN PyUnicode_Check
#endif
inline bool PyStaticMethod_Check(PyObject *o) { return o->ob_type == &PyStaticMethod_Type; }
inline bool PyStaticMethod_Check(PyObject *o) { return Py_TYPE(o) == &PyStaticMethod_Type; }
class kwargs_proxy : public handle {
public: