From: Ethan Furman on
Christian Heimes wrote:
>> Perhaps punctuation will help clarify my intent:
>>
>> __missing__ is *not* part of (dict)s, as shown by dir(dict()):
>
> Indeed, that's correct. Can we agree, that __missing__ is an optional
> feature of the dict interface, that can be implemented in subclasses of
> dict?

Absolutely.

~Ethan~
From: John Posner on
On 8/3/2010 6:48 PM, Ethan Furman wrote:
> Christian Heimes wrote:
>>> I just went and read the entry that had the bogus claim --
>>> personally, I didn't see any confusion. I would like to point out the
>>> __missing__ is *not* part of dicts (tested on 2.5 and 2.6 -- don't
>>> have 2.7 installed yet).
>>
>> I beg your pardon but you are wrong. __missing__ is available for all
>> *subclasses* of dict since Python 2.5. See
>> http://svn.python.org/view/python/branches/release25-maint/Objects/dictobject.c?revision=81031&view=markup
>>
>>
>>>>> class mydict(dict):
>> ... def __missing__(self, key):
>> ... print "__missing__", key
>> ... raise KeyError(key)
>> ...
>>>>> m = mydict()
>>>>> m[1]
>> __missing__ 1
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in <module>
>> File "<stdin>", line 4, in __missing__
>> KeyError: 1
>
> Perhaps punctuation will help clarify my intent:
>
> __missing__ is *not* part of (dict)s, as shown by dir(dict()):
>
> ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__',
> '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__',
> '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__',
> '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__',
> '__repr__', '__setattr__', '__setitem__', '__str__', 'clear', 'copy',
> 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys',
> 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update',
> 'values']
>
> And, just to state what is hopefully obvious, if you don't create
> __missing__ yourself, it still isn't in the subclass:

Right, a __missing__ method does not magically appear in the subclass.
Rather, the subclass is allowed (but not required) to define a method
named __missing__, which will "magically" be called in certain situations.

Here's a dict subclass that uses the "magic" for a purpose that has
nothing to do with default values:

class BadKeyTrackerDict(dict):
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
self.bad_keys = set([])

def __missing__(self, key):
"""
add missing key to "bad keys" set
"""
self.bad_keys.add(key)
raise KeyError

Note that "defaultdict" is nowhere in sight here. It's the dict class
(or type) itself that provides the magic -- but only for its subclasses.

>
> --> class somedict(dict):
> ... "Is __missing__ defined if I don't define it? Nope."
> ...
> --> sd = somedict()
> --> sd[1]
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> KeyError: 1
> --> dir(sd)
> ['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__',
> '__dict__', '__doc__', '__eq__', '__ge__', '__getattribute__',
> '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__',
> '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
> '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__str__',
> '__weakref__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items',
> 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem',
> 'setdefault', 'update', 'values']
>
> ~Ethan~

-John
From: John Posner on
On 8/2/2010 11:00 PM, John Posner wrote:
> On 7/31/2010 1:31 PM, John Posner wrote:
>>
>> Caveat -- there's another description of defaultdict here:
>>
>> http://docs.python.org/library/collections.html#collections.defaultdict
>>
>> ... and it's bogus. This other description claims that __missing__ is a
>> method of defaultdict, not of dict.
>
> Following is a possible replacement for the bogus description. Comments
> welcome. I intend to submit a Python doc bug, and I'd like to have a
> clean alternative to propose.


After some off-list discussion with Ethan Furman (many thanks!), the
Python Doc bug is submitted: #9536 at bugs.python.org.

-John
From: Wolfram Hinderer on
On 6 Aug., 22:07, John Posner <jjpos...(a)optimum.net> wrote:
> On 8/2/2010 11:00 PM, John Posner wrote:
>
> > On 7/31/2010 1:31 PM, John Posner wrote:
>
> >> Caveat -- there's another description of defaultdict here:
>
> >>http://docs.python.org/library/collections.html#collections.defaultdict
>
> >> ... and it's bogus. This other description claims that __missing__ is a
> >> method of defaultdict, not of dict.
>
> > Following is a possible replacement for the bogus description. Comments
> > welcome. I intend to submit a Python doc bug, and I'd like to have a
> > clean alternative to propose.
>
> After some off-list discussion with Ethan Furman (many thanks!), the
> Python Doc bug is submitted: #9536 at bugs.python.org.
>
> -John

This is probably nitpicking, but the patch calls __missing__ a special
method. However, unlike special methods, it is not invoked by "special
syntax" but by the dict's __getitem__ method. (len() invokes __len__
on any object - you can't do something similar with __missing__.)

__missing__ is also not listed as a special method on
http://docs.python.org/py3k/reference/datamodel.html#special-method-names

However, "normal" special method lookup seems to be used.
From: John Posner on
On 8/6/2010 6:24 PM, Wolfram Hinderer wrote:
>
> This is probably nitpicking, but the patch calls __missing__ a special
> method. However, unlike special methods, it is not invoked by "special
> syntax" but by the dict's __getitem__ method. (len() invokes __len__
> on any object - you can't do something similar with __missing__.)
>
> __missing__ is also not listed as a special method on
> http://docs.python.org/py3k/reference/datamodel.html#special-method-names
>
> However, "normal" special method lookup seems to be used.

Fair enough. Please add your comment to #9536 at bugs.python.org.

Tx,
John