Python Slots Performance

Posted on  by admin
Python Slots Performance 9,9/10 5310 votes
  1. Python Slots Performance Tool
  2. Monty Python Slot Machine App
17 Nov 2013 by Ben

This situation likely won’t change anytime soon due to the challenge of accommodating subtypes without damaging performance or functionality. PyTypeObject, the Base Type Struct ¶ The PyTypeObject, exposed in Python as type, is the cornerstone of the type system implementation in CPython. Similarly, Even Attack Wave also a periodic +6 bonus to Attack. However, this buff can be bestowed by a teammate instead, freeing up Python’s C slot skill for whatever his team may require. If Python is deployed exclusively alongside Cavalry heroes, Hone Cavalry is a great choice for a cheap but effective skill. I'm a Software Engineer located in Russia. My current technical interests are Machine learning, NLP, web security, Python, information extraction, network protocols, and software internals.

We’ve mentioned before how Oyster.com’s Python-based web servers cache huge amounts of static content in huge Python dicts (hash tables). Well, we recently saved over 2 GB in each of four 6 GB server processes with a single line of code — using __slots__ on our Image class.

Here’s a screenshot of RAM usage before and after deploying this change on one of our servers:

Relative performance also often depends on your experience with the two languages. Use xrange instead of range. This section no longer applies if you're using Python 3, where range now provides an iterator over ranges of arbitrary size, and where xrange no longer exists. Python has two ways to get a range of numbers: range and xrange. Hello Python Forum, as a learning experience I created a very basic 'Slot' machine. It's far from perfect and could definitely use many upgrades, more winning options, pay tables, etc. As for this project I was mostly focusing on functionality, and I may continue working on it from time to time to make it better (more interesting to play).

We allocate about a million instances of a class like the following:

By default Python uses a dict to store an object’s instance attributes. Which is usually fine, and it allows fully dynamic things like setting arbitrary new attributes at runtime.

However, for small classes that have a few fixed attributes known at “compile time”, the dict is a waste of RAM, and this makes a real difference when you’re creating a million of them. You can tell Python not to use a dict, and only allocate space for a fixed set of attributes, by settings __slots__ on the class to a fixed list of attribute names:

Note that you can also use collections.namedtuple, which allows attribute access, but only takes the space of a tuple, so it’s similar to using __slots__ on a class. However, to me it always feels weird to inherit from a namedtuple class. Also, if you want a custom initializer you have to override __new__ rather than __init__.

Warning: Don’t prematurely optimize and use this everywhere! It’s not great for code maintenance, and it really only saves you when you have thousands of instances.

Please enable JavaScript to view the comments powered by Disqus.

CPython includes a powerful C-API by which you can heavily customizePython. This includes creating custom types. Though you can create newtypes directly in Python now, this wasn’t always the case. Python has astrong heritage of tapping into C to produce new types. One consequenceis that creating new Python types in C affords you more functionalitythan you’ll find in pure Python.

In this reference page we’ll be looking at the details surroundingPyTypeObject, which is the linchpin of Python types written in C.

The CPython C-API¶

One important thing to note is that CPython’s C-API provides a number ofinterfaces for efficiently interacting with Python objects in C. Thosefunctions fall into one of two groups:

  • the abstract object API (e.g. PyObject_*)
  • the concrete object API (e.g. PyDict_*)

The concrete APIs take advantage of the implementation details of theirrespective types to get improved efficiency and functionality. However,this comes at the cost of ignoring implementations in subtypes. The dictconcrete API is a prime example of this, as it make direct calls tostatic methods in the implementation, skipping a lookup of the relevantimplementation on the type. This situation likely won’t change anytimesoon due to the challenge of accommodating subtypes without damagingperformance or functionality.

PyTypeObject, the Base Type Struct¶

The PyTypeObject, exposed in Python as type, is the cornerstone of thetype system implementation in CPython.

Note: A “dynamic” type is one created through the class statement inPython (i.e. by calling type(), or some other metaclass).

Creating a Python Type in C¶

Defining a Python type in C involves populating the fields of aPyTypeObject struct with the values you care about. We call each ofthose fields a “slot”.

One the definition is ready, we pass it into the PyType_Ready()function, which does a number of things, inclulding exposing most of thetype definition to Python’s attribute lookup mechanism.

PyTypeObject Slots¶

If a slot is not required it can be set to NULL.

Here is a table of the slots described in the docs [2]. Itdoes not include the slots provided by PyObject_VAR_HEAD, etc., northose added onto the end for the COUNT_ALLOCS macro.

Legend:* A slot name in parentheses means is is reserved or deprecated.* The “Req” column indicates that the slot is required.* The “Inh” column indicates that the slot is inherited by subclasses.* The “Rdy” column indicates that the slot is populated by PyType_Ready().* The “Mem” column indicates that the slot is memory-management-related.* For each of these columns, “X” indicates an affirmative.* For “Req”, “T” means it may be ignored for types that never be deallocated (a rare case).* For “Rdy”, “U”means it’s used by PyType_Ready().

PyTypeObject SlotReqRdyMemDescription
tp_nameXThe class’s name, possiblyfully qualified.
tp_basicsizeXXBase memory size of instances.
tp_itemsizeXPer-item size, if any.
tp_deallocTXInstance memory deallocator.
(tp_print)Special stringification forwriting to real files.
(tp_getattr)tp_getattro using strings.
(tp_setattr)tp_setattro using strings.
(tp_reserved)(Was tp_compare.)
tp_reprUser-friendly representation.
tp_as_numberUSee PyNumberMethods.
tp_as_sequenceUSee PySequenceMethods.
tp_as_mappingUSee PyMappingMethods.
tp_hashGet the hash of an instance.
tp_call“Run” an instance.
tp_strStringify an instance.
tp_getattroGet an attribute’s value.
tp_setattroSet an attribute’s value orremove the attribute.
tp_as_bufferUSee PyBufferProcs.
tp_flagsXA bit mask of various flags.
tp_docThe class’s docstring.
tp_traverseXGC helper for detecting cycles.
tp_clearXGC helper for breaking cycles.
tp_richcompareSame as the old __cmp__().
tp_weaklistoffsetUOffset into instance structfor a list of weak refs.
tp_iterGet an iterator for an instance.
tp_iternextIterate an instance.
tp_methodsURegular methods of the type.
tp_membersURegular data attributes.
tp_getsetUThe same as properties.
tp_baseUThe base type for inheritance.
tp_dictXThe class’s dict, if any.
tp_descr_get__get__ for the class.
tp_descr_set__set__ & __del__ for the class.
tp_dictoffsetUOffset into instance struct forinstance namespace.
tp_initInitialize an instance.
tp_allocXGet memory block for an instance.
tp_newReturn a new instance.
tp_freeXRelease memory block for an obj.
tp_is_gcXFor when Py_TPFLAGS_HAVE_GCisn’t good enough.
tp_basesXTuple of bases classes.(dynamic type only)
tp_mroXCalculated MRO tuple.
tp_cacheX(Not used.)
tp_subclassesXList of weak refs to subclasses.
tp_weaklistXList of weak refs to the type.
tp_delDeletion-time instance handling.
Python slots performance upgrades

Note: None of the slots populated by PyType_Ready() should be set whendefining a type, except for tp_flags.

Note: various flag bits in tp_flags may cause certain slots to beignored.

Note: tp_print is effectively deprecated, so don’t use it.

Note: PyType_Ready() will build the new type with consideration forthe various inherited slots. Thus, it effectively makes use of thoseslots.

Inheritance¶

Python types written in C still enjoy inheritance, but it’s a littledifferent than in Python. For one thing, only single-inheritance issupported at the C level. For another, at the C level PyTypeReadyfacilitates a form of inheritance-by-copy. This is where inheritedvalues are actually copied into the subclass.

Attribute lookup works the same either way, however. This means thatvalues which PyType_Ready did not copy into the subclass are stillavailable as long as they are exposed vi the base class’s __dict__.

Here’s a look at how inheritance-by-copy works for the variousPyTypeObject slots:

Legend:* The “Inh” column is more complicated:

  • The “Grp” column indicates inheritance dependencies:

PyTypeObject SlotInhGrpNotes
tp_name
tp_basicsizeX
tp_itemsizeX
tp_deallocX
(tp_print)X
(tp_getattr)X1
(tp_setattr)X2
(tp_reserved)
tp_reprX
tp_as_number
tp_as_sequence
tp_as_mapping
tp_hashX3
tp_callX
tp_strX
tp_getattroX1
tp_setattroX2
tp_as_buffer
tp_flags?4
tp_doc
tp_traverseX4
tp_clearX4
tp_richcompareX3
tp_weaklistoffsetX
tp_iterX
tp_iternextX
tp_methodsavailable through attr lookup
tp_membersavailable through attr lookup
tp_getsetavailable through attr lookup
tp_base
tp_dictavailable through attr lookup
tp_descr_getX
tp_descr_setX
tp_dictoffsetX
tp_initX
tp_alloc?static types only
tp_new?not static subtypes with the default tp_base
tp_free?static types only
tp_is_gcX
tp_bases
tp_mro
tp_cache
tp_subclasses
tp_weaklist
tp_delx

Note: Group 4 depends on the Py_TPFLAGS_HAVE_GC flag bit in tp_flags.

Defaults¶

A number of the PyTypeObject slots have default values, either byinheritance or by explicit setting (PyType_Ready). Here is a breakdownof what slots have defaults, where they come from, and what those valuesare:

PyTypeObject SlotDefault SourceValue
tp_name
tp_basicsizePyBaseObject_Type.tp_basicsizesizeof(PyObject)
tp_itemsize
tp_deallocPyBaseObject_Type.tp_deallocobject_dealloc
(tp_print)
(tp_getattr)
(tp_setattr)
(tp_reserved)
tp_reprPyBaseObject_Type.tp_reprobject_repr
tp_as_number
tp_as_sequence
tp_as_mapping
tp_hashPyBaseObject_Type.tp_hash_Py_HashPointer
tp_call
tp_strPyBaseObject_Type.tp_strobject_str
tp_getattroPyBaseObject_Type.tp_getattroPyObj_GenericGetAttr
tp_setattroPyBaseObject_Type.tp_setattroPyObj_GenericSetAttr
tp_as_buffer
tp_flagsPyBaseObject_Type.tp_flagsPy_TPFLAGS_DEFAULTPy_TPFLAGS_BASETYPE
tp_doc
tp_traverse
tp_clear
tp_richcomparePyBaseObject_Type.tp_richcompareobject_richcompare
tp_weaklistoffset
tp_iter
tp_iternext
tp_methods
tp_members
tp_getset
tp_basecall to PyType_ReadyPyBaseObject_Type
tp_dict
tp_descr_get
tp_descr_set
tp_dictoffset
tp_initPyBaseObject_Type.tp_initobject_init
tp_alloc(st) PyBaseObject_Type.tp_alloc(dyn) call to type.__new__PyType_GenericAllocPyType_GenericAlloc
tp_newPyBaseObject_Type.tp_newobject_new
tp_free(st) PyBaseObject_Type.tp_free(dyn) call to type.__new__PyObject_Del<compatible f>
tp_is_gc
tp_bases
tp_mro
tp_cache
tp_subclasses
tp_weaklist
tp_del

PyTypeObject Slot Types¶

Naturally each slot has a type. Some of the slots have a normal int/long/pointer type. However, most of them have function pointers. Eachof these function “types” (e.g. reprfunc) is actually a macro for aparticular function pointer cast.

Consequently, each function you set in your type definition must be castusing that macro:

For each of those slots the following table indicates the function’sparameters and return type. For non-function slots, just the slot’stype is populated and “—” is found in the parameters column.

For functions that return a PyObject *, it’s always a new reference.For functions that store a value (like tp_getattr), the value is never“borrowed”.

Note: visitproc is a function that takes PyObject * and returns int.

PyTypeObject SlotTypeParameter TypesReturn Type
tp_namechar *
tp_basicsizeint
tp_itemsizeint
tp_deallocdestructor<localobject> *void
tp_printprintfuncPyObject *FILE *intint
(tp_getattr)getattrfuncPyObject *const char *PyObject *
(tp_setattr)setattrfuncPyObject *const char *PyObject *int
(tp_reserved)void*
tp_reprreprfuncPyObject *PyObject *
tp_as_numberPyNumberMethods *
tp_as_sequencePySequenceMethods *
tp_as_mappingPyMappingMethods *
tp_hashhashfuncPyObject *Py_hash_t
tp_callternaryfuncPyObject *PyObject *PyObject *PyObject *
tp_strreprfuncPyObject *PyObject *
tp_getattrogetattrofuncPyObject *PyObject *PyObject *
tp_setattrosetattrofuncPyObject *PyObject *PyObject *int
tp_as_bufferPyBufferProcs *
tp_flagslong
tp_docchar *
tp_traversetraverseproc<localobject> *“visitproc”void *int
tp_clearinquiry<localobject> *int
tp_richcomparerichcmpfuncPyObject *PyObject *intPyObject *
tp_weaklistoffsetlong
tp_itergetiterfuncPyObject *PyObject *
tp_iternextiternextfuncPyObject *PyObject *
tp_methodsPyMethodDef[]
tp_membersPyMemberDef[]
tp_getsetPyGetSetDef[]
tp_basePyTypeObject *
tp_dictPyObject *
tp_descr_getdescrgetfuncPyObject *PyObject *PyObject *PyObject *
tp_descr_setdescrsetfuncPyObject *PyObject *PyObject *int
tp_dictoffsetlong
tp_initinitprocPyObject *PyObject *PyObject *int
tp_allocallocfuncPyTypeObject *Py_ssize_tPyObject *
tp_newnewfuncPyTypeObject *PyObject *PyObject *PyObject *
tp_freefreefuncvoid *void
tp_is_gcinquiryvoid *int
tp_basesPyObject *
tp_mroPyObject *
tp_cachePyObject *
tp_subclassesPyObject *
tp_weaklistPyObject *
tp_deldestructorPyObject *int

Helper functions/macros:

  • sizeof() - use to calculate tp_basicsize
  • PyDoc_STRVAR - preps a string for tp_doc

Specialized Slot Types¶

Some of the PyTypeObject slots are themselves structs. This way themain struct doesn’t have to get bigger than it already is. Also,types that don’t need the extra slots don’t need to take up as muchmemory.

PyNumberMethods SlotTypeParameter TypesReturn Type
nb_addbinaryfuncPyObject *PyObject *PyObject *
nb_subtractbinaryfuncPyObject *PyObject *PyObject *
nb_multiplybinaryfuncPyObject *PyObject *PyObject *
nb_remainderbinaryfuncPyObject *PyObject *PyObject *
nb_divmodbinaryfuncPyObject *PyObject *PyObject *
nb_powerternaryfuncPyObject *PyObject *PyObject *PyObject *
nb_negativeunaryfuncPyObject *PyObject *
nb_positiveunaryfuncPyObject *PyObject *
nb_absoluteunaryfuncPyObject *PyObject *
nb_boolinquiryPyObject *int
nb_invertunaryfuncPyObject *PyObject *
nb_lshiftbinaryfuncPyObject *PyObject *PyObject *
nb_rshiftbinaryfuncPyObject *PyObject *PyObject *
nb_andbinaryfuncPyObject *PyObject *PyObject *
nb_xorbinaryfuncPyObject *PyObject *PyObject *
nb_orbinaryfuncPyObject *PyObject *PyObject *
nb_intunaryfuncPyObject *PyObject *
nb_reservedvoid *
nb_floatunaryfuncPyObject *PyObject *
nb_inplace_addbinaryfuncPyObject *PyObject *PyObject *
nb_inplace_subtractbinaryfuncPyObject *PyObject *PyObject *
nb_inplace_multiplybinaryfuncPyObject *PyObject *PyObject *
nb_inplace_remainderbinaryfuncPyObject *PyObject *PyObject *
nb_inplace_powerternaryfuncPyObject *PyObject *PyObject *PyObject *
nb_inplace_lshiftbinaryfuncPyObject *PyObject *PyObject *
nb_inplace_rshiftbinaryfuncPyObject *PyObject *PyObject *
nb_inplace_andbinaryfuncPyObject *PyObject *PyObject *
nb_inplace_xorbinaryfuncPyObject *PyObject *PyObject *
nb_inplace_orbinaryfuncPyObject *PyObject *PyObject *
nb_floor_dividebinaryfuncPyObject *PyObject *PyObject *
nb_true_dividebinaryfuncPyObject *PyObject *PyObject *
nb_inplace_floor_divide binaryfunc
PyObject *PyObject *PyObject *
nb_inplace_true_divide binaryfunc
PyObject *PyObject *PyObject *
nb_indexunaryfuncPyObject *PyObject *
PySequenceMethods SlotTypeParameter TypesReturn Type
sq_lengthlenfuncPyObject *Py_ssize_t
sq_concatbinaryfuncPyObject *PyObject *PyObject *
sq_repeatssizeargfuncPyObject *Py_ssize_tPyObject *
sq_itemssizeargfuncPyObject *Py_ssize_tPyObject *
sq_ass_itemssizeobjargprocPyObject *Py_ssize_tint
sq_containsobjobjprocPyObject *PyObject *int
sq_inplace_concatbinaryfuncPyObject *PyObject *PyObject *
sq_inplace_repeatssizeargfuncPyObject *Py_ssize_tPyObject *
PyMappingMethods SlotTypeParameter TypesReturn Type
mp_lengthlenfuncPyObject *Py_ssize_t
mp_subscriptbinaryfuncPyObject *PyObject *PyObject *
mp_ass_subscriptobjobjargprocPyObject *PyObject *PyObject *int
PyBufferProcs SlotTypeParameter TypesReturn Type
bf_get_buffergetbufferprocPyObject *PyBuffer *intint
bf_release_bufferreleasebufferprocPyObject *PyBuffer *void

PyTypeObject and Special Methods¶

Python’s flavor of operator overloading is achieved through “specialmethods”, a.k.a dunder methods, a.k.a magic methods [1].They provide a simple and straightforward mechanism without getting inthe way when you don’t need them. Likely you’re already familiar with afew of them: __init__(), __new__(), __str__(), and __repr__().

The CPython C-API, particularly PyTypeObject [2], providesa likewise (relatively) straightforward mechanism. Here we areexploring how the special methods relate to the Python types defined in C.

PyType_Ready() populates each type’s __dict__ with a wrappers aroundthe various type slots. Not all of them are available on instances ofthe type.

One thing to note is that when __slots__ or __weakref__ are defined fora type, special handling happens for the time which impacts memory use.The creation/use of __dict__ is also impacted. It’s worth taking alittle time to understand, though that’s outside the scope of thisreference page.

Here’s a break-down of the slots that are exposed via Python attributes.Also, this table shows likewise exposed attributes that don’t actuallycorrespond to type slots.

Legend:* The “Obj” column indicates if the method is available on instances.* The “Rdy” column indicates that the value is exposed by PyType_Ready().* A slot name in parentheses means is is reserved or deprecated.

PyTypeObject SlotSpecial MethodObjRdyNotes
tp_name__name__PyType_Type.tp_getset
tp_basicsize__basicsize__PyType_Type.tp_members
tp_itemsize__itemsize__PyType_Type.tp_members
tp_dealloc
tp_print
(tp_getattr)__getattribute____getattr__XX
(tp_setattr)__setattr____delattr__XX
(tp_reserved)
tp_repr__repr__XX
tp_as_number(see below)X
tp_as_sequence(see below)X
tp_as_mapping(see below)X
tp_hash__hash__XX
tp_call__call__XX
tp_str__str__XX
tp_getattro__getattribute____getattr__XX
tp_setattro__setattr____delattr__XX
tp_as_buffer(see below)
tp_flags__flags__PyType_Type.tp_members
tp_doc__doc__XPyType_Type.tp_getset
tp_traverse
tp_clear
tp_richcompare__eq____ne____lt____gt____le____ge__XX
tp_weaklistoffset__weakrefoffset__PyType_Type.tp_members
tp_iter__iter__XX
tp_iternext__next__XX
tp_methods(__dict__)X
tp_members(__dict__)X
tp_getset(__dict__)X
tp_base__base__PyType_Type.tp_members
tp_dict__dict__PyType_Type.tp_getset
tp_descr_get__get__XX
tp_descr_set__set____delete__XX
tp_dictoffset__dictoffset__PyType_Type.tp_members
tp_init__init__XX
tp_alloc
tp_new__new__XX
tp_free
tp_is_gc
tp_bases__bases__PyType_Type.tp_getset
tp_mro__mro__PyType_Type.tp_members
tp_cache
tp_subclasses__subclasses__PyType_Type.tp_methods
tp_weaklist__weakref__Xdynamic types or manual
tp_del__del__XX
__qualname__PyType_Type.tp_getset
__module__PyType_Type.tp_getset
__abstractmethods__PyType_Type.tp_getset
mroPyType_Type.tp_methods
__prepare__PyType_Type.tp_methods
__instancecheck__PyType_Type.tp_methods
__subclasscheck__PyType_Type.tp_methods
__dir__PyType_Type.tp_methods
__sizeof__PyType_Type.tp_methods
PyNumberMethods SlotSpecial MethodUsage
nb_add__add____radd__
nb_subtract__sub____rsub__
nb_multiply__mul____rmul__
nb_remainder__mod____rmod__
nb_divmod__divmod____rdivmod__
nb_power__pow____rpow__
nb_negative__neg__
nb_positive__pos__
nb_absolute__abs__
nb_bool__bool__
nb_invert__invert__
nb_lshift__lshift____rlshift__
nb_rshift__rshift____rrshift__
nb_and__and____rand__
nb_xor__xor____rxor__
nb_or__or____ror__
nb_int__int__
nb_reserved
nb_float__float__
nb_inplace_add__iadd__
nb_inplace_subtract__isub__
nb_inplace_multiply__imul__
nb_inplace_remainder__imod__
nb_inplace_power__ipow__
nb_inplace_lshift__ilshift__
nb_inplace_rshift__irshift__
nb_inplace_and__iand__
nb_inplace_xor__ixor__
nb_inplace_or__ior__
nb_floor_divide__floordiv____rfloordiv__
nb_true_divide__truediv____rtruediv__
nb_inplace_floor_divide__ifloordiv__
nb_inplace_true_divide__itruediv__
nb_index__index__
PySequenceMethods SlotSpecial MethodNotes
sq_length__len__
sq_concat__add__
sq_repeat__mul____rmul__
sq_item__getitem__
sq_ass_item__setitem____delitem__
sq_contains__contains__
sq_inplace_concat__iadd__
sq_inplace_repeat__imul__
PyMappingMethods SlotSpecial MethodNotes
mp_length__len__
mp_subscript__getitem__
mp_ass_subscript__setitem____getitem__
PyBufferProcs SlotSpecial MethodNotes
bf_get_buffer
bf_release_buffer

How They Get Used by the Interpreter¶

The usage of tp_print falls back to str(obj).

PyTypeObject SlotSpecial MethodUsage
tp_name__name__
tp_basicsize__basicsize__
tp_itemsize__itemsize__
tp_dealloc
tp_print
(tp_getattr)__getattribute____getattr__
(tp_setattr)__setattr____delattr__
(tp_reserved)
tp_repr__repr__
tp_as_number(see below)
tp_as_sequence(see below)
tp_as_mapping(see below)
tp_hash__hash__
tp_call__call__
tp_str__str__
tp_getattro__getattribute____getattr__
tp_setattro__setattr____delattr__
tp_as_buffer(see below)
tp_flags__flags__
tp_doc__doc__
tp_traverse
tp_clear
tp_richcompare__eq____ne____lt____gt____le____ge__
tp_weaklistoffset__weakrefoffset__
tp_iter__iter__
tp_iternext__next__
tp_methods(__dict__)
tp_members(__dict__)
tp_getset(__dict__)
tp_base__base__
tp_dict__dict__
tp_descr_get__get__
tp_descr_set__set____delete__
tp_dictoffset__dictoffset__
tp_init__init__
tp_alloc
tp_new__new__
tp_free
tp_is_gc
tp_bases__bases__
tp_mro__mro__
tp_cache
tp_subclasses__subclasses__
tp_weaklist__weakref__
tp_del__del__
__qualname__
__module__
__abstractmethods__
mro
__prepare__
__instancecheck__
__subclasscheck__
__dir__
__sizeof__
PyNumberMethods SlotSpecial MethodUsage
nb_add__add____radd__
nb_subtract__sub____rsub__
nb_multiply__mul____rmul__
nb_remainder__mod____rmod__
nb_divmod__divmod____rdivmod__
nb_power__pow____rpow__
nb_negative__neg__
nb_positive__pos__
nb_absolute__abs__
nb_bool__bool__
nb_invert__invert__
nb_lshift__lshift____rlshift__
nb_rshift__rshift____rrshift__
nb_and__and____rand__
nb_xor__xor____rxor__
nb_or__or____ror__
nb_int__int__
nb_reserved
nb_float__float__
nb_inplace_add__iadd__
nb_inplace_subtract__isub__
nb_inplace_multiply__imul__
nb_inplace_remainder__imod__
nb_inplace_power__ipow__
nb_inplace_lshift__ilshift__
nb_inplace_rshift__irshift__
nb_inplace_and__iand__
nb_inplace_xor__ixor__
nb_inplace_or__ior__
nb_floor_divide__floordiv____rfloordiv__
nb_true_divide__truediv____rtruediv__
nb_inplace_floor_divide__ifloordiv__
nb_inplace_true_divide__itruediv__
nb_index__index__
PySequenceMethods SlotSpecial MethodUsage
sq_length__len__
sq_concat__add__
sq_repeat__mul____rmul__
sq_item__getitem__
sq_ass_item__setitem____delitem__
sq_contains__contains__
sq_inplace_concat__iadd__
sq_inplace_repeat__imul__
PyMappingMethods SlotSpecial MethodUsage
mp_length__len__
mp_subscript__getitem__
mp_ass_subscript__setitem____getitem__
PyBufferProcs SlotSpecial MethodUsage
bf_get_buffer
bf_release_buffer

How They Get Used by Built-in Functions¶

PyTypeObject SlotSpecial MethodUsage
tp_name__name__
tp_basicsize__basicsize__
tp_itemsize__itemsize__
tp_dealloc
tp_print
(tp_getattr)__getattribute____getattr__
(tp_setattr)__setattr____delattr__
(tp_reserved)
tp_repr__repr__
tp_as_number(see below)
tp_as_sequence(see below)
tp_as_mapping(see below)
tp_hash__hash__
tp_call__call__
tp_str__str__
tp_getattro__getattribute____getattr__
tp_setattro__setattr____delattr__
tp_as_buffer(see below)
tp_flags__flags__
tp_doc__doc__
tp_traverse
tp_clear
tp_richcompare__eq____ne____lt____gt____le____ge__
tp_weaklistoffset__weakrefoffset__
tp_iter__iter__
tp_iternext__next__
tp_methods(__dict__)
tp_members(__dict__)
tp_getset(__dict__)
tp_base__base__
tp_dict__dict__
tp_descr_get__get__
tp_descr_set__set____delete__
tp_dictoffset__dictoffset__
tp_init__init__
tp_alloc
tp_new__new__
tp_free
tp_is_gc
tp_bases__bases__
tp_mro__mro__
tp_cache
tp_subclasses__subclasses__
tp_weaklist__weakref__
tp_del__del__
__qualname__
__module__
__abstractmethods__
mro
__prepare__
__instancecheck__
__subclasscheck__
__dir__
__sizeof__
PyNumberMethods SlotSpecial MethodUsage
nb_add__add____radd__
nb_subtract__sub____rsub__
nb_multiply__mul____rmul__
nb_remainder__mod____rmod__
nb_divmod__divmod____rdivmod__
nb_power__pow____rpow__
nb_negative__neg__
nb_positive__pos__
nb_absolute__abs__
nb_bool__bool__
nb_invert__invert__
nb_lshift__lshift____rlshift__
nb_rshift__rshift____rrshift__
nb_and__and____rand__
nb_xor__xor____rxor__
nb_or__or____ror__
nb_int__int__
nb_reserved
nb_float__float__
nb_inplace_add__iadd__
nb_inplace_subtract__isub__
nb_inplace_multiply__imul__
nb_inplace_remainder__imod__
nb_inplace_power__ipow__
nb_inplace_lshift__ilshift__
nb_inplace_rshift__irshift__
nb_inplace_and__iand__
nb_inplace_xor__ixor__
nb_inplace_or__ior__
nb_floor_divide__floordiv____rfloordiv__
nb_true_divide__truediv____rtruediv__
nb_inplace_floor_divide__ifloordiv__
nb_inplace_true_divide__itruediv__
nb_index__index__
PySequenceMethods SlotSpecial MethodUsage
sq_length__len__
sq_concat__add__
sq_repeat__mul____rmul__
sq_item__getitem__
sq_ass_item__setitem____delitem__
sq_contains__contains__
sq_inplace_concat__iadd__
sq_inplace_repeat__imul__
PyMappingMethods SlotSpecial MethodUsage
mp_length__len__
mp_subscript__getitem__
mp_ass_subscript__setitem____getitem__
PyBufferProcs SlotSpecial MethodUsage
bf_get_buffer
bf_release_buffer
Monty python slots

How They Get Used by the C-API¶

PyTypeObject SlotSpecial MethodUsage
tp_name__name__
tp_basicsize__basicsize__
tp_itemsize__itemsize__
tp_dealloc
tp_print
(tp_getattr)__getattribute____getattr__
(tp_setattr)__setattr____delattr__
(tp_reserved)
tp_repr__repr__
tp_as_number(see below)
tp_as_sequence(see below)
tp_as_mapping(see below)
tp_hash__hash__
tp_call__call__
tp_str__str__
tp_getattro__getattribute____getattr__
tp_setattro__setattr____delattr__
tp_as_buffer(see below)
tp_flags__flags__
tp_doc__doc__
tp_traverse
tp_clear
tp_richcompare__eq____ne____lt____gt____le____ge__
tp_weaklistoffset__weakrefoffset__
tp_iter__iter__
tp_iternext__next__
tp_methods(__dict__)
tp_members(__dict__)
tp_getset(__dict__)
tp_base__base__
tp_dict__dict__
tp_descr_get__get__
tp_descr_set__set____delete__
tp_dictoffset__dictoffset__
tp_init__init__
tp_alloc
tp_new__new__
tp_free
tp_is_gc
tp_bases__bases__
tp_mro__mro__
tp_cache
tp_subclasses__subclasses__
tp_weaklist__weakref__
tp_del__del__
__qualname__
__module__
__abstractmethods__
mro
__prepare__
__instancecheck__
__subclasscheck__
__dir__
__sizeof__
PyNumberMethods SlotSpecial MethodUsage
nb_add__add____radd__
nb_subtract__sub____rsub__
nb_multiply__mul____rmul__
nb_remainder__mod____rmod__
nb_divmod__divmod____rdivmod__
nb_power__pow____rpow__
nb_negative__neg__
nb_positive__pos__
nb_absolute__abs__
nb_bool__bool__
nb_invert__invert__
nb_lshift__lshift____rlshift__
nb_rshift__rshift____rrshift__
nb_and__and____rand__
nb_xor__xor____rxor__
nb_or__or____ror__
nb_int__int__
nb_reserved
nb_float__float__
nb_inplace_add__iadd__
nb_inplace_subtract__isub__
nb_inplace_multiply__imul__
nb_inplace_remainder__imod__
nb_inplace_power__ipow__
nb_inplace_lshift__ilshift__
nb_inplace_rshift__irshift__
nb_inplace_and__iand__
nb_inplace_xor__ixor__
nb_inplace_or__ior__
nb_floor_divide__floordiv____rfloordiv__
nb_true_divide__truediv____rtruediv__
nb_inplace_floor_divide__ifloordiv__
nb_inplace_true_divide__itruediv__
nb_index__index__

Python Slots Performance Tool

PySequenceMethods SlotSpecial MethodUsage
sq_length__len__
sq_concat__add__
sq_repeat__mul____rmul__
sq_item__getitem__
sq_ass_item__setitem____delitem__
sq_contains__contains__
sq_inplace_concat__iadd__
sq_inplace_repeat__imul__
PyMappingMethods SlotSpecial MethodUsage
mp_length__len__
mp_subscript__getitem__
mp_ass_subscript__setitem____getitem__
PyBufferProcs SlotSpecial MethodUsage
bf_get_buffer
bf_release_buffer

Footnotes

[1]See http://docs.python.org/3.4/reference/datamodel.html#special-method-names.
[2](1, 2) See http://docs.python.org/3.4/c-api/typeobj.html.

Monty Python Slot Machine App

To Do¶

XXX fill out the “How They Get Used” sectionsXXX explain heap typesXXX explicitly outline what PyType_Ready() does