New submission from Joshua Bronson <jabron...@gmail.com>:

Creating this issue by request of INADA Naoki to discuss my proposed patch in 
https://github.com/python/cpython/pull/5944.

Copy/pasting from that PR:

If you try something like issubclass('not a class', str), you get a helpful 
error message that immediately clues you in on what you did wrong:

>>> issubclass('not a class', str)
TypeError: issubclass() arg 1 must be a class
("AHA! I meant isinstance there. Thanks, friendly error message!")

But if you try this with some ABC, the error message is much less friendly!

>>> from some_library import SomeAbc
>>> issubclass('not a class', SomeAbc)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File 
"/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/abc.py",
 line 230, in __subclasscheck__
    cls._abc_negative_cache.add(subclass)
  File 
"/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_weakrefset.py",
 line 84, in add
    self.data.add(ref(item, self._remove))
TypeError: cannot create weak reference to 'str' object

("WTF just went wrong?" Several more minutes of head-scratching ensues. Maybe a 
less experienced Python programmer who hits this hasn't seen weakrefs before 
and gets overwhelmed, maybe needlessly proceeding down a deep rabbit hole 
before realizing no knowledge of weakrefs was required to understand what they 
did wrong.)

Or how about this example:

>>> from collections import Reversible
>>> issubclass([1, 2, 3], Reversible)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File 
"/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/abc.py",
 line 207, in __subclasscheck__
    ok = cls.__subclasshook__(subclass)
  File 
"/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_collections_abc.py",
 line 305, in __subclasshook__
    return _check_methods(C, "__reversed__", "__iter__")
  File 
"/usr/local/Cellar/python3/3.6.4_2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/_collections_abc.py",
 line 73, in _check_methods
    mro = C.__mro__
AttributeError: 'list' object has no attribute '__mro__'
Here you don't even get the same type of error (AttributeError rather than 
TypeError), which seems unintentionally inconsistent.

This trivial patch fixes this, and will hopefully save untold numbers of future 
Python programmers some time and headache.

Let me know if any further changes are required, and thanks in advance for 
reviewing.

----------
messages: 313376
nosy: inada.naoki, izbyshev, jab, serhiy.storchaka
priority: normal
pull_requests: 5781
severity: normal
status: open
title: Improve issubclass() error checking and message
type: enhancement
versions: Python 3.7, Python 3.8

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue33018>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to