1 /*
2 Copyright (c) 2016 Wenzel Jakob <wenzel.jakob@epfl.ch>
3
4 All rights reserved. Use of this source code is governed by a
5 BSD-style license that can be found in the LICENSE file.
6 */
7
8
9
10
11 #pragma once
12
13 #include "../attr.h"
14
15 NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
NAMESPACE_BEGIN(detail)16 NAMESPACE_BEGIN(detail)
17
18 #if PY_VERSION_HEX >= 0x03030000
19 # define PYBIND11_BUILTIN_QUALNAME
20 # define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj)
21 #else
22
23
24 # define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) setattr((PyObject *) obj, "__qualname__", nameobj)
25 #endif
26
27 inline PyTypeObject *type_incref(PyTypeObject *type) {
28 Py_INCREF(type);
29 return type;
30 }
31
32 #if !defined(PYPY_VERSION)
33
34
pybind11_static_get(PyObject * self,PyObject *,PyObject * cls)35 extern "C" inline PyObject *pybind11_static_get(PyObject *self, PyObject * , PyObject *cls) {
36 return PyProperty_Type.tp_descr_get(self, cls, cls);
37 }
38
39
pybind11_static_set(PyObject * self,PyObject * obj,PyObject * value)40 extern "C" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) {
41 PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj);
42 return PyProperty_Type.tp_descr_set(self, cls, value);
43 }
44
45
make_static_property_type()46 inline PyTypeObject *make_static_property_type() {
47 constexpr auto *name = "pybind11_static_property";
48 auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));
49
50
51 auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
52 if (!heap_type)
53 pybind11_fail("make_static_property_type(): error allocating type!");
54
55 heap_type->ht_name = name_obj.inc_ref().ptr();
56 #ifdef PYBIND11_BUILTIN_QUALNAME
57 heap_type->ht_qualname = name_obj.inc_ref().ptr();
58 #endif
59
60 auto type = &heap_type->ht_type;
61 type->tp_name = name;
62 type->tp_base = type_incref(&PyProperty_Type);
63 type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
64 type->tp_descr_get = pybind11_static_get;
65 type->tp_descr_set = pybind11_static_set;
66
67 if (PyType_Ready(type) < 0)
68 pybind11_fail("make_static_property_type(): failure in PyType_Ready()!");
69
70 setattr((PyObject *) type, "__module__", str("pybind11_builtins"));
71 PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);
72
73 return type;
74 }
75
76 #else
77
78
make_static_property_type()79 inline PyTypeObject *make_static_property_type() {
80 auto d = dict();
81 PyObject *result = PyRun_String(R"(\
82 class pybind11_static_property(property):
83 def __get__(self, obj, cls):
84 return property.__get__(self, cls, cls)
85
86 def __set__(self, obj, value):
87 cls = obj if isinstance(obj, type) else type(obj)
88 property.__set__(self, cls, value)
89 )", Py_file_input, d.ptr(), d.ptr()
90 );
91 if (result == nullptr)
92 throw error_already_set();
93 Py_DECREF(result);
94 return (PyTypeObject *) d["pybind11_static_property"].cast<object>().release().ptr();
95 }
96
97 #endif
98
99
pybind11_meta_setattro(PyObject * obj,PyObject * name,PyObject * value)100 extern "C" inline int pybind11_meta_setattro(PyObject* obj, PyObject* name, PyObject* value) {
101
102
103 PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);
104
105
106
107
108
109 const auto static_prop = (PyObject *) get_internals().static_property_type;
110 const auto call_descr_set = descr && PyObject_IsInstance(descr, static_prop)
111 && !PyObject_IsInstance(value, static_prop);
112 if (call_descr_set) {
113
114 #if !defined(PYPY_VERSION)
115 return Py_TYPE(descr)->tp_descr_set(descr, obj, value);
116 #else
117 if (PyObject *result = PyObject_CallMethod(descr, "__set__", "OO", obj, value)) {
118 Py_DECREF(result);
119 return 0;
120 } else {
121 return -1;
122 }
123 #endif
124 } else {
125
126 return PyType_Type.tp_setattro(obj, name, value);
127 }
128 }
129
130 #if PY_MAJOR_VERSION >= 3
131
pybind11_meta_getattro(PyObject * obj,PyObject * name)132 extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name) {
133 PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name);
134 if (descr && PyInstanceMethod_Check(descr)) {
135 Py_INCREF(descr);
136 return descr;
137 }
138 else {
139 return PyType_Type.tp_getattro(obj, name);
140 }
141 }
142 #endif
143
144
make_default_metaclass()145 inline PyTypeObject* make_default_metaclass() {
146 constexpr auto *name = "pybind11_type";
147 auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));
148
149
150 auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0);
151 if (!heap_type)
152 pybind11_fail("make_default_metaclass(): error allocating metaclass!");
153
154 heap_type->ht_name = name_obj.inc_ref().ptr();
155 #ifdef PYBIND11_BUILTIN_QUALNAME
156 heap_type->ht_qualname = name_obj.inc_ref().ptr();
157 #endif
158
159 auto type = &heap_type->ht_type;
160 type->tp_name = name;
161 type->tp_base = type_incref(&PyType_Type);
162 type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
163
164 type->tp_setattro = pybind11_meta_setattro;
165 #if PY_MAJOR_VERSION >= 3
166 type->tp_getattro = pybind11_meta_getattro;
167 #endif
168
169 if (PyType_Ready(type) < 0)
170 pybind11_fail("make_default_metaclass(): failure in PyType_Ready()!");
171
172 setattr((PyObject *) type, "__module__", str("pybind11_builtins"));
173 PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);
174
175 return type;
176 }
177
178
179
180
traverse_offset_bases(void * valueptr,const detail::type_info * tinfo,instance * self,bool (* f)(void *,instance *))181 inline void traverse_offset_bases(void *valueptr, const detail::type_info *tinfo, instance *self,
182 bool (*f)(void * , instance * )) {
183 for (handle h : reinterpret_borrow<tuple>(tinfo->type->tp_bases)) {
184 if (auto parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) {
185 for (auto &c : parent_tinfo->implicit_casts) {
186 if (c.first == tinfo->cpptype) {
187 auto *parentptr = c.second(valueptr);
188 if (parentptr != valueptr)
189 f(parentptr, self);
190 traverse_offset_bases(parentptr, parent_tinfo, self, f);
191 break;
192 }
193 }
194 }
195 }
196 }
197
register_instance_impl(void * ptr,instance * self)198 inline bool register_instance_impl(void *ptr, instance *self) {
199 get_internals().registered_instances.emplace(ptr, self);
200 return true;
201 }
deregister_instance_impl(void * ptr,instance * self)202 inline bool deregister_instance_impl(void *ptr, instance *self) {
203 auto ®istered_instances = get_internals().registered_instances;
204 auto range = registered_instances.equal_range(ptr);
205 for (auto it = range.first; it != range.second; ++it) {
206 if (Py_TYPE(self) == Py_TYPE(it->second)) {
207 registered_instances.erase(it);
208 return true;
209 }
210 }
211 return false;
212 }
213
register_instance(instance * self,void * valptr,const type_info * tinfo)214 inline void register_instance(instance *self, void *valptr, const type_info *tinfo) {
215 register_instance_impl(valptr, self);
216 if (!tinfo->simple_ancestors)
217 traverse_offset_bases(valptr, tinfo, self, register_instance_impl);
218 }
219
deregister_instance(instance * self,void * valptr,const type_info * tinfo)220 inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo) {
221 bool ret = deregister_instance_impl(valptr, self);
222 if (!tinfo->simple_ancestors)
223 traverse_offset_bases(valptr, tinfo, self, deregister_instance_impl);
224 return ret;
225 }
226
227
228
229
make_new_instance(PyTypeObject * type)230 inline PyObject *make_new_instance(PyTypeObject *type) {
231 #if defined(PYPY_VERSION)
232
233
234 ssize_t instance_size = static_cast<ssize_t>(sizeof(instance));
235 if (type->tp_basicsize < instance_size) {
236 type->tp_basicsize = instance_size;
237 }
238 #endif
239 PyObject *self = type->tp_alloc(type, 0);
240 auto inst = reinterpret_cast<instance *>(self);
241
242 inst->allocate_layout();
243
244 inst->owned = true;
245
246 return self;
247 }
248
249
250
pybind11_object_new(PyTypeObject * type,PyObject *,PyObject *)251 extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) {
252 return make_new_instance(type);
253 }
254
255
256
257
pybind11_object_init(PyObject * self,PyObject *,PyObject *)258 extern "C" inline int pybind11_object_init(PyObject *self, PyObject *, PyObject *) {
259 PyTypeObject *type = Py_TYPE(self);
260 std::string msg;
261 #if defined(PYPY_VERSION)
262 msg += handle((PyObject *) type).attr("__module__").cast<std::string>() + ".";
263 #endif
264 msg += type->tp_name;
265 msg += ": No constructor defined!";
266 PyErr_SetString(PyExc_TypeError, msg.c_str());
267 return -1;
268 }
269
add_patient(PyObject * nurse,PyObject * patient)270 inline void add_patient(PyObject *nurse, PyObject *patient) {
271 auto &internals = get_internals();
272 auto instance = reinterpret_cast<detail::instance *>(nurse);
273 instance->has_patients = true;
274 Py_INCREF(patient);
275 internals.patients[nurse].push_back(patient);
276 }
277
clear_patients(PyObject * self)278 inline void clear_patients(PyObject *self) {
279 auto instance = reinterpret_cast<detail::instance *>(self);
280 auto &internals = get_internals();
281 auto pos = internals.patients.find(self);
282 assert(pos != internals.patients.end());
283
284
285
286 auto patients = std::move(pos->second);
287 internals.patients.erase(pos);
288 instance->has_patients = false;
289 for (PyObject *&patient : patients)
290 Py_CLEAR(patient);
291 }
292
293
294
clear_instance(PyObject * self)295 inline void clear_instance(PyObject *self) {
296 auto instance = reinterpret_cast<detail::instance *>(self);
297
298
299 for (auto &v_h : values_and_holders(instance)) {
300 if (v_h) {
301
302
303
304 if (v_h.instance_registered() && !deregister_instance(instance, v_h.value_ptr(), v_h.type))
305 pybind11_fail("pybind11_object_dealloc(): Tried to deallocate unregistered instance!");
306
307 if (instance->owned || v_h.holder_constructed())
308 v_h.type->dealloc(v_h);
309 }
310 }
311
312 instance->deallocate_layout();
313
314 if (instance->weakrefs)
315 PyObject_ClearWeakRefs(self);
316
317 PyObject **dict_ptr = _PyObject_GetDictPtr(self);
318 if (dict_ptr)
319 Py_CLEAR(*dict_ptr);
320
321 if (instance->has_patients)
322 clear_patients(self);
323 }
324
325
326
pybind11_object_dealloc(PyObject * self)327 extern "C" inline void pybind11_object_dealloc(PyObject *self) {
328 clear_instance(self);
329
330 auto type = Py_TYPE(self);
331 type->tp_free(self);
332
333
334
335
336
337 auto pybind11_object_type = (PyTypeObject *) get_internals().instance_base;
338 if (type->tp_dealloc == pybind11_object_type->tp_dealloc)
339 Py_DECREF(type);
340 }
341
342
make_object_base_type(PyTypeObject * metaclass)343 inline PyObject *make_object_base_type(PyTypeObject *metaclass) {
344 constexpr auto *name = "pybind11_object";
345 auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name));
346
347
348 auto heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);
349 if (!heap_type)
350 pybind11_fail("make_object_base_type(): error allocating type!");
351
352 heap_type->ht_name = name_obj.inc_ref().ptr();
353 #ifdef PYBIND11_BUILTIN_QUALNAME
354 heap_type->ht_qualname = name_obj.inc_ref().ptr();
355 #endif
356
357 auto type = &heap_type->ht_type;
358 type->tp_name = name;
359 type->tp_base = type_incref(&PyBaseObject_Type);
360 type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));
361 type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
362
363 type->tp_new = pybind11_object_new;
364 type->tp_init = pybind11_object_init;
365 type->tp_dealloc = pybind11_object_dealloc;
366
367
368 type->tp_weaklistoffset = offsetof(instance, weakrefs);
369
370 if (PyType_Ready(type) < 0)
371 pybind11_fail("PyType_Ready failed in make_object_base_type():" + error_string());
372
373 setattr((PyObject *) type, "__module__", str("pybind11_builtins"));
374 PYBIND11_SET_OLDPY_QUALNAME(type, name_obj);
375
376 assert(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));
377 return (PyObject *) heap_type;
378 }
379
380
pybind11_get_dict(PyObject * self,void *)381 extern "C" inline PyObject *pybind11_get_dict(PyObject *self, void *) {
382 PyObject *&dict = *_PyObject_GetDictPtr(self);
383 if (!dict)
384 dict = PyDict_New();
385 Py_XINCREF(dict);
386 return dict;
387 }
388
389
pybind11_set_dict(PyObject * self,PyObject * new_dict,void *)390 extern "C" inline int pybind11_set_dict(PyObject *self, PyObject *new_dict, void *) {
391 if (!PyDict_Check(new_dict)) {
392 PyErr_Format(PyExc_TypeError, "__dict__ must be set to a dictionary, not a '%.200s'",
393 Py_TYPE(new_dict)->tp_name);
394 return -1;
395 }
396 PyObject *&dict = *_PyObject_GetDictPtr(self);
397 Py_INCREF(new_dict);
398 Py_CLEAR(dict);
399 dict = new_dict;
400 return 0;
401 }
402
403
pybind11_traverse(PyObject * self,visitproc visit,void * arg)404 extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) {
405 PyObject *&dict = *_PyObject_GetDictPtr(self);
406 Py_VISIT(dict);
407 return 0;
408 }
409
410
pybind11_clear(PyObject * self)411 extern "C" inline int pybind11_clear(PyObject *self) {
412 PyObject *&dict = *_PyObject_GetDictPtr(self);
413 Py_CLEAR(dict);
414 return 0;
415 }
416
417
enable_dynamic_attributes(PyHeapTypeObject * heap_type)418 inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) {
419 auto type = &heap_type->ht_type;
420 #if defined(PYPY_VERSION)
421 pybind11_fail(std::string(type->tp_name) + ": dynamic attributes are "
422 "currently not supported in "
423 "conjunction with PyPy!");
424 #endif
425 type->tp_flags |= Py_TPFLAGS_HAVE_GC;
426 type->tp_dictoffset = type->tp_basicsize;
427 type->tp_basicsize += (ssize_t)sizeof(PyObject *);
428 type->tp_traverse = pybind11_traverse;
429 type->tp_clear = pybind11_clear;
430
431 static PyGetSetDef getset[] = {
432 {const_cast<char*>("__dict__"), pybind11_get_dict, pybind11_set_dict, nullptr, nullptr},
433 {nullptr, nullptr, nullptr, nullptr, nullptr}
434 };
435 type->tp_getset = getset;
436 }
437
438
pybind11_getbuffer(PyObject * obj,Py_buffer * view,int flags)439 extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) {
440
441 type_info *tinfo = nullptr;
442 for (auto type : reinterpret_borrow<tuple>(Py_TYPE(obj)->tp_mro)) {
443 tinfo = get_type_info((PyTypeObject *) type.ptr());
444 if (tinfo && tinfo->get_buffer)
445 break;
446 }
447 if (view == nullptr || obj == nullptr || !tinfo || !tinfo->get_buffer) {
448 if (view)
449 view->obj = nullptr;
450 PyErr_SetString(PyExc_BufferError, "pybind11_getbuffer(): Internal error");
451 return -1;
452 }
453 std::memset(view, 0, sizeof(Py_buffer));
454 buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data);
455 view->obj = obj;
456 view->ndim = 1;
457 view->internal = info;
458 view->buf = info->ptr;
459 view->itemsize = info->itemsize;
460 view->len = view->itemsize;
461 for (auto s : info->shape)
462 view->len *= s;
463 if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
464 view->format = const_cast<char *>(info->format.c_str());
465 if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
466 view->ndim = (int) info->ndim;
467 view->strides = &info->strides[0];
468 view->shape = &info->shape[0];
469 }
470 Py_INCREF(view->obj);
471 return 0;
472 }
473
474
pybind11_releasebuffer(PyObject *,Py_buffer * view)475 extern "C" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) {
476 delete (buffer_info *) view->internal;
477 }
478
479
enable_buffer_protocol(PyHeapTypeObject * heap_type)480 inline void enable_buffer_protocol(PyHeapTypeObject *heap_type) {
481 heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer;
482 #if PY_MAJOR_VERSION < 3
483 heap_type->ht_type.tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
484 #endif
485
486 heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer;
487 heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer;
488 }
489
490
make_new_python_type(const type_record & rec)491 inline PyObject* make_new_python_type(const type_record &rec) {
492 auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING(rec.name));
493
494 auto qualname = name;
495 if (rec.scope && !PyModule_Check(rec.scope.ptr()) && hasattr(rec.scope, "__qualname__")) {
496 #if PY_MAJOR_VERSION >= 3
497 qualname = reinterpret_steal<object>(
498 PyUnicode_FromFormat("%U.%U", rec.scope.attr("__qualname__").ptr(), name.ptr()));
499 #else
500 qualname = str(rec.scope.attr("__qualname__").cast<std::string>() + "." + rec.name);
501 #endif
502 }
503
504 object module;
505 if (rec.scope) {
506 if (hasattr(rec.scope, "__module__"))
507 module = rec.scope.attr("__module__");
508 else if (hasattr(rec.scope, "__name__"))
509 module = rec.scope.attr("__name__");
510 }
511
512 auto full_name = c_str(
513 #if !defined(PYPY_VERSION)
514 module ? str(module).cast<std::string>() + "." + rec.name :
515 #endif
516 rec.name);
517
518 char *tp_doc = nullptr;
519 if (rec.doc && options::show_user_defined_docstrings()) {
520
521 size_t size = strlen(rec.doc) + 1;
522 tp_doc = (char *) PyObject_MALLOC(size);
523 memcpy((void *) tp_doc, rec.doc, size);
524 }
525
526 auto &internals = get_internals();
527 auto bases = tuple(rec.bases);
528 auto base = (bases.size() == 0) ? internals.instance_base
529 : bases[0].ptr();
530
531
532 auto metaclass = rec.metaclass.ptr() ? (PyTypeObject *) rec.metaclass.ptr()
533 : internals.default_metaclass;
534
535 auto heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0);
536 if (!heap_type)
537 pybind11_fail(std::string(rec.name) + ": Unable to create type object!");
538
539 heap_type->ht_name = name.release().ptr();
540 #ifdef PYBIND11_BUILTIN_QUALNAME
541 heap_type->ht_qualname = qualname.inc_ref().ptr();
542 #endif
543
544 auto type = &heap_type->ht_type;
545 type->tp_name = full_name;
546 type->tp_doc = tp_doc;
547 type->tp_base = type_incref((PyTypeObject *)base);
548 type->tp_basicsize = static_cast<ssize_t>(sizeof(instance));
549 if (bases.size() > 0)
550 type->tp_bases = bases.release().ptr();
551
552
553 type->tp_init = pybind11_object_init;
554
555
556 type->tp_as_number = &heap_type->as_number;
557 type->tp_as_sequence = &heap_type->as_sequence;
558 type->tp_as_mapping = &heap_type->as_mapping;
559
560
561 type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
562 #if PY_MAJOR_VERSION < 3
563 type->tp_flags |= Py_TPFLAGS_CHECKTYPES;
564 #endif
565
566 if (rec.dynamic_attr)
567 enable_dynamic_attributes(heap_type);
568
569 if (rec.buffer_protocol)
570 enable_buffer_protocol(heap_type);
571
572 if (PyType_Ready(type) < 0)
573 pybind11_fail(std::string(rec.name) + ": PyType_Ready failed (" + error_string() + ")!");
574
575 assert(rec.dynamic_attr ? PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC)
576 : !PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC));
577
578
579 if (rec.scope)
580 setattr(rec.scope, rec.name, (PyObject *) type);
581 else
582 Py_INCREF(type);
583
584 if (module)
585 setattr((PyObject *) type, "__module__", module);
586
587 PYBIND11_SET_OLDPY_QUALNAME(type, qualname);
588
589 return (PyObject *) type;
590 }
591
592 NAMESPACE_END(detail)
593 NAMESPACE_END(PYBIND11_NAMESPACE)
594