-
-
Notifications
You must be signed in to change notification settings - Fork 31.4k
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
.
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.
Thanks! Just two minor comments
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.
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.
LGTM now.
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.
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.
LGTM. +1 about the unittest name could be more specific, but it's just a preference.
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 🌮🎉.. I'm working now to backport this PR to: 3.7. |
(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.
C implementation of
ABC.__subclasscheck__(cls, subclass)
crashed whensubclass
is not type object.This commit makes C implementation more similar to Python implementation.
https://bugs.python.org/issue32999