[Python-ideas] Override dict.__new__ to raise if cls is not dict; do the same for str, list, etc.
Ethan Furman
ethan at stoneleaf.us
Fri Apr 22 07:51:47 EDT 2016
On 04/21/2016 11:06 PM, Chris Angelico wrote:
> On Fri, Apr 22, 2016 at 3:17 PM, Ben Finney wrote:
>> Random832 writes:
>>> Because looking up an attribute implies getting an item from the
>>> object or class's __dict__ with a string key of the name of the
>>> attribute (see below for the documented basis for this assumption).
>>
>> No, that's not what it implies. The ‘__dict__’ of an object is an
>> implementation detail, and is not necessarily used for attribute lookup.
>>
>> As the documentation says:
>>
>> A class has a namespace implemented by a dictionary object. Class
>> attribute references are translated to lookups in this dictionary,
>> e.g., C.x is translated to C.__dict__["x"] (although there are a
>> number of hooks which allow for other means of locating attributes).
>>
>> <URL:https://docs.python.org/3.5/reference/datamodel.html>
>
> Okay. That definitely implies that the class itself has a real dict,
> though.
A class does have a real dict() -- not a subclass, not a look-a-like,
but a real, honest-to-goodness, freshly minted {}.
> And it should be possible, using a metaclass, to manipulate
> that, right?
Only for the purposes of class creation. One of the final steps of
creating a class (after __prepare__ and __new__ have been called) is to
copy everything from whatever dict (sub)class you used into a brand-new
dict.
> Maybe I'm just misunderstanding how metaclasses should be written, but
> this seems like it ought to work.
You have the metaclass portion right.
> And it's not making any use of the
> AutoCreateDict - despite __prepare__ and __new__ clearly being called,
> the latter with an AutoCreateDict instance.
Well, it would if you tried creating any attributes without values
during class creation.
> But by the time it gets
> actually attached to the dictionary, we have a mappingproxy that
> ignores __missing__.
No, it's a dict -- we just don't get to directly fiddle with it (hence
the return of a mappingproxy).
> The docs say "are translated to", implying that
> this will actually be equivalent.
> Is there any way to make use of this documented transformation?
There are already many hooks in place to supplement or replace attribute
lookup -- use them instead. :)
--
~Ethan~
More information about the Python-ideas
mailing list