[Python-ideas] Override dict.__new__ to raise if cls is not dict; do the same for str, list, etc.

Nick Coghlan ncoghlan at gmail.com
Fri Apr 22 09:24:10 EDT 2016


On 22 April 2016 at 16:06, Chris Angelico <rosuav at gmail.com> wrote:

> Maybe I'm just misunderstanding how metaclasses should be written, but
> this seems like it ought to work. And it's not making any use of the
> AutoCreateDict - despite __prepare__ and __new__ clearly being called,
> the latter with an AutoCreateDict instance. But by the time it gets
> actually attached to the dictionary, we have a mappingproxy that
> ignores __missing__. The docs say "are translated to", implying that
> this will actually be equivalent.
>

The mapping used during class body execution can be customised via
__prepare__, but the resulting contents of that mapping are still copied to
a regular dictionary when constructing the class object itself.

We deliberately don't provide a mechanism to customise the runtime
dictionary used by object instances, regardless of whether they're normal
instances or type definitions. In combination with the __dict__ descriptor
only exposing a mapping proxy, this ensures that all Python level
modifications to the contents go through the descriptor machinery - you
can't get your hands on a mutable pointer to the post-creation namespace.

It looks like there *is* a missing detail in the data model docs in
relation to this, though:
https://docs.python.org/3/reference/datamodel.html#creating-the-class-object
should state explicitly that the namespace contents are copied to a plain
dict (which is then never exposed directly to Python code), but it doesn't.

Cheers,
Nick.

P.S. I actually played around with an experimental interpreter build that
dropped the copy-to-a-new-namespace step back when I was working on
https://www.python.org/dev/peps/pep-0422/#new-ways-of-using-classes. It's
astonishingly broken in the number of ways it offers to corrupt the
interpreter state (since you can entirely bypass the descriptor machinery,
which the rest of the interpreter expects to be impossible if you're not
messing about with ctypes or C extensions), but kinda fun in the quirky
action at a distance it makes possible :)

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160422/e9c76dee/attachment-0001.html>


More information about the Python-ideas mailing list