@@ -498,6 +498,33 @@ static int nb_type_init(PyObject *self, PyObject *args, PyObject *kwds) {
498498 return 0 ;
499499}
500500
501+ // / metaclass `__call__` function that is used to create all nanobind objects
502+ static PyObject *nb_type_call (PyObject *type, PyObject *args, PyObject *kwargs) {
503+
504+ // use the default metaclass call to create/initialize the object
505+ #if defined(Py_LIMITED_API)
506+ PyObject *self = ((ternaryfunc)PyType_GetSlot (&PyType_Type, Py_tp_call))(type, args, kwargs);
507+ #else
508+ PyObject *self = PyType_Type.tp_call (type, args, kwargs);
509+ #endif
510+ if (self == nullptr ) {
511+ return nullptr ;
512+ }
513+
514+ // This must be a nanobind instance
515+ nb_inst *inst = (nb_inst *) self;
516+ if (inst->state == nb_inst::state_uninitialized) {
517+ const type_data *t = nb_type_data (Py_TYPE (self));
518+ PyErr_Format (PyExc_TypeError,
519+ " %.200s.__init__() must be called when overriding __init__" ,
520+ t->name );
521+ Py_DECREF (self);
522+ return nullptr ;
523+ }
524+
525+ return self;
526+ }
527+
501528// / Special case to handle 'Class.property = value' assignments
502529int nb_type_setattro (PyObject* obj, PyObject* name, PyObject* value) {
503530 nb_internals *int_p = internals;
@@ -861,6 +888,7 @@ static PyTypeObject *nb_type_tp(size_t supplement) noexcept {
861888 { Py_tp_dealloc, (void *) nb_type_dealloc },
862889 { Py_tp_setattro, (void *) nb_type_setattro },
863890 { Py_tp_init, (void *) nb_type_init },
891+ { Py_tp_call, (void *) nb_type_call },
864892#if defined(Py_LIMITED_API)
865893 { Py_tp_members, (void *) members },
866894#endif
0 commit comments