13 #include "../options.h"
15 PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
16 PYBIND11_NAMESPACE_BEGIN(detail)
18 #if PY_VERSION_HEX >= 0x03030000 && !defined(PYPY_VERSION)
19 # define PYBIND11_BUILTIN_QUALNAME
20 # define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)
24 # define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) setattr((PyObject *) obj, "__qualname__", nameobj)
27 inline std::string get_fully_qualified_tp_name(PyTypeObject *
type) {
28 #if !defined(PYPY_VERSION)
31 auto module_name =
handle((PyObject *)
type).attr(
"__module__").
cast<std::string>();
32 if (module_name == PYBIND11_BUILTINS_MODULE)
35 return std::move(module_name) +
"." +
type->tp_name;
39 inline PyTypeObject *type_incref(PyTypeObject *
type) {
44 #if !defined(PYPY_VERSION)
47 extern "C" inline PyObject *pybind11_static_get(PyObject *
self, PyObject * , PyObject *cls) {
48 return PyProperty_Type.tp_descr_get(
self, cls, cls);
52 extern "C" inline int pybind11_static_set(PyObject *
self, PyObject *obj, PyObject *value) {
53 PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj);
54 return PyProperty_Type.tp_descr_set(
self, cls, value);
60 inline PyTypeObject *make_static_property_type() {
61 constexpr
auto *
name =
"pybind11_static_property";
62 auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(
name));
68 auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
70 pybind11_fail(
"make_static_property_type(): error allocating type!");
72 heap_type->ht_name = name_obj.inc_ref().ptr();
73 #ifdef PYBIND11_BUILTIN_QUALNAME
74 heap_type->ht_qualname = name_obj.inc_ref().ptr();
77 auto type = &heap_type->ht_type;
79 type->tp_base = type_incref(&PyProperty_Type);
80 type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
81 type->tp_descr_get = pybind11_static_get;
82 type->tp_descr_set = pybind11_static_set;
84 if (PyType_Ready(
type) < 0)
85 pybind11_fail(
"make_static_property_type(): failure in PyType_Ready()!");
87 setattr((PyObject *)
type,
"__module__",
str(
"pybind11_builtins"));
88 PYBIND11_SET_OLDPY_QUALNAME(
type, name_obj);
98 inline PyTypeObject *make_static_property_type() {
100 PyObject *result = PyRun_String(R
"(\
101 class pybind11_static_property(property):
102 def __get__(self, obj, cls):
103 return property.__get__(self, cls, cls)
105 def __set__(self, obj, value):
106 cls = obj if isinstance(obj, type) else type(obj)
107 property.__set__(self, cls, value)
108 )", Py_file_input, d.ptr(), d.ptr()
110 if (result ==
nullptr)
113 return (PyTypeObject *) d[
"pybind11_static_property"].cast<
object>().release().ptr();
122 extern "C" inline int pybind11_meta_setattro(PyObject* obj, PyObject*
name, PyObject* value) {
125 PyObject *
descr = _PyType_Lookup((PyTypeObject *) obj,
name);
131 const auto static_prop = (PyObject *) get_internals().static_property_type;
132 const auto call_descr_set =
descr && PyObject_IsInstance(
descr, static_prop)
133 && !PyObject_IsInstance(value, static_prop);
134 if (call_descr_set) {
136 #if !defined(PYPY_VERSION)
137 return Py_TYPE(
descr)->tp_descr_set(
descr, obj, value);
139 if (PyObject *result = PyObject_CallMethod(
descr,
"__set__",
"OO", obj, value)) {
148 return PyType_Type.tp_setattro(obj,
name, value);
152 #if PY_MAJOR_VERSION >= 3
159 extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *
name) {
160 PyObject *
descr = _PyType_Lookup((PyTypeObject *) obj,
name);
166 return PyType_Type.tp_getattro(obj,
name);
172 extern "C" inline PyObject *pybind11_meta_call(PyObject *
type, PyObject *
args, PyObject *
kwargs) {
176 if (
self ==
nullptr) {
181 auto instance =
reinterpret_cast<detail::instance *
>(
self);
185 if (!vh.holder_constructed()) {
186 PyErr_Format(PyExc_TypeError,
"%.200s.__init__() must be called when overriding __init__",
187 get_fully_qualified_tp_name(vh.type->type).c_str());
197 extern "C" inline void pybind11_meta_dealloc(PyObject *obj) {
198 auto *
type = (PyTypeObject *) obj;
205 if (found_type !=
internals.registered_types_py.end() &&
206 found_type->second.size() == 1 &&
207 found_type->second[0]->type ==
type) {
209 auto *tinfo = found_type->second[0];
210 auto tindex = std::type_index(*tinfo->cpptype);
211 internals.direct_conversions.erase(tindex);
213 if (tinfo->module_local)
214 registered_local_types_cpp().erase(tindex);
216 internals.registered_types_cpp.erase(tindex);
217 internals.registered_types_py.erase(tinfo->type);
220 auto &cache =
internals.inactive_override_cache;
221 for (
auto it = cache.begin(), last = cache.end(); it != last; ) {
222 if (it->first == (PyObject *) tinfo->type)
223 it = cache.erase(it);
231 PyType_Type.tp_dealloc(obj);
237 inline PyTypeObject* make_default_metaclass() {
238 constexpr
auto *
name =
"pybind11_type";
239 auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(
name));
245 auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
247 pybind11_fail(
"make_default_metaclass(): error allocating metaclass!");
249 heap_type->ht_name = name_obj.inc_ref().ptr();
250 #ifdef PYBIND11_BUILTIN_QUALNAME
251 heap_type->ht_qualname = name_obj.inc_ref().ptr();
254 auto type = &heap_type->ht_type;
256 type->tp_base = type_incref(&PyType_Type);
257 type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
259 type->tp_call = pybind11_meta_call;
261 type->tp_setattro = pybind11_meta_setattro;
262 #if PY_MAJOR_VERSION >= 3
263 type->tp_getattro = pybind11_meta_getattro;
266 type->tp_dealloc = pybind11_meta_dealloc;
268 if (PyType_Ready(
type) < 0)
269 pybind11_fail(
"make_default_metaclass(): failure in PyType_Ready()!");
271 setattr((PyObject *)
type,
"__module__",
str(
"pybind11_builtins"));
272 PYBIND11_SET_OLDPY_QUALNAME(
type, name_obj);
280 inline void traverse_offset_bases(
void *valueptr,
const detail::type_info *tinfo,
instance *
self,
282 for (
handle h : reinterpret_borrow<tuple>(tinfo->type->tp_bases)) {
283 if (
auto parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) {
284 for (
auto &c : parent_tinfo->implicit_casts) {
285 if (c.first == tinfo->cpptype) {
286 auto *parentptr = c.second(valueptr);
287 if (parentptr != valueptr)
289 traverse_offset_bases(parentptr, parent_tinfo,
self, f);
297 inline bool register_instance_impl(
void *ptr,
instance *
self) {
298 get_internals().registered_instances.emplace(ptr,
self);
301 inline bool deregister_instance_impl(
void *ptr,
instance *
self) {
302 auto ®istered_instances = get_internals().registered_instances;
303 auto range = registered_instances.equal_range(ptr);
304 for (
auto it = range.first; it != range.second; ++it) {
305 if (
self == it->second) {
306 registered_instances.erase(it);
313 inline void register_instance(
instance *
self,
void *valptr,
const type_info *tinfo) {
314 register_instance_impl(valptr,
self);
315 if (!tinfo->simple_ancestors)
316 traverse_offset_bases(valptr, tinfo,
self, register_instance_impl);
319 inline bool deregister_instance(
instance *
self,
void *valptr,
const type_info *tinfo) {
320 bool ret = deregister_instance_impl(valptr,
self);
321 if (!tinfo->simple_ancestors)
322 traverse_offset_bases(valptr, tinfo,
self, deregister_instance_impl);
329 inline PyObject *make_new_instance(PyTypeObject *
type) {
330 #if defined(PYPY_VERSION)
333 ssize_t instance_size =
static_cast<ssize_t
>(
sizeof(
instance));
334 if (
type->tp_basicsize < instance_size) {
335 type->tp_basicsize = instance_size;
338 PyObject *
self =
type->tp_alloc(
type, 0);
339 auto inst =
reinterpret_cast<instance *
>(
self);
350 extern "C" inline PyObject *pybind11_object_new(PyTypeObject *
type, PyObject *, PyObject *) {
351 return make_new_instance(
type);
357 extern "C" inline int pybind11_object_init(PyObject *
self, PyObject *, PyObject *) {
358 PyTypeObject *
type = Py_TYPE(
self);
359 std::string msg = get_fully_qualified_tp_name(
type) +
": No constructor defined!";
360 PyErr_SetString(PyExc_TypeError, msg.c_str());
364 inline void add_patient(PyObject *nurse, PyObject *patient) {
366 auto instance =
reinterpret_cast<detail::instance *
>(nurse);
369 internals.patients[nurse].push_back(patient);
372 inline void clear_patients(PyObject *
self) {
373 auto instance =
reinterpret_cast<detail::instance *
>(
self);
375 auto pos =
internals.patients.find(
self);
380 auto patients = std::move(pos->second);
383 for (PyObject *&patient : patients)
389 inline void clear_instance(PyObject *
self) {
390 auto instance =
reinterpret_cast<detail::instance *
>(
self);
398 if (v_h.instance_registered() && !deregister_instance(
instance, v_h.value_ptr(), v_h.type))
399 pybind11_fail(
"pybind11_object_dealloc(): Tried to deallocate unregistered instance!");
402 v_h.type->dealloc(v_h);
409 PyObject_ClearWeakRefs(
self);
411 PyObject **dict_ptr = _PyObject_GetDictPtr(
self);
416 clear_patients(
self);
421 extern "C" inline void pybind11_object_dealloc(PyObject *
self) {
422 clear_instance(
self);
424 auto type = Py_TYPE(
self);
427 #if PY_VERSION_HEX < 0x03080000
432 auto pybind11_object_type = (PyTypeObject *) get_internals().instance_base;
433 if (
type->tp_dealloc == pybind11_object_type->tp_dealloc)
445 inline PyObject *make_object_base_type(PyTypeObject *
metaclass) {
446 constexpr
auto *
name =
"pybind11_object";
447 auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(
name));
455 pybind11_fail(
"make_object_base_type(): error allocating type!");
457 heap_type->ht_name = name_obj.inc_ref().ptr();
458 #ifdef PYBIND11_BUILTIN_QUALNAME
459 heap_type->ht_qualname = name_obj.inc_ref().ptr();
462 auto type = &heap_type->ht_type;
464 type->tp_base = type_incref(&PyBaseObject_Type);
465 type->tp_basicsize =
static_cast<ssize_t
>(
sizeof(
instance));
466 type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
468 type->tp_new = pybind11_object_new;
469 type->tp_init = pybind11_object_init;
470 type->tp_dealloc = pybind11_object_dealloc;
475 if (PyType_Ready(
type) < 0)
476 pybind11_fail(
"PyType_Ready failed in make_object_base_type():" + error_string());
478 setattr((PyObject *)
type,
"__module__",
str(
"pybind11_builtins"));
479 PYBIND11_SET_OLDPY_QUALNAME(
type, name_obj);
481 assert(!PyType_HasFeature(
type, Py_TPFLAGS_HAVE_GC));
482 return (PyObject *) heap_type;
486 extern "C" inline PyObject *pybind11_get_dict(PyObject *
self,
void *) {
487 PyObject *&
dict = *_PyObject_GetDictPtr(
self);
495 extern "C" inline int pybind11_set_dict(PyObject *
self, PyObject *new_dict,
void *) {
496 if (!PyDict_Check(new_dict)) {
497 PyErr_Format(PyExc_TypeError,
"__dict__ must be set to a dictionary, not a '%.200s'",
498 get_fully_qualified_tp_name(Py_TYPE(new_dict)).c_str());
501 PyObject *&
dict = *_PyObject_GetDictPtr(
self);
509 extern "C" inline int pybind11_traverse(PyObject *
self, visitproc visit,
void *
arg) {
510 PyObject *&
dict = *_PyObject_GetDictPtr(
self);
516 extern "C" inline int pybind11_clear(PyObject *
self) {
517 PyObject *&
dict = *_PyObject_GetDictPtr(
self);
523 inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
524 auto type = &heap_type->ht_type;
525 type->tp_flags |= Py_TPFLAGS_HAVE_GC;
526 type->tp_dictoffset =
type->tp_basicsize;
527 type->tp_basicsize += (ssize_t)
sizeof(PyObject *);
528 type->tp_traverse = pybind11_traverse;
529 type->tp_clear = pybind11_clear;
531 static PyGetSetDef getset[] = {
532 {
const_cast<char*
>(
"__dict__"), pybind11_get_dict, pybind11_set_dict,
nullptr,
nullptr},
533 {
nullptr,
nullptr,
nullptr,
nullptr,
nullptr}
535 type->tp_getset = getset;
539 extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view,
int flags) {
542 for (
auto type : reinterpret_borrow<tuple>(Py_TYPE(obj)->tp_mro)) {
543 tinfo = get_type_info((PyTypeObject *)
type.
ptr());
544 if (tinfo && tinfo->get_buffer)
547 if (view ==
nullptr || !tinfo || !tinfo->get_buffer) {
550 PyErr_SetString(PyExc_BufferError,
"pybind11_getbuffer(): Internal error");
553 std::memset(view, 0,
sizeof(Py_buffer));
554 buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data);
557 view->internal = info;
558 view->buf = info->ptr;
559 view->itemsize = info->itemsize;
560 view->len = view->itemsize;
561 for (
auto s : info->shape)
563 view->readonly = info->readonly;
564 if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE && info->readonly) {
567 PyErr_SetString(PyExc_BufferError,
"Writable buffer requested for readonly storage");
570 if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
571 view->format =
const_cast<char *
>(info->format.c_str());
572 if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
573 view->ndim = (int) info->ndim;
574 view->strides = &info->strides[0];
575 view->shape = &info->shape[0];
577 Py_INCREF(view->obj);
582 extern "C" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) {
587 inline void enable_buffer_protocol(PyHeapTypeObject *heap_type) {
588 heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer;
589 #if PY_MAJOR_VERSION < 3
590 heap_type->ht_type.tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
593 heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer;
594 heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer;
599 inline PyObject* make_new_python_type(
const type_record &rec) {
600 auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING(rec.
name));
602 auto qualname =
name;
603 if (rec.
scope && !PyModule_Check(rec.
scope.
ptr()) && hasattr(rec.
scope,
"__qualname__")) {
604 #if PY_MAJOR_VERSION >= 3
605 qualname = reinterpret_steal<object>(
606 PyUnicode_FromFormat(
"%U.%U", rec.
scope.attr(
"__qualname__").
ptr(),
name.ptr()));
608 qualname =
str(rec.
scope.attr(
"__qualname__").
cast<std::string>() +
"." + rec.
name);
614 if (hasattr(rec.
scope,
"__module__"))
616 else if (hasattr(rec.
scope,
"__name__"))
620 auto full_name = c_str(
621 #
if !defined(PYPY_VERSION)
626 char *tp_doc =
nullptr;
627 if (rec.
doc && options::show_user_defined_docstrings()) {
630 size_t size = strlen(rec.
doc) + 1;
631 tp_doc = (
char *) PyObject_MALLOC(size);
632 memcpy((
void *) tp_doc, rec.
doc, size);
649 pybind11_fail(std::string(rec.
name) +
": Unable to create type object!");
651 heap_type->ht_name =
name.release().ptr();
652 #ifdef PYBIND11_BUILTIN_QUALNAME
653 heap_type->ht_qualname = qualname.inc_ref().ptr();
656 auto type = &heap_type->ht_type;
657 type->tp_name = full_name;
658 type->tp_doc = tp_doc;
659 type->tp_base = type_incref((PyTypeObject *)
base);
660 type->tp_basicsize =
static_cast<ssize_t
>(
sizeof(
instance));
665 type->tp_init = pybind11_object_init;
668 type->tp_as_number = &heap_type->as_number;
669 type->tp_as_sequence = &heap_type->as_sequence;
670 type->tp_as_mapping = &heap_type->as_mapping;
671 #if PY_VERSION_HEX >= 0x03050000
672 type->tp_as_async = &heap_type->as_async;
676 type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE;
677 #if PY_MAJOR_VERSION < 3
678 type->tp_flags |= Py_TPFLAGS_CHECKTYPES;
681 type->tp_flags |= Py_TPFLAGS_BASETYPE;
684 enable_dynamic_attributes(heap_type);
687 enable_buffer_protocol(heap_type);
689 if (PyType_Ready(
type) < 0)
690 pybind11_fail(std::string(rec.
name) +
": PyType_Ready failed (" + error_string() +
")!");
693 : !PyType_HasFeature(
type, Py_TPFLAGS_HAVE_GC));
704 PYBIND11_SET_OLDPY_QUALNAME(
type, qualname);
706 return (PyObject *)
type;
709 PYBIND11_NAMESPACE_END(detail)
710 PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
PyObject * ptr() const
Return the underlying PyObject * pointer.
Wrapper for Python extension modules.
Annotation indicating that a class derives from another given type.
Information record describing a Python buffer object.
The 'instance' type which needs to be standard layout (need to be able to use 'offsetof')
void allocate_layout()
Initializes all of the above type/values/holders data (but not the instance values themselves)
void deallocate_layout()
Destroys/deallocates all of the above.
bool owned
If true, the pointer is owned which means we're free to manage it with a holder.
bool has_patients
If true, get_internals().patients has an entry for this object.
PyObject * weakrefs
Weak references.
Annotation for function names.
Special data structure which (temporarily) holds metadata about a bound class.
handle scope
Handle to the parent scope.
list bases
List of base classes of the newly created type.
bool buffer_protocol
Does the class implement the buffer protocol?
const char * doc
Optional docstring.
const char * name
Name of the class.
bool is_final
Is the class inheritable from python classes?
bool dynamic_attr
Does the class manage a dict?
handle metaclass
Custom metaclass (optional)