Confused about __prepare__

andrew cooke andrew at
Fri Apr 8 00:31:16 CEST 2011

In the code below I use __prepare__ to change the class dictionary so that a tuple is stored in __setitem__().  Since __getitem__() removes the tuple I wasn't expecting any problems, but it seems that __init__ is being retrieved via some other mechanism.  Why?  Is a copy of the dict being made somewhere?  If so, can I change that?


class TupleDict(dict):
    '''Stores additional info, but removes it on __getitem__().'''
    def __setitem__(self, key, value):
        print('setting', key, value)
        super(TupleDict, self).__setitem__(key, (value, 'secret'))
    def __getitem__(self, key):
        value = super(TupleDict, self).__getitem__(key)
        print('getting', key, value[0]) # drop secret
        return value[0]

class TupleMeta(type):
    def __prepare__(metacls, name, bases, **kargs):
        print('in prepare')
        return TupleDict()
    def __new__(cls, name, bases, classdict):
        print('in new')
        return type.__new__(cls, name, bases, classdict)
class C(metaclass=TupleMeta):
    def __init__(self):
        self.a = 1
c = C()

in prepare
setting __module__ __main__
setting __init__ <function __init__ at 0x7f37cbad40d8>
in new
Traceback (most recent call last):
  File ..., line 34, in <module>
    c = C() # TypeError: 'tuple' object is not callable
TypeError: 'tuple' object is not callable

More information about the Python-list mailing list