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
bpo-32999: Fix ABC.__subclasscheck__ crash #6002
Conversation
Modules/_abc.c
Outdated
| * return True | ||
| */ | ||
| _Py_IDENTIFIER(__mro__); | ||
| if (_PyObject_LookupAttrId(subclass, &PyId___mro__, &mro) < 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mro is leaked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As well as impl.
Lib/test/test_abc.py
Outdated
| @@ -392,6 +392,13 @@ class MyInt(int): | |||
| self.assertIsInstance(42, A) | |||
| self.assertIsInstance(42, (A,)) | |||
|
|
|||
| def test_issubclass(self): | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather make the test name more specific, or add few more corner cases here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
Modules/_abc.c
Outdated
| */ | ||
| _Py_IDENTIFIER(__mro__); | ||
| if (_PyObject_LookupAttrId(subclass, &PyId___mro__, &mro) < 0) { | ||
| return NULL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe this should be goto end; or similar? (for clean-up)
Modules/_abc.c
Outdated
| @@ -690,6 +699,7 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self, | |||
| result = Py_False; | |||
|
|
|||
| end: | |||
| Py_XDECREF(mro); | |||
| Py_XDECREF(impl); | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks to me impl can't be NULL here.
Lib/test/test_abc.py
Outdated
| __mro__ = 42 # __mro__ is not tuple | ||
|
|
||
| with self.assertRaises(TypeError): | ||
| self.assertTrue(issubclass(C(), A)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.assertTrue is not needed.
Modules/_abc.c
Outdated
| if (_add_to_weak_set(&impl->_abc_cache, subclass) < 0) { | ||
| for (pos = 0; pos < PyTuple_GET_SIZE(mro); pos++) { | ||
| PyObject *mro_item = PyTuple_GET_ITEM(mro, pos); | ||
| if (mro_item == NULL) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this check needed? If it is a must, we need to set an exception in this branch, otherwise we will return NULL while no exception set.
Modules/_abc.c
Outdated
| @@ -258,6 +252,7 @@ _abc__get_dump(PyObject *module, PyObject *self) | |||
| static int | |||
| compute_abstract_methods(PyObject *self) | |||
| { | |||
| _Py_IDENTIFIER(__abstractmethods__); | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why don't we define these identifiers at the top level?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer local variable when it's used only in one function.
If you prefer top level, I'll revert unnecessary changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I usually move them to the top level as it's hard to track if a variable like this is used in one or in many functions. Really up to you though, I'm OK about this change either way.
|
I'm bad at English, including vocabulary. Would you propose better name, instead of just saying "specific"? |
|
I mean something like |
|
Thanks @methane for the PR |
(cherry picked from commit fc7df0e) Co-authored-by: INADA Naoki <methane@users.noreply.github.com>
|
GH-6014 is a backport of this pull request to the 3.7 branch. |
bpo-33018 (pythonGH-5944) fixed bpo-32999 too. So fc7df0e is not required anymore. Revert it except test case.
bpo-33018 (pythonGH-5944) fixed bpo-32999 too. So fc7df0e is not required anymore. Revert it except test case. (cherry picked from commit f757b72) Co-authored-by: INADA Naoki <methane@users.noreply.github.com>
bpo-33018 (pythonGH-5944) fixed bpo-32999 too. So fc7df0e is not required anymore. Revert it except test case.
bpo-33018 (pythonGH-5944) fixed bpo-32999 too. So fc7df0e is not required anymore. Revert it except test case.
C implementation of
ABC.__subclasscheck__(cls, subclass)crashed whensubclassis not type object.This commit makes C implementation more similar to Python implementation.
https://bugs.python.org/issue32999