[issue33018] Improve issubclass() error checking and message

Joshua Bronson report at bugs.python.org
Mon Mar 12 08:59:11 EDT 2018


Joshua Bronson <jabronson at gmail.com> added the comment:

I'll share the use case that prompted me to submit this PR in the first place.

I am the author of bidict (https://pypi.python.org/pypi/bidict), which provides a bidirectional dict class. A bidict is just like a dict, except it automatically maintains its inverse bidict, which is accessible via its .inv attribute. To prevent a bidict and its inverse from creating a strong reference cycle, a weak ref is used to store the reference one direction.

bidicts implement my BidirectionalMapping ABC, which extends collections.abc.Mapping to include the .inv abstractproperty. BidirectionalMapping overrides __subclasshook__ so that outside implementations that don't subclass it explicitly may still be considered subclasses.

Recently, I tried something like `issublass('foo', BidirectionalMapping)`, and got the "cannot create weak reference to 'str' object" error. Because this error message differs from the (much more helpful) "arg 1 must be a class" error message that you get when you do e.g. `issubclass('foo', Mapping)`, I thought there might be a bug somewhere in my code. Then I looked deeper and found where this is really coming from.

I experimented more and noticed that `issubclass('foo', Reversible)` raises AttributeError, which isn't even the same type of error.

The exceptions that are raised in these cases seem like an abstraction leak. The error messages do not help users immediately realize what they did wrong and how they can fix it; more knowledge of internals is required to make sense of what's going on than should be needed. The inconsistency in these errors is a further problem. The same mistake should not cause three different errors unless there is some really good reason. This seems unintentional. Can any of the original authors say whether this is working as intended or if this is in fact an oversight?

The current behavior causes confusion for both less experienced and more experienced Python users alike. (Would anyone else here have correctly predicted all of the different errors that the examples above cause? How many other Python experts could have?) For less experienced users, Python's general consistency and predictability, lack of gotchas, and good errors are some of its best features. This is such an exception that it seems like a bug.

I'm happy for some other patch than the one I submitted in https://github.com/python/cpython/pull/5944 to land if necessary, as long as something fixes this. And fwiw, +1 for 3.7, unless anyone can demonstrate any credible risk.

Thanks for your consideration :)

----------

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue33018>
_______________________________________


More information about the Python-bugs-list mailing list