I believe CPython just allocates slightly more memory than the structure describing the object requres and stores the attributes in fixed locations immediately after it. It's basically the same way that it handles attributes of built-in types, except that those also have a C struct describing the attribute layout.