-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
issubclass(obj, abc.ABC) causes a segfault #77180
Comments
Demo: >>> from abc import ABC
>>> issubclass(1, ABC)
Segmentation fault (core dumped) The stack trace is attached. Before reimplementation of abc in C, the result was confusing too: Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)]
on win32
>>> from abc import ABC
>>> issubclass(1, ABC)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "abc.py", line 230, in __subclasscheck__
File "_weakrefset.py", line 84, in add
TypeError: cannot create weak reference to 'int' object |
In debug mode, the following assertion fails: python: ./Modules/_abc.c:642: _abc__abc_subclasscheck_impl: Assertion `((((((PyObject*)(mro))->ob_type))->tp_flags & ((1UL << 26))) != 0)' failed. |
Is there any sense in accepting non-types as the first argument of issubclass()? I would add a check just in issubclass(). |
No, though it is not (clearly) documented. The docs mention TypeError, but only for the second argument if my reading is correct. In practice, issubclass() raises a TypeError if the first argument is not a class object: >>> issubclass(1, int)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: issubclass() arg 1 must be a class Though, as I mentioned above, behavior for ABCs was always weird. |
I've also checked that ABC.register() doesn't allow non-classes (and PEP-3119 mentions that). Looking at PyObject_IsSubclass in Objects/abstract.c, the only case in which its check_class() could be avoided is if there is a custom __subclasscheck__: >>> class M(type):
... def __subclasscheck__(cls, c):
... return c == 1 or super().__subclasscheck__(c)
...
>>> class A(metaclass=M):
... pass
...
>>> issubclass(1, A)
True If there is no need to support such weird __subclasscheck__, check_class() could be called earlier. Note, however, that check_class() treats anything having __bases__ as a class, so moving the check alone is not enough to avoid the crash in all cases. |
Actually, the behaviour when __suclasscheck__ returns True for non-class objects may be used by some code. Even typing module did this, I tried to remove as much as possible of this, but I think there may be few such situations left. Therefore, the patch by Inada-san (that makes C behaviour follow Python behaviour) looks reasonable to me. |
OK, making a new implementation behave as the old one is fine with me too. BTW, do TypeErrors related to weak references deserve any treatment? Isn't it a kind of coincidence that the error raised due to usage of WeakSet in issubclass(obj, ABC) is what we expect? (Sorry, I'm not familiar with WeakSets). |
Could you please show examples with __suclasscheck__ returning True for non-class objects? |
Sorry, I can't get what is your point. |
@inada.naoki: I don't question your change. My point is the same as in bpo-33018 (I've discovered that PR only after I commented). The error message is misleading, and it's just a coincidence that a TypeError and not some other error is raised when abc attempts to add a non-type object to a WeakSet. @serhiy.storchaka: Note that an example that you requested is unlikely to be related to ABC and probably is more like my artificial __subclasscheck__ example. So, making changes just for ABC as suggested in bpo-33018 might make sense. |
Sorry for status update, this was due to a concurrent modification. |
Serhiy, for example |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: