@@ -85,6 +85,34 @@ inline PyTypeObject *make_static_property_type() {
8585
8686#endif // PYPY
8787
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+
88116/* * Types with static properties need to handle `Type.static_prop = x` in a specific way.
89117 By default, Python replaces the `static_property` itself, but for wrapped C++ types
90118 we need to call `static_property.__set__()` in order to propagate the new value to
@@ -135,6 +163,8 @@ inline PyTypeObject* make_default_metaclass() {
135163 type->tp_name = name;
136164 type->tp_base = &PyType_Type;
137165 type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
166+
167+ type->tp_new = pybind11_meta_new;
138168 type->tp_setattro = pybind11_meta_setattro;
139169
140170 if (PyType_Ready (type) < 0 )
@@ -143,5 +173,328 @@ inline PyTypeObject* make_default_metaclass() {
143173 return type;
144174}
145175
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+
146499NAMESPACE_END (detail)
147500NAMESPACE_END(pybind11)
0 commit comments