Confused about __prepare__

A

andrew cooke

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?

Thanks,
Andrew


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):

@classmethod
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
 
C

Chris Rebert

In the code below I use __prepare__ to change the class dictionary so that a tuple is stored in __setitem__().  Since __getitem__() removes thetuple I wasn't expecting any problems, but it seems that __init__ is beingretrieved via some other mechanism.  Why?

I suspect you're being bitten by
http://docs.python.org/dev/reference/datamodel.html#special-method-lookup

In particular: "implicit special method lookup generally also bypasses
the __getattribute__() method".

__init__() is a special method.
The default __getattribute__() implementation consults an object's __dict__..
type.__new__() presumably does an implicit special method lookup for
__init__() behind the scenes.

Hence, your custom __dict__ is bypassed.

Cheers,
Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top