Core interpreter types

C indicates whether the type is currently counted totally.
G indicates whether the type co-operates with the GC.
P indicates whether the type is pure, i.e. does not allocate raw memory. This does not include variable-size objects such as tuple and long.
S indicates whether the type is simple and pure, i.e. holds no references to other objects and does not allocate raw memory.

Pure types which co-operate with the GC can be counted accurately by GCObject.
Impure types will need their own code to work out their size.
Types which don't co-operate with the GC will need their own code to work out what objects they refer to.

There are things like PyMethodDef* which could partly be counted, but they're not Python objects and blindly including them in the size of anything which used them would overestimate their size, because it would be as if a different copy of each was included in each object.

Perhaps for those we could have virtual objects which had their own wrapper but weren't really first class Python objects. I'm not sure if it's worth the trouble, though.

The counting code for some objects is quite fragile - it makes a lot of assumptions about the representation of the object. This is noted here. All the Pyrex and C code is fragile.

Type Defined in Information C G P S
bool Represented as an int. Yes Yes Yes Yes
buffer link(Objects/bufferobject.c) Yes Yes Yes No
cell link(Include/cellobject.h). Yes Yes Yes No
classobj link(Include/classobject.h) Yes Yes Yes No
instance link(Include/classobject.h) Yes Yes Yes No
instancemethod link(Include/classobject.h) Yes Yes Yes No
PyCObject link(Objects/cobject.c) Wraps arbitrary C data. Seems impossible to count. No No No No
complex link(Include/complexobject.h) Yes Yes Yes Yes
*_descriptor link(Include/descrobject.h) Looks very annoying to count. Contains C functions. It should be possible to count partly, though. No No No No
dictproxy link(Objects/descrobject.c) Yes Yes Yes No
method-wrapper link(Objects/descrobject.c) Yes Yes Yes No
property link(Objects/descrobject.c) Yes Yes Yes No
dict link(Include/dictobject.h) Code depends on representation and PyDict_MINSIZE. Yes Yes No No
dict-itemiterator link(Objects/dictobject.c) Returned from dict.iteritems(). Code contains a direct copy of dictiterobject from dictobject.c! Doesn't work in Python 2.3. Yes No Yes No
dict-keyiterator link(Objects/dictobject.c) Returned from dict.iterkeys(). Code contains a direct copy of dictiterobject from dictobject.c! Doesn't work in Python 2.3. Yes No Yes No
dict-valueiterator link(Objects/dictobject.c) Returned from dict.itervalues(). Code contains a direct copy of dictiterobject from dictobject.c! Doesn't work in Python 2.3. Yes No Yes No
enumerate link(Objects/enumobject.c) Yes Yes Yes No
file link(Include/fileobject.h) Counted by Pyrex code, apart from stdio internals, of course. Yes No No No
float link(Include/floatobject.h) Yes Yes Yes Yes
frame link(Include/frameobject.h) Carries an additional f_code.co_stacksize words of data (the stack). Yes Yes No No
function link(Include/funcobject.h) Yes Yes Yes No
classmethod link(Objects/funcobject.c) Yes Yes Yes No
staticmethod link(Objects/funcobject.c) Yes Yes Yes No
generator link(Include/genobject.h) Yes Yes Yes No
int link(Include/intobject.h) Yes Yes Yes Yes
iterator link(Objects/iterobject.c) Yes Yes Yes No
callable-iterator link(Objects/iterobject.c) Yes Yes Yes No
list link(Include/listobject.h) Counting code depends on representation of list as array of PyObject*. Yes Yes No No
listiterator link(Objects/listobject.c) Yes Yes Yes No
listreverseiterator link(Objects/listobject.c) Yes Yes Yes No
long link(Include/longintrepr.h) Counted by utils.c. Yes Yes No No
builtin_function_or_method link(Include/methodobject.h) Just about impossible to count - it represents a built-in function. It contains a PyMethodDef* which could be counted, though the size of the table will probably be negligible compared to the size of the functions. No Yes No No
module link(Objects/moduleobject.c) Very nice for such an important type. Just contains a dict. Yes Yes Yes No
NoneType link(Objects/object.c) Yes Yes Yes Yes
NotImplementedType link(Objects/object.c) Yes Yes Yes Yes
xrange link(Objects/rangeobject.c) Yes Yes Yes Yes
set, frozenset link(Include/setobject.h) Similar representation to dict. Code depends on representation and PySet_MINSIZE. Yes No No No
ellipsis link(Objects/sliceobject.c) Yes Yes Yes Yes
slice link(Include/sliceobject.h) Yes No Yes No
basestring link(Objects/stringobject.c) Yes Yes Yes Yes
str link(Include/stringobject.h) Code depends on representation as variable-size object. Yes Yes No No
structseq link(Include/structseq.h) Not a real type, despite appearances :-) N/A N/A N/A N/A
tuple link(Include/tupleobject.h) Code depends on representation as variable-size object. Yes Yes No No
tupleiterator link(Objects/tupleobject.c) Yes Yes Yes Yes
type link(Include/object.h) Terribly hairy to count. It's not done yet. It might be impossible. Luckily it tells the GC about its fields. No Yes No No
object link(Include/object.h) Only references its type. That's counted. Yes No No No
super link(Objects/typeobject.c) Yes Yes Yes No
unicode link(Include/unicodeobject.h) Sets __itemsize__ == 0, so the code uses 2 instead. Can contain a string-encoded version of itself which is counted by code in utils.c. Yes No No No
weakref, weakproxy, weakcallableproxy link(Include/weakrefobject.h) All behave nicely. Yes Yes Yes No
code link(Include/compile.h) Eek, I made a mistake with this and thought it talked to the GC. Yes No Yes No
symtable entry link(Include/symtable.h) Yes, the type name has a space in it! It looks like it co-operates with the GC, so should work nicely. Yes Yes No No
traceback link(Include/traceback.h) Yes Yes Yes No

Finding instances of some of the stranger types

buffer, cell, *_descriptor

Look in sizes.samples. You might need to run test2.test() first.

dictproxy

type.__dict__

method-wrapper

[].__len__

dict-itemiterator, dict-keyiterator, dict-valueiterator

Call dict object's iteritems(), iterkeys() and itervalues() methods respectively.

iterator

Define:

class A(object):
	def __getitem__(self, val):
		pass

and call iter(A()).

listiterator

iter(l) where l is a list.

listreverseiterator

reversed(l) where l is a list.

tupleiterator

iter(t) where t is a tuple.

List of all core types

This is a list of all types in the core interpreter. It's the edited output of grep PyTypeObject Objects/* Python/*.

link(Objects/boolobject.c):PyTypeObject PyBool_Type = {
link(Objects/bufferobject.c):PyTypeObject PyBuffer_Type = {
link(Objects/cellobject.c):PyTypeObject PyCell_Type = {
link(Objects/classobject.c):PyTypeObject PyClass_Type = {
link(Objects/classobject.c):PyTypeObject PyInstance_Type = {
link(Objects/classobject.c):PyTypeObject PyMethod_Type = {
link(Objects/cobject.c):PyTypeObject PyCObject_Type = {
link(Objects/complexobject.c):PyTypeObject PyComplex_Type = {
link(Objects/descrobject.c):static PyTypeObject PyMethodDescr_Type = {
link(Objects/descrobject.c):static PyTypeObject PyClassMethodDescr_Type = {
link(Objects/descrobject.c):static PyTypeObject PyMemberDescr_Type = {
link(Objects/descrobject.c):static PyTypeObject PyGetSetDescr_Type = {
link(Objects/descrobject.c):PyTypeObject PyWrapperDescr_Type = {
link(Objects/descrobject.c):static PyTypeObject proxytype = {
link(Objects/descrobject.c):static PyTypeObject wrappertype = {
link(Objects/descrobject.c):PyTypeObject PyProperty_Type = {
link(Objects/dictobject.c):PyTypeObject PyDict_Type = {
link(Objects/dictobject.c):PyTypeObject PyDictIterKey_Type = {
link(Objects/dictobject.c):PyTypeObject PyDictIterValue_Type = {
link(Objects/dictobject.c):PyTypeObject PyDictIterItem_Type = {
link(Objects/enumobject.c):PyTypeObject PyEnum_Type = {
link(Objects/enumobject.c):PyTypeObject PyReversed_Type = {
link(Objects/fileobject.c):PyTypeObject PyFile_Type = {
link(Objects/floatobject.c):PyTypeObject PyFloat_Type = {
link(Objects/frameobject.c):PyTypeObject PyFrame_Type = {
link(Objects/funcobject.c):PyTypeObject PyFunction_Type = {
link(Objects/funcobject.c):PyTypeObject PyClassMethod_Type = {
link(Objects/funcobject.c):PyTypeObject PyStaticMethod_Type = {
link(Objects/genobject.c):PyTypeObject PyGen_Type = {
link(Objects/intobject.c):PyTypeObject PyInt_Type = {
link(Objects/iterobject.c):PyTypeObject PySeqIter_Type = {
link(Objects/iterobject.c):PyTypeObject PyCallIter_Type = {
link(Objects/listobject.c):static PyTypeObject sortwrapper_type = {
link(Objects/listobject.c):static PyTypeObject cmpwrapper_type = {
link(Objects/listobject.c):PyTypeObject PyList_Type = {
link(Objects/listobject.c):PyTypeObject PyListIter_Type;
link(Objects/listobject.c):PyTypeObject PyListIter_Type = {
link(Objects/listobject.c):PyTypeObject PyListRevIter_Type;
link(Objects/listobject.c):PyTypeObject PyListRevIter_Type = {
link(Objects/longobject.c):PyTypeObject PyLong_Type = {
link(Objects/methodobject.c):PyTypeObject PyCFunction_Type = {
link(Objects/moduleobject.c):PyTypeObject PyModule_Type = {
link(Objects/object.c):static PyTypeObject PyNone_Type = {
link(Objects/object.c):static PyTypeObject PyNotImplemented_Type = {
link(Objects/rangeobject.c):PyTypeObject PyRange_Type = {
link(Objects/setobject.c):PyTypeObject PySet_Type = {
link(Objects/setobject.c):PyTypeObject PyFrozenSet_Type = {
link(Objects/sliceobject.c):static PyTypeObject PyEllipsis_Type = {
link(Objects/sliceobject.c):PyTypeObject PySlice_Type = {
link(Objects/stringobject.c):PyTypeObject PyBaseString_Type = {
link(Objects/stringobject.c):PyTypeObject PyString_Type = {
link(Objects/structseq.c):static PyTypeObject _struct_sequence_template = {
link(Objects/tupleobject.c):PyTypeObject PyTuple_Type = {
link(Objects/tupleobject.c):PyTypeObject PyTupleIter_Type;
link(Objects/tupleobject.c):PyTypeObject PyTupleIter_Type = {
link(Objects/typeobject.c):PyTypeObject PyType_Type = {
link(Objects/typeobject.c):PyTypeObject PyBaseObject_Type = {
link(Objects/typeobject.c):PyTypeObject PySuper_Type = {
link(Objects/unicodeobject.c):PyTypeObject PyUnicode_Type = {
link(Objects/weakrefobject.c):PyTypeObject _PyWeakref_RefType = {
link(Objects/weakrefobject.c):PyTypeObject _PyWeakref_ProxyType = {
link(Objects/weakrefobject.c):PyTypeObject _PyWeakref_CallableProxyType = {
link(Python/compile.c):PyTypeObject PyCode_Type = {
link(Python/symtable.c):PyTypeObject PySymtableEntry_Type = {
link(Python/traceback.c):PyTypeObject PyTraceBack_Type = {