File indexing completed on 2025-08-28 09:02:09
0001
0002
0003 #pragma once
0004
0005 #include <pybind11/pytypes.h>
0006
0007 #include "common.h"
0008 #include "internals.h"
0009
0010 #include <typeinfo>
0011
0012 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
0013 PYBIND11_NAMESPACE_BEGIN(detail)
0014
0015
0016 extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *);
0017
0018 inline bool type_is_managed_by_our_internals(PyTypeObject *type_obj) {
0019 #if defined(PYPY_VERSION)
0020 auto &internals = get_internals();
0021 return bool(internals.registered_types_py.find(type_obj)
0022 != internals.registered_types_py.end());
0023 #else
0024 return bool(type_obj->tp_new == pybind11_object_new);
0025 #endif
0026 }
0027
0028 inline bool is_instance_method_of_type(PyTypeObject *type_obj, PyObject *attr_name) {
0029 PyObject *descr = _PyType_Lookup(type_obj, attr_name);
0030 return bool((descr != nullptr) && PyInstanceMethod_Check(descr));
0031 }
0032
0033 inline object try_get_cpp_conduit_method(PyObject *obj) {
0034 if (PyType_Check(obj)) {
0035 return object();
0036 }
0037 PyTypeObject *type_obj = Py_TYPE(obj);
0038 str attr_name("_pybind11_conduit_v1_");
0039 bool assumed_to_be_callable = false;
0040 if (type_is_managed_by_our_internals(type_obj)) {
0041 if (!is_instance_method_of_type(type_obj, attr_name.ptr())) {
0042 return object();
0043 }
0044 assumed_to_be_callable = true;
0045 }
0046 PyObject *method = PyObject_GetAttr(obj, attr_name.ptr());
0047 if (method == nullptr) {
0048 PyErr_Clear();
0049 return object();
0050 }
0051 if (!assumed_to_be_callable && PyCallable_Check(method) == 0) {
0052 Py_DECREF(method);
0053 return object();
0054 }
0055 return reinterpret_steal<object>(method);
0056 }
0057
0058 inline void *try_raw_pointer_ephemeral_from_cpp_conduit(handle src,
0059 const std::type_info *cpp_type_info) {
0060 object method = try_get_cpp_conduit_method(src.ptr());
0061 if (method) {
0062 capsule cpp_type_info_capsule(const_cast<void *>(static_cast<const void *>(cpp_type_info)),
0063 typeid(std::type_info).name());
0064 object cpp_conduit = method(bytes(PYBIND11_PLATFORM_ABI_ID),
0065 cpp_type_info_capsule,
0066 bytes("raw_pointer_ephemeral"));
0067 if (isinstance<capsule>(cpp_conduit)) {
0068 return reinterpret_borrow<capsule>(cpp_conduit).get_pointer();
0069 }
0070 }
0071 return nullptr;
0072 }
0073
0074 #define PYBIND11_HAS_CPP_CONDUIT 1
0075
0076 PYBIND11_NAMESPACE_END(detail)
0077 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)