@@ -85,6 +85,34 @@ inline PyTypeObject *make_static_property_type() {
85
85
86
86
#endif // PYPY
87
87
88
+ /* * Inheriting from multiple C++ types in Python is not supported -- set an error instead.
89
+ A Python definition (`class C(A, B): pass`) will call `tp_new` so we check for multiple
90
+ C++ bases here. On the other hand, C++ type definitions (`py::class_<C, A, B>(m, "C")`)
91
+ don't not use `tp_new` and will not trigger this error. */
92
+ extern " C" inline PyObject *pybind11_meta_new (PyTypeObject *metaclass, PyObject *args,
93
+ PyObject *kwargs) {
94
+ PyObject *bases = PyTuple_GetItem (args, 1 ); // arguments: (name, bases, dict)
95
+ if (!bases)
96
+ return nullptr ;
97
+
98
+ auto &internals = get_internals ();
99
+ auto num_cpp_bases = 0 ;
100
+ for (auto base : reinterpret_borrow<tuple>(bases)) {
101
+ auto base_type = (PyTypeObject *) base.ptr ();
102
+ auto instance_size = static_cast <size_t >(base_type->tp_basicsize );
103
+ if (PyObject_IsSubclass (base.ptr (), internals.get_base (instance_size)))
104
+ ++num_cpp_bases;
105
+ }
106
+
107
+ if (num_cpp_bases > 1 ) {
108
+ PyErr_SetString (PyExc_TypeError, " Can't inherit from multiple C++ classes in Python."
109
+ " Use py::class_ to define the class in C++ instead." );
110
+ return nullptr ;
111
+ } else {
112
+ return PyType_Type.tp_new (metaclass, args, kwargs);
113
+ }
114
+ }
115
+
88
116
/* * Types with static properties need to handle `Type.static_prop = x` in a specific way.
89
117
By default, Python replaces the `static_property` itself, but for wrapped C++ types
90
118
we need to call `static_property.__set__()` in order to propagate the new value to
@@ -135,6 +163,8 @@ inline PyTypeObject* make_default_metaclass() {
135
163
type->tp_name = name;
136
164
type->tp_base = &PyType_Type;
137
165
type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
166
+
167
+ type->tp_new = pybind11_meta_new;
138
168
type->tp_setattro = pybind11_meta_setattro;
139
169
140
170
if (PyType_Ready (type) < 0 )
@@ -143,5 +173,328 @@ inline PyTypeObject* make_default_metaclass() {
143
173
return type;
144
174
}
145
175
176
+ // / Instance creation function for all pybind11 types. It only allocates space for the
177
+ // / C++ object, but doesn't call the constructor -- an `__init__` function must do that.
178
+ extern " C" inline PyObject *pybind11_object_new (PyTypeObject *type, PyObject *, PyObject *) {
179
+ PyObject *self = type->tp_alloc (type, 0 );
180
+ auto instance = (instance_essentials<void > *) self;
181
+ auto tinfo = get_type_info (type);
182
+ instance->value = ::operator new (tinfo->type_size );
183
+ instance->owned = true ;
184
+ instance->holder_constructed = false ;
185
+ get_internals ().registered_instances .emplace (instance->value , self);
186
+ return self;
187
+ }
188
+
189
+ // / An `__init__` function constructs the C++ object. Users should provide at least one
190
+ // / of these using `py::init` or directly with `.def(__init__, ...)`. Otherwise, the
191
+ // / following default function will be used which simply throws an exception.
192
+ extern " C" inline int pybind11_object_init (PyObject *self, PyObject *, PyObject *) {
193
+ PyTypeObject *type = Py_TYPE (self);
194
+ std::string msg;
195
+ #if defined(PYPY_VERSION)
196
+ msg += handle ((PyObject *) type).attr (" __module__" ).cast <std::string>() + " ." ;
197
+ #endif
198
+ msg += type->tp_name ;
199
+ msg += " : No constructor defined!" ;
200
+ PyErr_SetString (PyExc_TypeError, msg.c_str ());
201
+ return -1 ;
202
+ }
203
+
204
+ // / Instance destructor function for all pybind11 types. It calls `type_info.dealloc`
205
+ // / to destroy the C++ object itself, while the rest is Python bookkeeping.
206
+ extern " C" inline void pybind11_object_dealloc (PyObject *self) {
207
+ auto instance = (instance_essentials<void > *) self;
208
+ if (instance->value ) {
209
+ auto type = Py_TYPE (self);
210
+ get_type_info (type)->dealloc (self);
211
+
212
+ auto ®istered_instances = get_internals ().registered_instances ;
213
+ auto range = registered_instances.equal_range (instance->value );
214
+ bool found = false ;
215
+ for (auto it = range.first ; it != range.second ; ++it) {
216
+ if (type == Py_TYPE (it->second )) {
217
+ registered_instances.erase (it);
218
+ found = true ;
219
+ break ;
220
+ }
221
+ }
222
+ if (!found)
223
+ pybind11_fail (" pybind11_object_dealloc(): Tried to deallocate unregistered instance!" );
224
+
225
+ if (instance->weakrefs )
226
+ PyObject_ClearWeakRefs (self);
227
+
228
+ PyObject **dict_ptr = _PyObject_GetDictPtr (self);
229
+ if (dict_ptr)
230
+ Py_CLEAR (*dict_ptr);
231
+ }
232
+ Py_TYPE (self)->tp_free (self);
233
+ }
234
+
235
+ /* * Create a type which can be used as a common base for all classes with the same
236
+ instance size, i.e. all classes with the same `sizeof(holder_type)`. This is
237
+ needed in order to satisfy Python's requirements for multiple inheritance.
238
+ Return value: New reference. */
239
+ inline PyObject *make_object_base_type (size_t instance_size) {
240
+ auto name = " pybind11_object_" + std::to_string (instance_size);
241
+ auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING (name.c_str ()));
242
+
243
+ /* Danger zone: from now (and until PyType_Ready), make sure to
244
+ issue no Python C API calls which could potentially invoke the
245
+ garbage collector (the GC will call type_traverse(), which will in
246
+ turn find the newly constructed type in an invalid state) */
247
+ auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc (&PyType_Type, 0 );
248
+ if (!heap_type)
249
+ pybind11_fail (" make_object_base_type(): error allocating type!" );
250
+
251
+ heap_type->ht_name = name_obj.inc_ref ().ptr ();
252
+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
253
+ heap_type->ht_qualname = name_obj.inc_ref ().ptr ();
254
+ #endif
255
+
256
+ auto type = &heap_type->ht_type ;
257
+ type->tp_name = strdup (name.c_str ());
258
+ type->tp_base = &PyBaseObject_Type;
259
+ type->tp_basicsize = static_cast <ssize_t >(instance_size);
260
+ type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
261
+
262
+ type->tp_new = pybind11_object_new;
263
+ type->tp_init = pybind11_object_init;
264
+ type->tp_dealloc = pybind11_object_dealloc;
265
+
266
+ /* Support weak references (needed for the keep_alive feature) */
267
+ type->tp_weaklistoffset = offsetof (instance_essentials<void >, weakrefs);
268
+
269
+ if (PyType_Ready (type) < 0 )
270
+ pybind11_fail (" PyType_Ready failed in make_object_base_type():" + error_string ());
271
+
272
+ assert (!PyType_HasFeature (type, Py_TPFLAGS_HAVE_GC));
273
+ return (PyObject *) heap_type;
274
+ }
275
+
276
+ /* * Return the appropriate base type for the given instance size. The results are cached
277
+ in `internals.bases` so that only a single base is ever created for any size value.
278
+ Return value: Borrowed reference. */
279
+ inline PyObject *internals::get_base (size_t instance_size) {
280
+ auto it = bases.find (instance_size);
281
+ if (it != bases.end ()) {
282
+ return it->second ;
283
+ } else {
284
+ auto base = make_object_base_type (instance_size);
285
+ bases[instance_size] = base;
286
+ return base;
287
+ }
288
+ }
289
+
290
+ // / dynamic_attr: Support for `d = instance.__dict__`.
291
+ extern " C" inline PyObject *pybind11_get_dict (PyObject *self, void *) {
292
+ PyObject *&dict = *_PyObject_GetDictPtr (self);
293
+ if (!dict)
294
+ dict = PyDict_New ();
295
+ Py_XINCREF (dict);
296
+ return dict;
297
+ }
298
+
299
+ // / dynamic_attr: Support for `instance.__dict__ = dict()`.
300
+ extern " C" inline int pybind11_set_dict (PyObject *self, PyObject *new_dict, void *) {
301
+ if (!PyDict_Check (new_dict)) {
302
+ PyErr_Format (PyExc_TypeError, " __dict__ must be set to a dictionary, not a '%.200s'" ,
303
+ Py_TYPE (new_dict)->tp_name );
304
+ return -1 ;
305
+ }
306
+ PyObject *&dict = *_PyObject_GetDictPtr (self);
307
+ Py_INCREF (new_dict);
308
+ Py_CLEAR (dict);
309
+ dict = new_dict;
310
+ return 0 ;
311
+ }
312
+
313
+ // / dynamic_attr: Allow the garbage collector to traverse the internal instance `__dict__`.
314
+ extern " C" inline int pybind11_traverse (PyObject *self, visitproc visit, void *arg) {
315
+ PyObject *&dict = *_PyObject_GetDictPtr (self);
316
+ Py_VISIT (dict);
317
+ return 0 ;
318
+ }
319
+
320
+ // / dynamic_attr: Allow the GC to clear the dictionary.
321
+ extern " C" inline int pybind11_clear (PyObject *self) {
322
+ PyObject *&dict = *_PyObject_GetDictPtr (self);
323
+ Py_CLEAR (dict);
324
+ return 0 ;
325
+ }
326
+
327
+ // / Give instances of this type a `__dict__` and opt into garbage collection.
328
+ inline void enable_dynamic_attributes (PyHeapTypeObject *heap_type) {
329
+ auto type = &heap_type->ht_type ;
330
+ #if defined(PYPY_VERSION)
331
+ pybind11_fail (std::string (type->tp_name ) + " : dynamic attributes are "
332
+ " currently not supported in "
333
+ " conjunction with PyPy!" );
334
+ #endif
335
+ type->tp_flags |= Py_TPFLAGS_HAVE_GC;
336
+ type->tp_dictoffset = type->tp_basicsize ; // place dict at the end
337
+ type->tp_basicsize += sizeof (PyObject *); // and allocate enough space for it
338
+ type->tp_traverse = pybind11_traverse;
339
+ type->tp_clear = pybind11_clear;
340
+
341
+ static PyGetSetDef getset[] = {
342
+ {const_cast <char *>(" __dict__" ), pybind11_get_dict, pybind11_set_dict, nullptr , nullptr },
343
+ {nullptr , nullptr , nullptr , nullptr , nullptr }
344
+ };
345
+ type->tp_getset = getset;
346
+ }
347
+
348
+ // / buffer_protocol: Fill in the view as specified by flags.
349
+ extern " C" inline int pybind11_getbuffer (PyObject *obj, Py_buffer *view, int flags) {
350
+ auto tinfo = get_type_info (Py_TYPE (obj));
351
+ if (view == nullptr || obj == nullptr || !tinfo || !tinfo->get_buffer ) {
352
+ if (view)
353
+ view->obj = nullptr ;
354
+ PyErr_SetString (PyExc_BufferError, " generic_type::getbuffer(): Internal error" );
355
+ return -1 ;
356
+ }
357
+ memset (view, 0 , sizeof (Py_buffer));
358
+ buffer_info *info = tinfo->get_buffer (obj, tinfo->get_buffer_data );
359
+ view->obj = obj;
360
+ view->ndim = 1 ;
361
+ view->internal = info;
362
+ view->buf = info->ptr ;
363
+ view->itemsize = (ssize_t ) info->itemsize ;
364
+ view->len = view->itemsize ;
365
+ for (auto s : info->shape )
366
+ view->len *= s;
367
+ if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
368
+ view->format = const_cast <char *>(info->format .c_str ());
369
+ if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
370
+ view->ndim = (int ) info->ndim ;
371
+ view->strides = (ssize_t *) &info->strides [0 ];
372
+ view->shape = (ssize_t *) &info->shape [0 ];
373
+ }
374
+ Py_INCREF (view->obj );
375
+ return 0 ;
376
+ }
377
+
378
+ // / buffer_protocol: Release the resources of the buffer.
379
+ extern " C" inline void pybind11_releasebuffer (PyObject *, Py_buffer *view) {
380
+ delete (buffer_info *) view->internal ;
381
+ }
382
+
383
+ // / Give this type a buffer interface.
384
+ inline void enable_buffer_protocol (PyHeapTypeObject *heap_type) {
385
+ heap_type->ht_type .tp_as_buffer = &heap_type->as_buffer ;
386
+ #if PY_MAJOR_VERSION < 3
387
+ heap_type->ht_type .tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
388
+ #endif
389
+
390
+ heap_type->as_buffer .bf_getbuffer = pybind11_getbuffer;
391
+ heap_type->as_buffer .bf_releasebuffer = pybind11_releasebuffer;
392
+ }
393
+
394
+ /* * Create a brand new Python type according to the `type_record` specification.
395
+ Return value: New reference. */
396
+ inline PyObject* make_new_python_type (const type_record &rec) {
397
+ auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING (rec.name ));
398
+
399
+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
400
+ auto ht_qualname = name;
401
+ if (rec.scope && hasattr (rec.scope , " __qualname__" )) {
402
+ ht_qualname = reinterpret_steal<object>(
403
+ PyUnicode_FromFormat (" %U.%U" , rec.scope .attr (" __qualname__" ).ptr (), name.ptr ()));
404
+ }
405
+ #endif
406
+
407
+ object module;
408
+ if (rec.scope ) {
409
+ if (hasattr (rec.scope , " __module__" ))
410
+ module = rec.scope .attr (" __module__" );
411
+ else if (hasattr (rec.scope , " __name__" ))
412
+ module = rec.scope .attr (" __name__" );
413
+ }
414
+
415
+ #if !defined(PYPY_VERSION)
416
+ const auto full_name = module ? str (module).cast <std::string>() + " ." + rec.name
417
+ : std::string (rec.name );
418
+ #else
419
+ const auto full_name = std::string (rec.name );
420
+ #endif
421
+
422
+ char *tp_doc = nullptr ;
423
+ if (rec.doc && options::show_user_defined_docstrings ()) {
424
+ /* Allocate memory for docstring (using PyObject_MALLOC, since
425
+ Python will free this later on) */
426
+ size_t size = strlen (rec.doc ) + 1 ;
427
+ tp_doc = (char *) PyObject_MALLOC (size);
428
+ memcpy ((void *) tp_doc, rec.doc , size);
429
+ }
430
+
431
+ auto &internals = get_internals ();
432
+ auto bases = tuple (rec.bases );
433
+ auto base = (bases.size () == 0 ) ? internals.get_base (rec.instance_size )
434
+ : bases[0 ].ptr ();
435
+
436
+ /* Danger zone: from now (and until PyType_Ready), make sure to
437
+ issue no Python C API calls which could potentially invoke the
438
+ garbage collector (the GC will call type_traverse(), which will in
439
+ turn find the newly constructed type in an invalid state) */
440
+ auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc (&PyType_Type, 0 );
441
+ if (!heap_type)
442
+ pybind11_fail (std::string (rec.name ) + " : Unable to create type object!" );
443
+
444
+ heap_type->ht_name = name.release ().ptr ();
445
+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
446
+ heap_type->ht_qualname = ht_qualname.release ().ptr ();
447
+ #endif
448
+
449
+ auto type = &heap_type->ht_type ;
450
+ type->tp_name = strdup (full_name.c_str ());
451
+ type->tp_doc = tp_doc;
452
+ type->tp_base = (PyTypeObject *) handle (base).inc_ref ().ptr ();
453
+ type->tp_basicsize = static_cast <ssize_t >(rec.instance_size );
454
+ if (bases.size () > 0 )
455
+ type->tp_bases = bases.release ().ptr ();
456
+
457
+ /* Don't inherit base __init__ */
458
+ type->tp_init = pybind11_object_init;
459
+
460
+ /* Custom metaclass if requested (used for static properties) */
461
+ if (rec.metaclass ) {
462
+ Py_INCREF (internals.default_metaclass );
463
+ Py_TYPE (type) = (PyTypeObject *) internals.default_metaclass ;
464
+ }
465
+
466
+ /* Supported protocols */
467
+ type->tp_as_number = &heap_type->as_number ;
468
+ type->tp_as_sequence = &heap_type->as_sequence ;
469
+ type->tp_as_mapping = &heap_type->as_mapping ;
470
+
471
+ /* Flags */
472
+ type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
473
+ #if PY_MAJOR_VERSION < 3
474
+ type->tp_flags |= Py_TPFLAGS_CHECKTYPES;
475
+ #endif
476
+
477
+ if (rec.dynamic_attr )
478
+ enable_dynamic_attributes (heap_type);
479
+
480
+ if (rec.buffer_protocol )
481
+ enable_buffer_protocol (heap_type);
482
+
483
+ if (PyType_Ready (type) < 0 )
484
+ pybind11_fail (std::string (rec.name ) + " : PyType_Ready failed (" + error_string () + " )!" );
485
+
486
+ assert (rec.dynamic_attr ? PyType_HasFeature (type, Py_TPFLAGS_HAVE_GC)
487
+ : !PyType_HasFeature (type, Py_TPFLAGS_HAVE_GC));
488
+
489
+ /* Register type with the parent scope */
490
+ if (rec.scope )
491
+ setattr (rec.scope , rec.name , (PyObject *) type);
492
+
493
+ if (module) // Needed by pydoc
494
+ setattr ((PyObject *) type, " __module__" , module);
495
+
496
+ return (PyObject *) type;
497
+ }
498
+
146
499
NAMESPACE_END (detail)
147
500
NAMESPACE_END(pybind11)
0 commit comments