FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

gh-159739: Keep the instance type alive during ABC subclass checks by jelle-openai · Pull Request #160198 · python/cpython · GitHub

Repository navigation

Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension .c  (1) .py  (1) .rst  (1) All 3 file types selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
30 changes: 29 additions & 1 deletion Lib/test/test_abc.py
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@
"""Unit tests for abc.py."""

import unittest
import weakref

import abc
import _py_abc
from inspect import isabstract
from test.support import warnings_helper
from test.support import gc_collect, warnings_helper

def test_factory(abc_ABCMeta, abc_get_cache_token):
class TestLegacyAPI(unittest.TestCase):
Expand Down Expand Up @@ -380,6 +381,33 @@ class C(str): pass
self.assertIsSubclass(C, A)
self.assertIsSubclass(C, (A,))

def test_instancecheck_class_changes_in_subclasscheck(self):
class Original:
def __getattribute__(self, name):
if name == '__class__':
return int
return object.__getattribute__(self, name)

class Replacement:
pass

instance = Original()
original = weakref.ref(Original)
del Original

class Meta(abc_ABCMeta):
def __subclasscheck__(cls, candidate):
if candidate is int:
instance.__class__ = Replacement
gc_collect()
self.assertIsNotNone(original())
return False

class Interface(metaclass=Meta):
pass

self.assertNotIsInstance(instance, Interface)

def test_instancecheck_no_class(self):
# gh-153772: __instancecheck__ must fall back to type(instance)
# when the instance has no __class__, matching isinstance().
Expand Down
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix a possible crash in :class:`abc.ABCMeta` instance checks when a subclass-checking callback changes the instance’s class.
4 changes: 4 additions & 0 deletions Modules/_abc.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -664,9 +664,12 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self,
subclass);
goto end;
}
/* A subclass check can change the instance's actual type. */
Py_INCREF(subtype);
result = PyObject_CallMethodOneArg(self, &_Py_ID(__subclasscheck__),
subclass);
if (result == NULL) {
Py_DECREF(subtype);
goto end;
}

Expand All @@ -684,6 +687,7 @@ _abc__abc_instancecheck_impl(PyObject *module, PyObject *self,
default:
Py_UNREACHABLE();
}
Py_DECREF(subtype);

end:
Py_XDECREF(impl);
Expand Down
Loading

Back | FazBrowse Home | New Git URL