<div dir="ltr"><br><br><div class="gmail_quote"><div dir="ltr">On Wed, 28 Oct 2015 at 08:47 <<a href="mailto:jab@math.brown.edu">jab@math.brown.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Dear Python-Dev,<div><br></div><div>I am the author of bidict, a bidirectional map implementation for Python. A user recently filed a bug that bidict should be a subclass of dict, so that isinstance(mybidict, dict) would return True. I replied that the user should instead use isinstance(mybidict, collections.abc.Mapping), which does already return True, and is more polymorphic to boot.</div></div></blockquote><div><br></div><div>I would argue that chances are they don't need isinstance() in either case. :)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>But before I put the issue to bed, I want to make sure I'm correctly understanding the intended usage of collections.abc, as well as any relevant interfaces I'm not currently using (collections.UserDict? __subclasshook__?), since the documentation leaves me with some doubt. Could any collections experts on this list please confirm whether bidict is implemented as the language intends it should be?</div></div></blockquote><div><br></div><div>ABCs are meant to make sure you implement key methods for an interface/protocol. So in the case of collections.abc.Mapping, it's to make sure you implement __getitem__. In exchange for subclassing the ABC you also gain some methods for free like get(). So you subclass an ABC because you want your object to be acceptable in any code that expects an object that implements that interface/protocol and you want the help ABCs provide in making sure you don't accidentally miss some key method.</div><div><br></div><div>Subclassing a concrete implementation of the Mapping ABC -- which is what dict is -- should be done if it is beneficial to you, but not simply to satisfy an isinstance() check. I think the ABC registration is the right thing to do and the user requesting the dict subclass should actually be doing what you suggested and testing for the interface/protocol and not the concrete implementation.</div><div><br></div><div>And if you want another way to hit this point home, with type hints people should only be expecting abstract types like typing.Mapping as input: <a href="https://docs.python.org/3/library/typing.html#typing.Mapping">https://docs.python.org/3/library/typing.html#typing.Mapping</a> . Restricting yourself to only a dict locks out other completely viable types that implement the mapping interface/protocol. Much like working with data, you should be as flexible as possible on your inputs (e.g., specifying typing.Mapping as the parameter type), but as strict as possible on the return type (.e.g, specifying dict/typing.Dict as the return type).</div><div><br></div><div>I honestly would want to know why the user cares about an isinstance() check to begin with since they might want to go with a try/except when using the object how they want it to be and erroring out if they get passed an object that doesn't quack like a dict thanks to duck typing.</div><div><br></div><div>-Brett</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>Some quick references:</div><div><a href="https://bidict.readthedocs.org/en/latest/other-bidict-types.html#bidict-type-hierarchy" target="_blank">https://bidict.readthedocs.org/en/latest/other-bidict-types.html#bidict-type-hierarchy</a><br></div><div><a href="https://github.com/jab/bidict/blob/master/bidict/_bidict.py" target="_blank">https://github.com/jab/bidict/blob/master/bidict/_bidict.py</a><br></div><div><br></div><div>I would be happy to try to capture what I learn from this thread and write up a guide for collections library authors in the future, or otherwise pay your help forward however I can.</div><div><br></div><div>Thanks and best wishes.</div><div><br></div><div>-jab</div></div>
_______________________________________________<br>
Python-Dev mailing list<br>
<a href="mailto:Python-Dev@python.org" target="_blank">Python-Dev@python.org</a><br>
<a href="https://mail.python.org/mailman/listinfo/python-dev" rel="noreferrer" target="_blank">https://mail.python.org/mailman/listinfo/python-dev</a><br>
Unsubscribe: <a href="https://mail.python.org/mailman/options/python-dev/brett%40python.org" rel="noreferrer" target="_blank">https://mail.python.org/mailman/options/python-dev/brett%40python.org</a><br>
</blockquote></div></div>