Skip to content
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

Merged
merged 12 commits into from
Mar 7, 2018

Conversation

methane
Copy link
Member

@methane methane commented Mar 6, 2018

C implementation of ABC.__subclasscheck__(cls, subclass) crashed when subclass is not type object.

This commit makes C implementation more similar to Python implementation.

https://bugs.python.org/issue32999

Modules/_abc.c Outdated
* return True
*/
_Py_IDENTIFIER(__mro__);
if (_PyObject_LookupAttrId(subclass, &PyId___mro__, &mro) < 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mro is leaked.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As well as impl.

Copy link
Member

@ilevkivskyi ilevkivskyi left a 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

@@ -392,6 +392,13 @@ class MyInt(int):
self.assertIsInstance(42, A)
self.assertIsInstance(42, (A,))

def test_issubclass(self):
Copy link
Member

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.

Copy link
Member

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;
Copy link
Member

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);
Copy link
Member

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.

__mro__ = 42 # __mro__ is not tuple

with self.assertRaises(TypeError):
self.assertTrue(issubclass(C(), A))
Copy link
Contributor

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.

Copy link
Member

@ilevkivskyi ilevkivskyi left a 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) {
Copy link
Member

@zhangyangyu zhangyangyu Mar 6, 2018

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__);
Copy link
Member

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?

Copy link
Member Author

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.

Copy link
Member

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.

Copy link
Member

@zhangyangyu zhangyangyu left a 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.

@methane
Copy link
Member Author

methane commented Mar 7, 2018

I'm bad at English, including vocabulary. Would you propose better name, instead of just saying "specific"?

@zhangyangyu
Copy link
Member

I mean something like test_issubclass_bad_arguments since the test only tests for exception cases.

@methane methane merged commit fc7df0e into python:master Mar 7, 2018
@miss-islington
Copy link
Contributor

Thanks @methane for the PR 🌮🎉.. I'm working now to backport this PR to: 3.7.
🐍🍒⛏🤖

@methane methane deleted the fix-abc-issubclass-bpo32999 branch March 7, 2018 07:27
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Mar 7, 2018
(cherry picked from commit fc7df0e)

Co-authored-by: INADA Naoki <methane@users.noreply.github.com>
@bedevere-bot
Copy link

GH-6014 is a backport of this pull request to the 3.7 branch.

miss-islington added a commit that referenced this pull request Mar 7, 2018
(cherry picked from commit fc7df0e)

Co-authored-by: INADA Naoki <methane@users.noreply.github.com>
methane added a commit to methane/cpython that referenced this pull request Mar 22, 2018
bpo-33018 (pythonGH-5944) fixed bpo-32999 too.  So fc7df0e is not required
anymore.  Revert it except test case.
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Mar 22, 2018
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>
methane added a commit that referenced this pull request Mar 22, 2018
bpo-33018 (GH-5944) fixed bpo-32999 too.  So fc7df0e is not required
anymore.  Revert it except test case.
ilevkivskyi pushed a commit that referenced this pull request Mar 22, 2018
bpo-33018 (GH-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>
jo2y pushed a commit to jo2y/cpython that referenced this pull request Mar 23, 2018
jo2y pushed a commit to jo2y/cpython that referenced this pull request Mar 23, 2018
bpo-33018 (pythonGH-5944) fixed bpo-32999 too.  So fc7df0e is not required
anymore.  Revert it except test case.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants