[Python-ideas] Override dict.__new__ to raise if cls is not dict; do the same for str, list, etc.
Neil Girdhar
mistersheik at gmail.com
Thu Apr 21 01:33:24 EDT 2016
On Thu, Apr 21, 2016 at 1:15 AM Chris Angelico <rosuav at gmail.com> wrote:
> On Thu, Apr 21, 2016 at 2:33 PM, Neil Girdhar <mistersheik at gmail.com>
> wrote:
> > I think inheriting directly from dict is simply bad code because CPython
> > doesn't promise that any of your overridden methods will be called. The
> > fact that it silently doesn't call them is an inscrutable trap. And
> really,
> > it's not much of a "punishment" to simply change your base class name.
>
> There are way too many cases that work just fine, though.
>
> >>> class AutoCreateDict(dict):
> ... def __missing__(self, key):
> ... return "<autocreated %r>" % key
> ...
> >>> acd = AutoCreateDict()
> >>> acd["asdf"]
> "<autocreated 'asdf'>"
>
> Why should I inherit from UserDict instead? I have to import that from
> somewhere (is it in types? collections? though presumably your error
> message would tell me that), and then I have to contend with the fact
> that my class is no longer a dictionary.
>
Of course it's a dictionary. It's an abc.Mapping, which is all a user of
your class should care about. After all, it "quacks like a duck", which is
all that matters.
>
> >>> class AutoCreateUserDict(collections.UserDict):
> ... def __missing__(self, key):
> ... return "<autocreated %r>" % key
> ...
> >>> acud = AutoCreateUserDict()
> >>> acud["qwer"]
> "<autocreated 'qwer'>"
> >>> json.dumps(acd)
> '{}'
> >>> json.dumps(acud)
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> File "/usr/local/lib/python3.6/json/__init__.py", line 230, in dumps
> return _default_encoder.encode(obj)
> File "/usr/local/lib/python3.6/json/encoder.py", line 199, in encode
> chunks = self.iterencode(o, _one_shot=True)
> File "/usr/local/lib/python3.6/json/encoder.py", line 257, in iterencode
> return _iterencode(o, 0)
> File "/usr/local/lib/python3.6/json/encoder.py", line 180, in default
> o.__class__.__name__)
> TypeError: Object of type 'AutoCreateUserDict' is not JSON serializable
>
>
That's a fair point, but it seems like a bug in JSON. They should have
checked if it's an abc.Mapping imho.
> If you *do* push forward with this proposal, incidentally, I would
> recommend not doing it in __new__, but changing it so the class is no
> longer subclassable, as per bool:
>
> >>> class X(int): pass
> ...
> >>> class X(bool): pass
> ...
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> TypeError: type 'bool' is not an acceptable base type
>
Good point.
>
> But I am firmly -1 on disallowing dict subclasses just because they
> aren't guaranteed to call all of your overridden methods.
>
> ChrisA
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
> --
>
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "python-ideas" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/python-ideas/7nFQURLhlQY/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> python-ideas+unsubscribe at googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20160421/434d69e6/attachment-0001.html>
More information about the Python-ideas
mailing list