Skip to content

Commit b723912

Browse files
committed
gh-92810: Address review fixes
1 parent e24e815 commit b723912

File tree

3 files changed

+71
-74
lines changed

3 files changed

+71
-74
lines changed

Lib/test/test_abc.py

Lines changed: 58 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
def test_factory(abc_ABCMeta, abc_get_cache_token):
1616
class TestLegacyAPI(unittest.TestCase):
17-
1817
def test_abstractproperty_basics(self):
1918
@abc.abstractproperty
2019
def foo(self): pass
@@ -70,6 +69,25 @@ def foo(): return 4
7069

7170

7271
class TestABC(unittest.TestCase):
72+
def check_isinstance(self, obj, target_class):
73+
self.assertIsInstance(obj, target_class)
74+
self.assertIsInstance(obj, (target_class,))
75+
self.assertIsInstance(obj, target_class | target_class)
76+
77+
def check_not_isinstance(self, obj, target_class):
78+
self.assertNotIsInstance(obj, target_class)
79+
self.assertNotIsInstance(obj, (target_class,))
80+
self.assertNotIsInstance(obj, target_class | target_class)
81+
82+
def check_issubclass(self, klass, target_class):
83+
self.assertIsSubclass(klass, target_class)
84+
self.assertIsSubclass(klass, (target_class,))
85+
self.assertIsSubclass(klass, target_class | target_class)
86+
87+
def check_not_issubclass(self, klass, target_class):
88+
self.assertNotIsSubclass(klass, target_class)
89+
self.assertNotIsSubclass(klass, (target_class,))
90+
self.assertNotIsSubclass(klass, target_class | target_class)
7391

7492
def test_ABC_helper(self):
7593
# create an ABC using the helper class and perform basic checks
@@ -283,39 +301,24 @@ class C(A):
283301
c = C()
284302
# trigger caching
285303
for _ in range(2):
286-
self.assertIsInstance(a, A)
287-
self.assertIsInstance(a, (A,))
288-
self.assertNotIsInstance(a, B)
289-
self.assertNotIsInstance(a, (B,))
290-
self.assertNotIsInstance(a, C)
291-
self.assertNotIsInstance(a, (C,))
292-
293-
self.assertIsInstance(b, B)
294-
self.assertIsInstance(b, (B,))
295-
self.assertIsInstance(b, A)
296-
self.assertIsInstance(b, (A,))
297-
self.assertNotIsInstance(b, C)
298-
self.assertNotIsInstance(b, (C,))
299-
300-
self.assertIsInstance(c, C)
301-
self.assertIsInstance(c, (C,))
302-
self.assertIsInstance(c, A)
303-
self.assertIsInstance(c, (A,))
304-
self.assertNotIsInstance(c, B)
305-
self.assertNotIsInstance(c, (B,))
306-
307-
self.assertIsSubclass(B, A)
308-
self.assertIsSubclass(B, (A,))
309-
self.assertIsSubclass(C, A)
310-
self.assertIsSubclass(C, (A,))
311-
self.assertNotIsSubclass(B, C)
312-
self.assertNotIsSubclass(B, (C,))
313-
self.assertNotIsSubclass(C, B)
314-
self.assertNotIsSubclass(C, (B,))
315-
self.assertNotIsSubclass(A, B)
316-
self.assertNotIsSubclass(A, (B,))
317-
self.assertNotIsSubclass(A, C)
318-
self.assertNotIsSubclass(A, (C,))
304+
self.check_isinstance(a, A)
305+
self.check_not_isinstance(a, B)
306+
self.check_not_isinstance(a, C)
307+
308+
self.check_isinstance(b, B)
309+
self.check_isinstance(b, A)
310+
self.check_not_isinstance(b, C)
311+
312+
self.check_isinstance(c, C)
313+
self.check_isinstance(c, A)
314+
self.check_not_isinstance(c, B)
315+
316+
self.check_issubclass(B, A)
317+
self.check_issubclass(C, A)
318+
self.check_not_issubclass(B, C)
319+
self.check_not_issubclass(C, B)
320+
self.check_not_issubclass(A, B)
321+
self.check_not_issubclass(A, C)
319322

320323
def test_registration_basics(self):
321324
class A(metaclass=abc_ABCMeta):
@@ -327,45 +330,33 @@ class B(object):
327330
b = B()
328331
# trigger caching
329332
for _ in range(2):
330-
self.assertNotIsSubclass(B, A)
331-
self.assertNotIsSubclass(B, (A,))
332-
self.assertNotIsInstance(b, A)
333-
self.assertNotIsInstance(b, (A,))
333+
self.check_not_issubclass(B, A)
334+
self.check_not_isinstance(b, A)
334335

335-
self.assertNotIsSubclass(A, B)
336-
self.assertNotIsSubclass(A, (B,))
337-
self.assertNotIsInstance(a, B)
338-
self.assertNotIsInstance(a, (B,))
336+
self.check_not_issubclass(A, B)
337+
self.check_not_isinstance(a, B)
339338

340339
B1 = A.register(B)
341340
# trigger caching
342341
for _ in range(2):
343-
self.assertIsSubclass(B, A)
344-
self.assertIsSubclass(B, (A,))
345-
self.assertIsInstance(b, A)
346-
self.assertIsInstance(b, (A,))
342+
self.check_issubclass(B, A)
343+
self.check_isinstance(b, A)
347344
self.assertIs(B1, B)
348345

349-
self.assertNotIsSubclass(A, B)
350-
self.assertNotIsSubclass(A, (B,))
351-
self.assertNotIsInstance(a, B)
352-
self.assertNotIsInstance(a, (B,))
346+
self.check_not_issubclass(A, B)
347+
self.check_not_isinstance(a, B)
353348

354349
class C(B):
355350
pass
356351

357352
c = C()
358353
# trigger caching
359354
for _ in range(2):
360-
self.assertIsSubclass(C, A)
361-
self.assertIsSubclass(C, (A,))
362-
self.assertIsInstance(c, A)
363-
self.assertIsInstance(c, (A,))
355+
self.check_issubclass(C, A)
356+
self.check_isinstance(c, A)
364357

365-
self.assertNotIsSubclass(A, C)
366-
self.assertNotIsSubclass(A, (C,))
367-
self.assertNotIsInstance(a, C)
368-
self.assertNotIsInstance(a, (C,))
358+
self.check_not_issubclass(A, C)
359+
self.check_not_isinstance(a, C)
369360

370361
def test_register_as_class_deco(self):
371362
class A(metaclass=abc_ABCMeta):
@@ -508,15 +499,15 @@ class Parent2(metaclass=abc_ABCMeta):
508499

509500
# trigger caching
510501
for _ in range(2):
511-
self.assertIsInstance(A(), Parent1)
512-
self.assertIsSubclass(A, Parent1)
513-
self.assertNotIsInstance(B(), Parent1)
514-
self.assertNotIsSubclass(B, Parent1)
515-
516-
self.assertIsInstance(A(), Parent2)
517-
self.assertIsSubclass(A, Parent2)
518-
self.assertNotIsInstance(B(), Parent2)
519-
self.assertNotIsSubclass(B, Parent2)
502+
self.check_isinstance(A(), Parent1)
503+
self.check_issubclass(A, Parent1)
504+
self.check_not_isinstance(B(), Parent1)
505+
self.check_not_issubclass(B, Parent1)
506+
507+
self.check_isinstance(A(), Parent2)
508+
self.check_issubclass(A, Parent2)
509+
self.check_not_isinstance(B(), Parent2)
510+
self.check_not_issubclass(B, Parent2)
520511

521512
def test_issubclass_bad_arguments(self):
522513
class A(metaclass=abc_ABCMeta):

Modules/_abc.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,14 @@ _get_impl(PyObject *module, PyObject *self)
181181
return (_abc_data *)impl;
182182
}
183183

184+
/* If class is inherited from ABC, set data to point to internal ABC state of class, and return 1.
185+
If object is not inherited from ABC, return 0.
186+
If error is encountered, return -1.
187+
*/
184188
static int
185-
_get_impl_optional(PyObject *module, PyObject *self, _abc_data **data)
189+
_get_optional_impl(_abcmodule_state *state, PyObject *self, _abc_data **data)
186190
{
187-
_abcmodule_state *state = get_abc_state(module);
191+
assert(data != NULL);
188192
PyObject *impl = NULL;
189193
int res = PyObject_GetOptionalAttr(self, &_Py_ID(_abc_impl), &impl);
190194
if (res <= 0) {
@@ -841,7 +845,7 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
841845
}
842846

843847
_abc_data *scls_impl;
844-
int scls_is_abc = _get_impl_optional(module, scls, &scls_impl);
848+
int scls_is_abc = _get_optional_impl(state, scls, &scls_impl);
845849
if (scls_is_abc < 0) {
846850
goto end;
847851
}
@@ -858,14 +862,16 @@ _abc__abc_subclasscheck_impl(PyObject *module, PyObject *self,
858862

859863
int r = PyObject_IsSubclass(subclass, scls);
860864
Py_DECREF(scls);
865+
if (r < 0) {
866+
Py_XDECREF(scls_impl);
867+
goto end;
868+
}
869+
861870
if (scls_is_abc > 0) {
862871
unset_issubclasscheck_recursive(scls_impl);
863-
Py_DECREF(scls_impl);
864872
}
873+
Py_XDECREF(scls_impl);
865874

866-
if (r < 0) {
867-
goto end;
868-
}
869875
if (r > 0) {
870876
if (!is_issubclasscheck_recursive(impl)) {
871877
if (_add_to_weak_set(impl, &impl->_abc_cache, subclass) < 0) {

0 commit comments

Comments
 (0)