1 | /* |
2 | pybind11/detail/class.h: Python C API implementation details for py::class_ |
3 | |
4 | Copyright (c) 2017 Wenzel Jakob <[email protected]> |
5 | |
6 | All rights reserved. Use of this source code is governed by a |
7 | BSD-style license that can be found in the LICENSE file. |
8 | */ |
9 | |
10 | #pragma once |
11 | |
12 | #include "../attr.h" |
13 | #include "../options.h" |
14 | |
15 | PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) |
16 | PYBIND11_NAMESPACE_BEGIN(detail) |
17 | |
18 | #if !defined(PYPY_VERSION) |
19 | # define PYBIND11_BUILTIN_QUALNAME |
20 | # define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) |
21 | #else |
22 | // In PyPy, we still set __qualname__ so that we can produce reliable function type |
23 | // signatures; in CPython this macro expands to nothing: |
24 | # define PYBIND11_SET_OLDPY_QUALNAME(obj, nameobj) \ |
25 | setattr((PyObject *) obj, "__qualname__", nameobj) |
26 | #endif |
27 | |
28 | inline std::string get_fully_qualified_tp_name(PyTypeObject *type) { |
29 | #if !defined(PYPY_VERSION) |
30 | return type->tp_name; |
31 | #else |
32 | auto module_name = handle((PyObject *) type).attr("__module__" ).cast<std::string>(); |
33 | if (module_name == PYBIND11_BUILTINS_MODULE) |
34 | return type->tp_name; |
35 | else |
36 | return std::move(module_name) + "." + type->tp_name; |
37 | #endif |
38 | } |
39 | |
40 | inline PyTypeObject *type_incref(PyTypeObject *type) { |
41 | Py_INCREF(type); |
42 | return type; |
43 | } |
44 | |
45 | #if !defined(PYPY_VERSION) |
46 | |
47 | /// `pybind11_static_property.__get__()`: Always pass the class instead of the instance. |
48 | extern "C" inline PyObject *pybind11_static_get(PyObject *self, PyObject * /*ob*/, PyObject *cls) { |
49 | return PyProperty_Type.tp_descr_get(self, cls, cls); |
50 | } |
51 | |
52 | /// `pybind11_static_property.__set__()`: Just like the above `__get__()`. |
53 | extern "C" inline int pybind11_static_set(PyObject *self, PyObject *obj, PyObject *value) { |
54 | PyObject *cls = PyType_Check(obj) ? obj : (PyObject *) Py_TYPE(obj); |
55 | return PyProperty_Type.tp_descr_set(self, cls, value); |
56 | } |
57 | |
58 | // Forward declaration to use in `make_static_property_type()` |
59 | inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type); |
60 | |
61 | /** A `static_property` is the same as a `property` but the `__get__()` and `__set__()` |
62 | methods are modified to always use the object type instead of a concrete instance. |
63 | Return value: New reference. */ |
64 | inline PyTypeObject *make_static_property_type() { |
65 | constexpr auto *name = "pybind11_static_property" ; |
66 | auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name)); |
67 | |
68 | /* Danger zone: from now (and until PyType_Ready), make sure to |
69 | issue no Python C API calls which could potentially invoke the |
70 | garbage collector (the GC will call type_traverse(), which will in |
71 | turn find the newly constructed type in an invalid state) */ |
72 | auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0); |
73 | if (!heap_type) { |
74 | pybind11_fail("make_static_property_type(): error allocating type!" ); |
75 | } |
76 | |
77 | heap_type->ht_name = name_obj.inc_ref().ptr(); |
78 | # ifdef PYBIND11_BUILTIN_QUALNAME |
79 | heap_type->ht_qualname = name_obj.inc_ref().ptr(); |
80 | # endif |
81 | |
82 | auto *type = &heap_type->ht_type; |
83 | type->tp_name = name; |
84 | type->tp_base = type_incref(&PyProperty_Type); |
85 | type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; |
86 | type->tp_descr_get = pybind11_static_get; |
87 | type->tp_descr_set = pybind11_static_set; |
88 | |
89 | if (PyType_Ready(type) < 0) { |
90 | pybind11_fail("make_static_property_type(): failure in PyType_Ready()!" ); |
91 | } |
92 | |
93 | # if PY_VERSION_HEX >= 0x030C0000 |
94 | // PRE 3.12 FEATURE FREEZE. PLEASE REVIEW AFTER FREEZE. |
95 | // Since Python-3.12 property-derived types are required to |
96 | // have dynamic attributes (to set `__doc__`) |
97 | enable_dynamic_attributes(heap_type); |
98 | # endif |
99 | |
100 | setattr((PyObject *) type, "__module__" , str("pybind11_builtins" )); |
101 | PYBIND11_SET_OLDPY_QUALNAME(type, name_obj); |
102 | |
103 | return type; |
104 | } |
105 | |
106 | #else // PYPY |
107 | |
108 | /** PyPy has some issues with the above C API, so we evaluate Python code instead. |
109 | This function will only be called once so performance isn't really a concern. |
110 | Return value: New reference. */ |
111 | inline PyTypeObject *make_static_property_type() { |
112 | auto d = dict(); |
113 | PyObject *result = PyRun_String(R"(\ |
114 | class pybind11_static_property(property): |
115 | def __get__(self, obj, cls): |
116 | return property.__get__(self, cls, cls) |
117 | |
118 | def __set__(self, obj, value): |
119 | cls = obj if isinstance(obj, type) else type(obj) |
120 | property.__set__(self, cls, value) |
121 | )" , |
122 | Py_file_input, |
123 | d.ptr(), |
124 | d.ptr()); |
125 | if (result == nullptr) |
126 | throw error_already_set(); |
127 | Py_DECREF(result); |
128 | return (PyTypeObject *) d["pybind11_static_property" ].cast<object>().release().ptr(); |
129 | } |
130 | |
131 | #endif // PYPY |
132 | |
133 | /** Types with static properties need to handle `Type.static_prop = x` in a specific way. |
134 | By default, Python replaces the `static_property` itself, but for wrapped C++ types |
135 | we need to call `static_property.__set__()` in order to propagate the new value to |
136 | the underlying C++ data structure. */ |
137 | extern "C" inline int pybind11_meta_setattro(PyObject *obj, PyObject *name, PyObject *value) { |
138 | // Use `_PyType_Lookup()` instead of `PyObject_GetAttr()` in order to get the raw |
139 | // descriptor (`property`) instead of calling `tp_descr_get` (`property.__get__()`). |
140 | PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name); |
141 | |
142 | // The following assignment combinations are possible: |
143 | // 1. `Type.static_prop = value` --> descr_set: `Type.static_prop.__set__(value)` |
144 | // 2. `Type.static_prop = other_static_prop` --> setattro: replace existing `static_prop` |
145 | // 3. `Type.regular_attribute = value` --> setattro: regular attribute assignment |
146 | auto *const static_prop = (PyObject *) get_internals().static_property_type; |
147 | const auto call_descr_set = (descr != nullptr) && (value != nullptr) |
148 | && (PyObject_IsInstance(descr, static_prop) != 0) |
149 | && (PyObject_IsInstance(value, static_prop) == 0); |
150 | if (call_descr_set) { |
151 | // Call `static_property.__set__()` instead of replacing the `static_property`. |
152 | #if !defined(PYPY_VERSION) |
153 | return Py_TYPE(descr)->tp_descr_set(descr, obj, value); |
154 | #else |
155 | if (PyObject *result = PyObject_CallMethod(descr, "__set__" , "OO" , obj, value)) { |
156 | Py_DECREF(result); |
157 | return 0; |
158 | } else { |
159 | return -1; |
160 | } |
161 | #endif |
162 | } else { |
163 | // Replace existing attribute. |
164 | return PyType_Type.tp_setattro(obj, name, value); |
165 | } |
166 | } |
167 | |
168 | /** |
169 | * Python 3's PyInstanceMethod_Type hides itself via its tp_descr_get, which prevents aliasing |
170 | * methods via cls.attr("m2") = cls.attr("m1"): instead the tp_descr_get returns a plain function, |
171 | * when called on a class, or a PyMethod, when called on an instance. Override that behaviour here |
172 | * to do a special case bypass for PyInstanceMethod_Types. |
173 | */ |
174 | extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name) { |
175 | PyObject *descr = _PyType_Lookup((PyTypeObject *) obj, name); |
176 | if (descr && PyInstanceMethod_Check(descr)) { |
177 | Py_INCREF(descr); |
178 | return descr; |
179 | } |
180 | return PyType_Type.tp_getattro(obj, name); |
181 | } |
182 | |
183 | /// metaclass `__call__` function that is used to create all pybind11 objects. |
184 | extern "C" inline PyObject *pybind11_meta_call(PyObject *type, PyObject *args, PyObject *kwargs) { |
185 | |
186 | // use the default metaclass call to create/initialize the object |
187 | PyObject *self = PyType_Type.tp_call(type, args, kwargs); |
188 | if (self == nullptr) { |
189 | return nullptr; |
190 | } |
191 | |
192 | // This must be a pybind11 instance |
193 | auto *instance = reinterpret_cast<detail::instance *>(self); |
194 | |
195 | // Ensure that the base __init__ function(s) were called |
196 | for (const auto &vh : values_and_holders(instance)) { |
197 | if (!vh.holder_constructed()) { |
198 | PyErr_Format(PyExc_TypeError, |
199 | "%.200s.__init__() must be called when overriding __init__" , |
200 | get_fully_qualified_tp_name(vh.type->type).c_str()); |
201 | Py_DECREF(self); |
202 | return nullptr; |
203 | } |
204 | } |
205 | |
206 | return self; |
207 | } |
208 | |
209 | /// Cleanup the type-info for a pybind11-registered type. |
210 | extern "C" inline void pybind11_meta_dealloc(PyObject *obj) { |
211 | auto *type = (PyTypeObject *) obj; |
212 | auto &internals = get_internals(); |
213 | |
214 | // A pybind11-registered type will: |
215 | // 1) be found in internals.registered_types_py |
216 | // 2) have exactly one associated `detail::type_info` |
217 | auto found_type = internals.registered_types_py.find(type); |
218 | if (found_type != internals.registered_types_py.end() && found_type->second.size() == 1 |
219 | && found_type->second[0]->type == type) { |
220 | |
221 | auto *tinfo = found_type->second[0]; |
222 | auto tindex = std::type_index(*tinfo->cpptype); |
223 | internals.direct_conversions.erase(tindex); |
224 | |
225 | if (tinfo->module_local) { |
226 | get_local_internals().registered_types_cpp.erase(tindex); |
227 | } else { |
228 | internals.registered_types_cpp.erase(tindex); |
229 | } |
230 | internals.registered_types_py.erase(tinfo->type); |
231 | |
232 | // Actually just `std::erase_if`, but that's only available in C++20 |
233 | auto &cache = internals.inactive_override_cache; |
234 | for (auto it = cache.begin(), last = cache.end(); it != last;) { |
235 | if (it->first == (PyObject *) tinfo->type) { |
236 | it = cache.erase(it); |
237 | } else { |
238 | ++it; |
239 | } |
240 | } |
241 | |
242 | delete tinfo; |
243 | } |
244 | |
245 | PyType_Type.tp_dealloc(obj); |
246 | } |
247 | |
248 | /** This metaclass is assigned by default to all pybind11 types and is required in order |
249 | for static properties to function correctly. Users may override this using `py::metaclass`. |
250 | Return value: New reference. */ |
251 | inline PyTypeObject *make_default_metaclass() { |
252 | constexpr auto *name = "pybind11_type" ; |
253 | auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name)); |
254 | |
255 | /* Danger zone: from now (and until PyType_Ready), make sure to |
256 | issue no Python C API calls which could potentially invoke the |
257 | garbage collector (the GC will call type_traverse(), which will in |
258 | turn find the newly constructed type in an invalid state) */ |
259 | auto *heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc(&PyType_Type, 0); |
260 | if (!heap_type) { |
261 | pybind11_fail("make_default_metaclass(): error allocating metaclass!" ); |
262 | } |
263 | |
264 | heap_type->ht_name = name_obj.inc_ref().ptr(); |
265 | #ifdef PYBIND11_BUILTIN_QUALNAME |
266 | heap_type->ht_qualname = name_obj.inc_ref().ptr(); |
267 | #endif |
268 | |
269 | auto *type = &heap_type->ht_type; |
270 | type->tp_name = name; |
271 | type->tp_base = type_incref(&PyType_Type); |
272 | type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; |
273 | |
274 | type->tp_call = pybind11_meta_call; |
275 | |
276 | type->tp_setattro = pybind11_meta_setattro; |
277 | type->tp_getattro = pybind11_meta_getattro; |
278 | |
279 | type->tp_dealloc = pybind11_meta_dealloc; |
280 | |
281 | if (PyType_Ready(type) < 0) { |
282 | pybind11_fail("make_default_metaclass(): failure in PyType_Ready()!" ); |
283 | } |
284 | |
285 | setattr((PyObject *) type, "__module__" , str("pybind11_builtins" )); |
286 | PYBIND11_SET_OLDPY_QUALNAME(type, name_obj); |
287 | |
288 | return type; |
289 | } |
290 | |
291 | /// For multiple inheritance types we need to recursively register/deregister base pointers for any |
292 | /// base classes with pointers that are difference from the instance value pointer so that we can |
293 | /// correctly recognize an offset base class pointer. This calls a function with any offset base |
294 | /// ptrs. |
295 | inline void traverse_offset_bases(void *valueptr, |
296 | const detail::type_info *tinfo, |
297 | instance *self, |
298 | bool (*f)(void * /*parentptr*/, instance * /*self*/)) { |
299 | for (handle h : reinterpret_borrow<tuple>(tinfo->type->tp_bases)) { |
300 | if (auto *parent_tinfo = get_type_info((PyTypeObject *) h.ptr())) { |
301 | for (auto &c : parent_tinfo->implicit_casts) { |
302 | if (c.first == tinfo->cpptype) { |
303 | auto *parentptr = c.second(valueptr); |
304 | if (parentptr != valueptr) { |
305 | f(parentptr, self); |
306 | } |
307 | traverse_offset_bases(parentptr, parent_tinfo, self, f); |
308 | break; |
309 | } |
310 | } |
311 | } |
312 | } |
313 | } |
314 | |
315 | inline bool register_instance_impl(void *ptr, instance *self) { |
316 | get_internals().registered_instances.emplace(ptr, self); |
317 | return true; // unused, but gives the same signature as the deregister func |
318 | } |
319 | inline bool deregister_instance_impl(void *ptr, instance *self) { |
320 | auto ®istered_instances = get_internals().registered_instances; |
321 | auto range = registered_instances.equal_range(ptr); |
322 | for (auto it = range.first; it != range.second; ++it) { |
323 | if (self == it->second) { |
324 | registered_instances.erase(it); |
325 | return true; |
326 | } |
327 | } |
328 | return false; |
329 | } |
330 | |
331 | inline void register_instance(instance *self, void *valptr, const type_info *tinfo) { |
332 | register_instance_impl(valptr, self); |
333 | if (!tinfo->simple_ancestors) { |
334 | traverse_offset_bases(valptr, tinfo, self, register_instance_impl); |
335 | } |
336 | } |
337 | |
338 | inline bool deregister_instance(instance *self, void *valptr, const type_info *tinfo) { |
339 | bool ret = deregister_instance_impl(valptr, self); |
340 | if (!tinfo->simple_ancestors) { |
341 | traverse_offset_bases(valptr, tinfo, self, deregister_instance_impl); |
342 | } |
343 | return ret; |
344 | } |
345 | |
346 | /// Instance creation function for all pybind11 types. It allocates the internal instance layout |
347 | /// for holding C++ objects and holders. Allocation is done lazily (the first time the instance is |
348 | /// cast to a reference or pointer), and initialization is done by an `__init__` function. |
349 | inline PyObject *make_new_instance(PyTypeObject *type) { |
350 | #if defined(PYPY_VERSION) |
351 | // PyPy gets tp_basicsize wrong (issue 2482) under multiple inheritance when the first |
352 | // inherited object is a plain Python type (i.e. not derived from an extension type). Fix it. |
353 | ssize_t instance_size = static_cast<ssize_t>(sizeof(instance)); |
354 | if (type->tp_basicsize < instance_size) { |
355 | type->tp_basicsize = instance_size; |
356 | } |
357 | #endif |
358 | PyObject *self = type->tp_alloc(type, 0); |
359 | auto *inst = reinterpret_cast<instance *>(self); |
360 | // Allocate the value/holder internals: |
361 | inst->allocate_layout(); |
362 | |
363 | return self; |
364 | } |
365 | |
366 | /// Instance creation function for all pybind11 types. It only allocates space for the |
367 | /// C++ object, but doesn't call the constructor -- an `__init__` function must do that. |
368 | extern "C" inline PyObject *pybind11_object_new(PyTypeObject *type, PyObject *, PyObject *) { |
369 | return make_new_instance(type); |
370 | } |
371 | |
372 | /// An `__init__` function constructs the C++ object. Users should provide at least one |
373 | /// of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the |
374 | /// following default function will be used which simply throws an exception. |
375 | extern "C" inline int pybind11_object_init(PyObject *self, PyObject *, PyObject *) { |
376 | PyTypeObject *type = Py_TYPE(self); |
377 | std::string msg = get_fully_qualified_tp_name(type) + ": No constructor defined!" ; |
378 | PyErr_SetString(PyExc_TypeError, msg.c_str()); |
379 | return -1; |
380 | } |
381 | |
382 | inline void add_patient(PyObject *nurse, PyObject *patient) { |
383 | auto &internals = get_internals(); |
384 | auto *instance = reinterpret_cast<detail::instance *>(nurse); |
385 | instance->has_patients = true; |
386 | Py_INCREF(patient); |
387 | internals.patients[nurse].push_back(patient); |
388 | } |
389 | |
390 | inline void clear_patients(PyObject *self) { |
391 | auto *instance = reinterpret_cast<detail::instance *>(self); |
392 | auto &internals = get_internals(); |
393 | auto pos = internals.patients.find(self); |
394 | assert(pos != internals.patients.end()); |
395 | // Clearing the patients can cause more Python code to run, which |
396 | // can invalidate the iterator. Extract the vector of patients |
397 | // from the unordered_map first. |
398 | auto patients = std::move(pos->second); |
399 | internals.patients.erase(pos); |
400 | instance->has_patients = false; |
401 | for (PyObject *&patient : patients) { |
402 | Py_CLEAR(patient); |
403 | } |
404 | } |
405 | |
406 | /// Clears all internal data from the instance and removes it from registered instances in |
407 | /// preparation for deallocation. |
408 | inline void clear_instance(PyObject *self) { |
409 | auto *instance = reinterpret_cast<detail::instance *>(self); |
410 | |
411 | // Deallocate any values/holders, if present: |
412 | for (auto &v_h : values_and_holders(instance)) { |
413 | if (v_h) { |
414 | |
415 | // We have to deregister before we call dealloc because, for virtual MI types, we still |
416 | // need to be able to get the parent pointers. |
417 | if (v_h.instance_registered() |
418 | && !deregister_instance(instance, v_h.value_ptr(), v_h.type)) { |
419 | pybind11_fail( |
420 | "pybind11_object_dealloc(): Tried to deallocate unregistered instance!" ); |
421 | } |
422 | |
423 | if (instance->owned || v_h.holder_constructed()) { |
424 | v_h.type->dealloc(v_h); |
425 | } |
426 | } |
427 | } |
428 | // Deallocate the value/holder layout internals: |
429 | instance->deallocate_layout(); |
430 | |
431 | if (instance->weakrefs) { |
432 | PyObject_ClearWeakRefs(self); |
433 | } |
434 | |
435 | PyObject **dict_ptr = _PyObject_GetDictPtr(self); |
436 | if (dict_ptr) { |
437 | Py_CLEAR(*dict_ptr); |
438 | } |
439 | |
440 | if (instance->has_patients) { |
441 | clear_patients(self); |
442 | } |
443 | } |
444 | |
445 | /// Instance destructor function for all pybind11 types. It calls `type_info.dealloc` |
446 | /// to destroy the C++ object itself, while the rest is Python bookkeeping. |
447 | extern "C" inline void pybind11_object_dealloc(PyObject *self) { |
448 | clear_instance(self); |
449 | |
450 | auto *type = Py_TYPE(self); |
451 | type->tp_free(self); |
452 | |
453 | #if PY_VERSION_HEX < 0x03080000 |
454 | // `type->tp_dealloc != pybind11_object_dealloc` means that we're being called |
455 | // as part of a derived type's dealloc, in which case we're not allowed to decref |
456 | // the type here. For cross-module compatibility, we shouldn't compare directly |
457 | // with `pybind11_object_dealloc`, but with the common one stashed in internals. |
458 | auto pybind11_object_type = (PyTypeObject *) get_internals().instance_base; |
459 | if (type->tp_dealloc == pybind11_object_type->tp_dealloc) |
460 | Py_DECREF(type); |
461 | #else |
462 | // This was not needed before Python 3.8 (Python issue 35810) |
463 | // https://github.com/pybind/pybind11/issues/1946 |
464 | Py_DECREF(type); |
465 | #endif |
466 | } |
467 | |
468 | std::string error_string(); |
469 | |
470 | /** Create the type which can be used as a common base for all classes. This is |
471 | needed in order to satisfy Python's requirements for multiple inheritance. |
472 | Return value: New reference. */ |
473 | inline PyObject *make_object_base_type(PyTypeObject *metaclass) { |
474 | constexpr auto *name = "pybind11_object" ; |
475 | auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING(name)); |
476 | |
477 | /* Danger zone: from now (and until PyType_Ready), make sure to |
478 | issue no Python C API calls which could potentially invoke the |
479 | garbage collector (the GC will call type_traverse(), which will in |
480 | turn find the newly constructed type in an invalid state) */ |
481 | auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0); |
482 | if (!heap_type) { |
483 | pybind11_fail("make_object_base_type(): error allocating type!" ); |
484 | } |
485 | |
486 | heap_type->ht_name = name_obj.inc_ref().ptr(); |
487 | #ifdef PYBIND11_BUILTIN_QUALNAME |
488 | heap_type->ht_qualname = name_obj.inc_ref().ptr(); |
489 | #endif |
490 | |
491 | auto *type = &heap_type->ht_type; |
492 | type->tp_name = name; |
493 | type->tp_base = type_incref(&PyBaseObject_Type); |
494 | type->tp_basicsize = static_cast<ssize_t>(sizeof(instance)); |
495 | type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE; |
496 | |
497 | type->tp_new = pybind11_object_new; |
498 | type->tp_init = pybind11_object_init; |
499 | type->tp_dealloc = pybind11_object_dealloc; |
500 | |
501 | /* Support weak references (needed for the keep_alive feature) */ |
502 | type->tp_weaklistoffset = offsetof(instance, weakrefs); |
503 | |
504 | if (PyType_Ready(type) < 0) { |
505 | pybind11_fail("PyType_Ready failed in make_object_base_type(): " + error_string()); |
506 | } |
507 | |
508 | setattr((PyObject *) type, "__module__" , str("pybind11_builtins" )); |
509 | PYBIND11_SET_OLDPY_QUALNAME(type, name_obj); |
510 | |
511 | assert(!PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC)); |
512 | return (PyObject *) heap_type; |
513 | } |
514 | |
515 | /// dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`. |
516 | extern "C" inline int pybind11_traverse(PyObject *self, visitproc visit, void *arg) { |
517 | PyObject *&dict = *_PyObject_GetDictPtr(self); |
518 | Py_VISIT(dict); |
519 | // https://docs.python.org/3/c-api/typeobj.html#c.PyTypeObject.tp_traverse |
520 | #if PY_VERSION_HEX >= 0x03090000 |
521 | Py_VISIT(Py_TYPE(self)); |
522 | #endif |
523 | return 0; |
524 | } |
525 | |
526 | /// dynamic_attr: Allow the GC to clear the dictionary. |
527 | extern "C" inline int pybind11_clear(PyObject *self) { |
528 | PyObject *&dict = *_PyObject_GetDictPtr(self); |
529 | Py_CLEAR(dict); |
530 | return 0; |
531 | } |
532 | |
533 | /// Give instances of this type a `__dict__` and opt into garbage collection. |
534 | inline void enable_dynamic_attributes(PyHeapTypeObject *heap_type) { |
535 | auto *type = &heap_type->ht_type; |
536 | type->tp_flags |= Py_TPFLAGS_HAVE_GC; |
537 | #if PY_VERSION_HEX < 0x030B0000 |
538 | type->tp_dictoffset = type->tp_basicsize; // place dict at the end |
539 | type->tp_basicsize += (ssize_t) sizeof(PyObject *); // and allocate enough space for it |
540 | #else |
541 | type->tp_flags |= Py_TPFLAGS_MANAGED_DICT; |
542 | #endif |
543 | type->tp_traverse = pybind11_traverse; |
544 | type->tp_clear = pybind11_clear; |
545 | |
546 | static PyGetSetDef getset[] = {{ |
547 | #if PY_VERSION_HEX < 0x03070000 |
548 | const_cast<char *>("__dict__" ), |
549 | #else |
550 | "__dict__" , |
551 | #endif |
552 | PyObject_GenericGetDict, |
553 | PyObject_GenericSetDict, |
554 | nullptr, |
555 | nullptr}, |
556 | {nullptr, nullptr, nullptr, nullptr, nullptr}}; |
557 | type->tp_getset = getset; |
558 | } |
559 | |
560 | /// buffer_protocol: Fill in the view as specified by flags. |
561 | extern "C" inline int pybind11_getbuffer(PyObject *obj, Py_buffer *view, int flags) { |
562 | // Look for a `get_buffer` implementation in this type's info or any bases (following MRO). |
563 | type_info *tinfo = nullptr; |
564 | for (auto type : reinterpret_borrow<tuple>(Py_TYPE(obj)->tp_mro)) { |
565 | tinfo = get_type_info((PyTypeObject *) type.ptr()); |
566 | if (tinfo && tinfo->get_buffer) { |
567 | break; |
568 | } |
569 | } |
570 | if (view == nullptr || !tinfo || !tinfo->get_buffer) { |
571 | if (view) { |
572 | view->obj = nullptr; |
573 | } |
574 | PyErr_SetString(PyExc_BufferError, "pybind11_getbuffer(): Internal error" ); |
575 | return -1; |
576 | } |
577 | std::memset(view, 0, sizeof(Py_buffer)); |
578 | buffer_info *info = tinfo->get_buffer(obj, tinfo->get_buffer_data); |
579 | if ((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE && info->readonly) { |
580 | delete info; |
581 | // view->obj = nullptr; // Was just memset to 0, so not necessary |
582 | PyErr_SetString(PyExc_BufferError, "Writable buffer requested for readonly storage" ); |
583 | return -1; |
584 | } |
585 | view->obj = obj; |
586 | view->ndim = 1; |
587 | view->internal = info; |
588 | view->buf = info->ptr; |
589 | view->itemsize = info->itemsize; |
590 | view->len = view->itemsize; |
591 | for (auto s : info->shape) { |
592 | view->len *= s; |
593 | } |
594 | view->readonly = static_cast<int>(info->readonly); |
595 | if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT) { |
596 | view->format = const_cast<char *>(info->format.c_str()); |
597 | } |
598 | if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) { |
599 | view->ndim = (int) info->ndim; |
600 | view->strides = info->strides.data(); |
601 | view->shape = info->shape.data(); |
602 | } |
603 | Py_INCREF(view->obj); |
604 | return 0; |
605 | } |
606 | |
607 | /// buffer_protocol: Release the resources of the buffer. |
608 | extern "C" inline void pybind11_releasebuffer(PyObject *, Py_buffer *view) { |
609 | delete (buffer_info *) view->internal; |
610 | } |
611 | |
612 | /// Give this type a buffer interface. |
613 | inline void enable_buffer_protocol(PyHeapTypeObject *heap_type) { |
614 | heap_type->ht_type.tp_as_buffer = &heap_type->as_buffer; |
615 | |
616 | heap_type->as_buffer.bf_getbuffer = pybind11_getbuffer; |
617 | heap_type->as_buffer.bf_releasebuffer = pybind11_releasebuffer; |
618 | } |
619 | |
620 | /** Create a brand new Python type according to the `type_record` specification. |
621 | Return value: New reference. */ |
622 | inline PyObject *make_new_python_type(const type_record &rec) { |
623 | auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING(rec.name)); |
624 | |
625 | auto qualname = name; |
626 | if (rec.scope && !PyModule_Check(rec.scope.ptr()) && hasattr(rec.scope, "__qualname__" )) { |
627 | qualname = reinterpret_steal<object>( |
628 | PyUnicode_FromFormat("%U.%U" , rec.scope.attr("__qualname__" ).ptr(), name.ptr())); |
629 | } |
630 | |
631 | object module_; |
632 | if (rec.scope) { |
633 | if (hasattr(rec.scope, "__module__" )) { |
634 | module_ = rec.scope.attr("__module__" ); |
635 | } else if (hasattr(rec.scope, "__name__" )) { |
636 | module_ = rec.scope.attr("__name__" ); |
637 | } |
638 | } |
639 | |
640 | const auto *full_name = c_str( |
641 | #if !defined(PYPY_VERSION) |
642 | module_ ? str(module_).cast<std::string>() + "." + rec.name : |
643 | #endif |
644 | rec.name); |
645 | |
646 | char *tp_doc = nullptr; |
647 | if (rec.doc && options::show_user_defined_docstrings()) { |
648 | /* Allocate memory for docstring (using PyObject_MALLOC, since |
649 | Python will free this later on) */ |
650 | size_t size = std::strlen(rec.doc) + 1; |
651 | tp_doc = (char *) PyObject_MALLOC(size); |
652 | std::memcpy((void *) tp_doc, rec.doc, size); |
653 | } |
654 | |
655 | auto &internals = get_internals(); |
656 | auto bases = tuple(rec.bases); |
657 | auto *base = (bases.empty()) ? internals.instance_base : bases[0].ptr(); |
658 | |
659 | /* Danger zone: from now (and until PyType_Ready), make sure to |
660 | issue no Python C API calls which could potentially invoke the |
661 | garbage collector (the GC will call type_traverse(), which will in |
662 | turn find the newly constructed type in an invalid state) */ |
663 | auto *metaclass |
664 | = rec.metaclass.ptr() ? (PyTypeObject *) rec.metaclass.ptr() : internals.default_metaclass; |
665 | |
666 | auto *heap_type = (PyHeapTypeObject *) metaclass->tp_alloc(metaclass, 0); |
667 | if (!heap_type) { |
668 | pybind11_fail(std::string(rec.name) + ": Unable to create type object!" ); |
669 | } |
670 | |
671 | heap_type->ht_name = name.release().ptr(); |
672 | #ifdef PYBIND11_BUILTIN_QUALNAME |
673 | heap_type->ht_qualname = qualname.inc_ref().ptr(); |
674 | #endif |
675 | |
676 | auto *type = &heap_type->ht_type; |
677 | type->tp_name = full_name; |
678 | type->tp_doc = tp_doc; |
679 | type->tp_base = type_incref((PyTypeObject *) base); |
680 | type->tp_basicsize = static_cast<ssize_t>(sizeof(instance)); |
681 | if (!bases.empty()) { |
682 | type->tp_bases = bases.release().ptr(); |
683 | } |
684 | |
685 | /* Don't inherit base __init__ */ |
686 | type->tp_init = pybind11_object_init; |
687 | |
688 | /* Supported protocols */ |
689 | type->tp_as_number = &heap_type->as_number; |
690 | type->tp_as_sequence = &heap_type->as_sequence; |
691 | type->tp_as_mapping = &heap_type->as_mapping; |
692 | type->tp_as_async = &heap_type->as_async; |
693 | |
694 | /* Flags */ |
695 | type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HEAPTYPE; |
696 | if (!rec.is_final) { |
697 | type->tp_flags |= Py_TPFLAGS_BASETYPE; |
698 | } |
699 | |
700 | if (rec.dynamic_attr) { |
701 | enable_dynamic_attributes(heap_type); |
702 | } |
703 | |
704 | if (rec.buffer_protocol) { |
705 | enable_buffer_protocol(heap_type); |
706 | } |
707 | |
708 | if (rec.custom_type_setup_callback) { |
709 | rec.custom_type_setup_callback(heap_type); |
710 | } |
711 | |
712 | if (PyType_Ready(type) < 0) { |
713 | pybind11_fail(std::string(rec.name) + ": PyType_Ready failed: " + error_string()); |
714 | } |
715 | |
716 | assert(!rec.dynamic_attr || PyType_HasFeature(type, Py_TPFLAGS_HAVE_GC)); |
717 | |
718 | /* Register type with the parent scope */ |
719 | if (rec.scope) { |
720 | setattr(rec.scope, rec.name, (PyObject *) type); |
721 | } else { |
722 | Py_INCREF(type); // Keep it alive forever (reference leak) |
723 | } |
724 | |
725 | if (module_) { // Needed by pydoc |
726 | setattr((PyObject *) type, "__module__" , module_); |
727 | } |
728 | |
729 | PYBIND11_SET_OLDPY_QUALNAME(type, qualname); |
730 | |
731 | return (PyObject *) type; |
732 | } |
733 | |
734 | PYBIND11_NAMESPACE_END(detail) |
735 | PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) |
736 | |