@@ -141,5 +141,303 @@ inline PyTypeObject* make_default_metaclass() {
141141 return type;
142142}
143143
144+ extern " C" inline PyObject *object_new (PyTypeObject *type, PyObject *, PyObject *) {
145+ PyObject *self = type->tp_alloc (type, 0 );
146+ auto instance = (instance_essentials<void > *) self;
147+ auto tinfo = get_type_info (type);
148+ instance->value = ::operator new (tinfo->type_size );
149+ instance->owned = true ;
150+ instance->holder_constructed = false ;
151+ get_internals ().registered_instances .emplace (instance->value , self);
152+ return self;
153+ }
154+
155+ extern " C" inline int object_init (PyObject *self, PyObject *, PyObject *) {
156+ PyTypeObject *type = Py_TYPE (self);
157+ std::string msg;
158+ #if defined(PYPY_VERSION)
159+ msg += handle ((PyObject *) type).attr (" __module__" ).cast <std::string>() + " ." ;
160+ #endif
161+ msg += type->tp_name ;
162+ msg += " : No constructor defined!" ;
163+ PyErr_SetString (PyExc_TypeError, msg.c_str ());
164+ return -1 ;
165+ }
166+
167+ extern " C" inline void object_dealloc (PyObject *self) {
168+ auto instance = (instance_essentials<void > *) self;
169+ if (instance->value ) {
170+ auto type = Py_TYPE (self);
171+ get_type_info (type)->dealloc (self);
172+
173+ auto ®istered_instances = get_internals ().registered_instances ;
174+ auto range = registered_instances.equal_range (instance->value );
175+ bool found = false ;
176+ for (auto it = range.first ; it != range.second ; ++it) {
177+ if (type == Py_TYPE (it->second )) {
178+ registered_instances.erase (it);
179+ found = true ;
180+ break ;
181+ }
182+ }
183+ if (!found)
184+ pybind11_fail (" object_dealloc(): Tried to deallocate unregistered instance!" );
185+
186+ if (instance->weakrefs )
187+ PyObject_ClearWeakRefs (self);
188+
189+ PyObject **dict_ptr = _PyObject_GetDictPtr (self);
190+ if (dict_ptr)
191+ Py_CLEAR (*dict_ptr);
192+ }
193+ Py_TYPE (self)->tp_free (self);
194+ }
195+
196+ extern " C" inline PyObject *object_get_dict (PyObject *self, void *) {
197+ PyObject *&dict = *_PyObject_GetDictPtr (self);
198+ if (!dict)
199+ dict = PyDict_New ();
200+ Py_XINCREF (dict);
201+ return dict;
202+ }
203+
204+ extern " C" inline int object_set_dict (PyObject *self, PyObject *new_dict, void *) {
205+ if (!PyDict_Check (new_dict)) {
206+ PyErr_Format (PyExc_TypeError, " __dict__ must be set to a dictionary, not a '%.200s'" ,
207+ Py_TYPE (new_dict)->tp_name );
208+ return -1 ;
209+ }
210+ PyObject *&dict = *_PyObject_GetDictPtr (self);
211+ Py_INCREF (new_dict);
212+ Py_CLEAR (dict);
213+ dict = new_dict;
214+ return 0 ;
215+ }
216+
217+ static PyGetSetDef object_getset[] = {
218+ {const_cast <char *>(" __dict__" ), object_get_dict, object_set_dict, nullptr , nullptr },
219+ {nullptr , nullptr , nullptr , nullptr , nullptr }
220+ };
221+
222+ extern " C" inline int object_traverse (PyObject *self, visitproc visit, void *arg) {
223+ PyObject *&dict = *_PyObject_GetDictPtr (self);
224+ Py_VISIT (dict);
225+ return 0 ;
226+ }
227+
228+ extern " C" inline int object_clear (PyObject *self) {
229+ PyObject *&dict = *_PyObject_GetDictPtr (self);
230+ Py_CLEAR (dict);
231+ return 0 ;
232+ }
233+
234+ extern " C" inline int object_getbuffer (PyObject *obj, Py_buffer *view, int flags) {
235+ auto tinfo = get_type_info (Py_TYPE (obj));
236+ if (view == nullptr || obj == nullptr || !tinfo || !tinfo->get_buffer ) {
237+ if (view)
238+ view->obj = nullptr ;
239+ PyErr_SetString (PyExc_BufferError, " generic_type::getbuffer(): Internal error" );
240+ return -1 ;
241+ }
242+ memset (view, 0 , sizeof (Py_buffer));
243+ buffer_info *info = tinfo->get_buffer (obj, tinfo->get_buffer_data );
244+ view->obj = obj;
245+ view->ndim = 1 ;
246+ view->internal = info;
247+ view->buf = info->ptr ;
248+ view->itemsize = (ssize_t ) info->itemsize ;
249+ view->len = view->itemsize ;
250+ for (auto s : info->shape )
251+ view->len *= s;
252+ if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
253+ view->format = const_cast <char *>(info->format .c_str ());
254+ if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
255+ view->ndim = (int ) info->ndim ;
256+ view->strides = (ssize_t *) &info->strides [0 ];
257+ view->shape = (ssize_t *) &info->shape [0 ];
258+ }
259+ Py_INCREF (view->obj );
260+ return 0 ;
261+ }
262+
263+ extern " C" inline void object_releasebuffer (PyObject *, Py_buffer *view) {
264+ delete (buffer_info *) view->internal ;
265+ }
266+
267+ /* * Create a type which can be used as a common base for all classes with the same
268+ instance size, i.e. all classes with the same `sizeof(holder_type)`. This is
269+ needed in order to satisfy Python's requirements for multiple inheritance.
270+ Return value: New reference. */
271+ inline PyObject *make_object_base_type (size_t instance_size) {
272+ auto name = " pybind11_object_" + std::to_string (instance_size);
273+ auto name_obj = reinterpret_steal<object>(PYBIND11_FROM_STRING (name.c_str ()));
274+
275+ /* Danger zone: from now (and until PyType_Ready), make sure to
276+ issue no Python C API calls which could potentially invoke the
277+ garbage collector (the GC will call type_traverse(), which will in
278+ turn find the newly constructed type in an invalid state) */
279+ auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc (&PyType_Type, 0 );
280+ if (!heap_type)
281+ pybind11_fail (" make_object_base_type(): error allocating type!" );
282+
283+ heap_type->ht_name = name_obj.inc_ref ().ptr ();
284+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
285+ heap_type->ht_qualname = name_obj.inc_ref ().ptr ();
286+ #endif
287+
288+ auto type = &heap_type->ht_type ;
289+ type->tp_name = strdup (name.c_str ());
290+ type->tp_base = &PyBaseObject_Type;
291+ type->tp_basicsize = static_cast <ssize_t >(instance_size);
292+ type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
293+
294+ type->tp_new = object_new;
295+ type->tp_init = object_init;
296+ type->tp_dealloc = object_dealloc;
297+
298+ /* Support weak references (needed for the keep_alive feature) */
299+ type->tp_weaklistoffset = offsetof (instance_essentials<void >, weakrefs);
300+
301+ if (PyType_Ready (type) < 0 )
302+ pybind11_fail (" PyType_Ready failed in make_object_base_type():" + error_string ());
303+
304+ assert (!PyType_HasFeature (type, Py_TPFLAGS_HAVE_GC));
305+ return (PyObject *) heap_type;
306+ }
307+
308+ /* * Return the appropriate base type for the given instance size. The results are cached
309+ in `internals.bases` so that only a single base is ever created for any size value.
310+ Return value: Borrowed reference. */
311+ inline PyObject *internals::get_base (size_t instance_size) {
312+ auto it = bases.find (instance_size);
313+ if (it != bases.end ()) {
314+ return it->second ;
315+ } else {
316+ auto base = make_object_base_type (instance_size);
317+ bases[instance_size] = base;
318+ return base;
319+ }
320+ }
321+
322+ /* * Create a brand new Python type according to the `type_record` specification.
323+ Return value: New reference. */
324+ inline PyObject* make_new_python_type (const type_record &rec) {
325+ auto name = reinterpret_steal<object>(PYBIND11_FROM_STRING (rec.name ));
326+
327+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
328+ auto ht_qualname = name;
329+ if (rec.scope && hasattr (rec.scope , " __qualname__" )) {
330+ ht_qualname = reinterpret_steal<object>(
331+ PyUnicode_FromFormat (" %U.%U" , rec.scope .attr (" __qualname__" ).ptr (), name.ptr ()));
332+ }
333+ #endif
334+
335+ object module ;
336+ if (rec.scope ) {
337+ if (hasattr (rec.scope , " __module__" ))
338+ module = rec.scope .attr (" __module__" );
339+ else if (hasattr (rec.scope , " __name__" ))
340+ module = rec.scope .attr (" __name__" );
341+ }
342+
343+ #if !defined(PYPY_VERSION)
344+ const auto full_name = module ? str (module ).cast <std::string>() + " ." + rec.name
345+ : std::string (rec.name );
346+ #else
347+ const auto full_name = std::string (rec.name );
348+ #endif
349+
350+ char *tp_doc = nullptr ;
351+ if (rec.doc && options::show_user_defined_docstrings ()) {
352+ /* Allocate memory for docstring (using PyObject_MALLOC, since
353+ Python will free this later on) */
354+ size_t size = strlen (rec.doc ) + 1 ;
355+ tp_doc = (char *) PyObject_MALLOC (size);
356+ memcpy ((void *) tp_doc, rec.doc , size);
357+ }
358+
359+ auto &internals = get_internals ();
360+ auto bases = tuple (rec.bases );
361+ auto base = (bases.size () == 0 ) ? internals.get_base (rec.instance_size )
362+ : bases[0 ].ptr ();
363+
364+ /* Danger zone: from now (and until PyType_Ready), make sure to
365+ issue no Python C API calls which could potentially invoke the
366+ garbage collector (the GC will call type_traverse(), which will in
367+ turn find the newly constructed type in an invalid state) */
368+ auto heap_type = (PyHeapTypeObject *) PyType_Type.tp_alloc (&PyType_Type, 0 );
369+ if (!heap_type)
370+ pybind11_fail (std::string (rec.name ) + " : Unable to create type object!" );
371+
372+ heap_type->ht_name = name.release ().ptr ();
373+ #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
374+ heap_type->ht_qualname = ht_qualname.release ().ptr ();
375+ #endif
376+
377+ auto type = &heap_type->ht_type ;
378+ type->tp_name = strdup (full_name.c_str ());
379+ type->tp_doc = tp_doc;
380+ type->tp_base = (PyTypeObject *) handle (base).inc_ref ().ptr ();
381+ type->tp_basicsize = static_cast <ssize_t >(rec.instance_size );
382+ if (bases.size () > 0 )
383+ type->tp_bases = bases.release ().ptr ();
384+
385+ /* Custom metaclass if requested (used for static properties) */
386+ if (rec.metaclass ) {
387+ Py_INCREF (internals.default_metaclass );
388+ Py_TYPE (type) = (PyTypeObject *) internals.default_metaclass ;
389+ }
390+
391+ /* Supported protocols */
392+ type->tp_as_number = &heap_type->as_number ;
393+ type->tp_as_sequence = &heap_type->as_sequence ;
394+ type->tp_as_mapping = &heap_type->as_mapping ;
395+
396+ /* Flags */
397+ type->tp_flags |= Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HEAPTYPE;
398+ #if PY_MAJOR_VERSION < 3
399+ type->tp_flags |= Py_TPFLAGS_CHECKTYPES;
400+ #endif
401+
402+ /* Support dynamic attributes */
403+ if (rec.dynamic_attr ) {
404+ #if defined(PYPY_VERSION)
405+ pybind11_fail (std::string (rec.name ) + " : dynamic attributes are "
406+ " currently not supported in "
407+ " conjunction with PyPy!" );
408+ #endif
409+ type->tp_dictoffset = type->tp_basicsize ; // place dict at the end
410+ type->tp_basicsize += sizeof (PyObject *); // and allocate enough space for it
411+ type->tp_getset = object_getset;
412+ type->tp_traverse = object_traverse;
413+ type->tp_clear = object_clear;
414+ type->tp_flags |= Py_TPFLAGS_HAVE_GC;
415+ }
416+
417+ if (rec.buffer_protocol ) {
418+ type->tp_as_buffer = &heap_type->as_buffer ;
419+ #if PY_MAJOR_VERSION < 3
420+ type->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER;
421+ #endif
422+ heap_type->as_buffer .bf_getbuffer = object_getbuffer;
423+ heap_type->as_buffer .bf_releasebuffer = object_releasebuffer;
424+ }
425+
426+ if (PyType_Ready (type) < 0 )
427+ pybind11_fail (std::string (rec.name ) + " : PyType_Ready failed (" + error_string () + " )!" );
428+
429+ assert (rec.dynamic_attr ? PyType_HasFeature (type, Py_TPFLAGS_HAVE_GC)
430+ : !PyType_HasFeature (type, Py_TPFLAGS_HAVE_GC));
431+
432+ /* Register type with the parent scope */
433+ if (rec.scope )
434+ setattr (rec.scope , rec.name , (PyObject *) type);
435+
436+ if (module ) // Needed by pydoc
437+ setattr ((PyObject *) type, " __module__" , module );
438+
439+ return (PyObject *) type;
440+ }
441+
144442NAMESPACE_END (detail)
145443NAMESPACE_END(pybind11)
0 commit comments