Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-08-28 09:02:09

0001 // Copyright (c) 2024 The pybind Community.
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 // Forward declaration needed here: Refactoring opportunity.
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)