Extending and Embedding Python, Release 3.9.5 25 2.2. Defining Extension Types: Tutorial This initializes the $_{Custom}$type, filling in a number of members to the appropriate default values, including $_{ob_type}$that we initially set to$_{NULL}$ . The actual definition of$_{PyTypeObject}$in$_{object.h}$has many more fields than the definition above. The re- maining fields will be filled with zeros by the C compiler, and it’s common practice to not specify them explicitly unless you need them. We’re going to pick it apart, one field at a time: PyVarObject_HEAD_INIT(NULL ,0) This line is mandatory boilerplate to initialize the$_{ob_base}$field mentioned above. .tp_name ="custom.Custom ", The name of our type. This will appear in the default textual representation of our objects and in some error messages, for example: Note that the name is a dotted name that includes both the module name and the name of the type within the module. The module in this case is custom and the type is Custom , so we set the type name to custom.Custom . Using the real dotted import path is important to make your type compatible with the pydoc and pickle modules. .tp_basicsize= sizeof (CustomObject), .tp_itemsize=0, This is so that Python knows how much memory to allocate when creating new$_{Custom}$instances.$_{tp_itemsize}$ is only used for variable-sized objects and should otherwise be zero. Note: If you want your type to be subclassable from Python, and your type has the same$_{tp_basicsize}$ as its base type, you may have problems with multiple inheritance. A Python subclass of your type will have to list your type first in its$_{__bases__}$ , or else it will not be able to call your type’s$_{__new__()}$ method without getting an error. You can avoid this problem by ensuring that your type has a larger value for$_{tp_basicsize}$ than its base type does. Most of the time, this will be true anyway, because either your base type will be$_{object}$, or else you will be adding data members to your base type, and therefore increasing its size. We set the class flags to$_{Py_TPFLAGS_DEFAULT}$ . .tp_flags =Py_TPFLAGS_DEFAULT, All types should include this constant in their flags. It enables all of the members defined until at least Python 3.3. If you need further members, you will need to OR the corresponding flags. We provide a doc string for the type in$_{tp_doc}$ . .tp_doc="Custom objects", To enable object creation, we have to provide a tp_new handler. This is the equivalent of the Python method __new__() , but has to be specified explicitly. In this case, we can just use the default implementation provided by the API function$_{PyType_GenericNew()}$ . .tp_new=PyType_GenericNew, Everything else in the file should be familiar, except for some code in$_{PyInit_custom()}$ : if (PyType_Ready( &CustomType)<0) return ; >>> ""+custom.Custom() Traceback (most recent call last): File "<stdin>" , line1, in <module> TypeError: can only concatenate str (not "custom.Custom") to str