Some notes on what __dictoffset__ on types means in CPython

April 27, 2011

I mentioned __dictoffset__ in passing in HowSlotsWorkI. Today I feel like expanding on that passing mention with some notes. All of this is specific to CPython.

As mentioned in passing in HowSlotsWorkI, the __dictoffset__ attribute tells you the offset to where you find the pointer to the __dict__ object in any instance object that has one. It is in bytes. A positive value is an offset from the start of the object; a negative value is an offset from the end of the object, and is used only for classes derived from types (such as str and long) that have a variable-sized component. A __dictoffset__ value of zero means that the type (or class) doesn't have a __dict__ attribute.

(You can tell which types have a variable-sized component by looking at their __itemsize__ attribute; zero means that they don't have such a component.)

As sort of discussed in the sidebar in HowSlotsWorkI, if you inherit from something with a zero __dictoffset__ your subclass will normally have a non-zero __dictoffset__ and the pointer to the __dict__ object will be glued on the end of the C-level blob of your basic type.

Most built-in types have a __dictoffset__ of zero, as you'd expect. However, a few types have a non-zero __dictoffset__; the ones I know of are exceptions, functions, modules, and type itself. What is going on is that all of these types already have to have some sort of dictionary for their contents, along with a pointer to this dictionary in their basic C-level blob. So they reuse this pointer (and associated dictionary) as their __dict__, by pointing __dictoffset__ directly to this internal field. One consequence of this is that subclasses of these classes always have a __dict__, even if your subclass uses __slots__.

(In general, once a class has a non-zero __dictoffset__ all of its subclasses will always have a __dict__. I think that you can sometimes still save space and allocations by using __slots__, but you don't get any of the other features of __slots__ that people are sometimes unwisely attracted to.)

Written on 27 April 2011.
« A quick look at some spam filtering stats from our system
Mail rejection stats for our external mail gateway »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Wed Apr 27 01:27:11 2011
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.