8000 fixed potential bug with deletion of implementation · python/cpython@114028e · GitHub
[go: up one dir, main page]

Skip to content

Commit 114028e

Browse files
author
ben avrahami
committed
fixed potential bug with deletion of implementation
1 parent 740183f commit 114028e

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

Lib/abc.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,13 @@ class after this function is called.
151151
" subclassing")
152152

153153
abstracts = set()
154-
# Check the existing abstract methods, keep only the ones that are
155-
# still abstract.
156-
for name in cls.__abstractmethods__:
157-
value = getattr(cls, name, None)
158-
if getattr(value, "__isabstractmethod__", False):
159-
abstracts.add(name)
154+
# Check the existing abstract methods of the parents, keep only the ones
155+
# that are not implemented.
156+
for scls in cls.__bases__:
157+
for name in getattr(scls, '__abstractmethods__', ()):
158+
value = getattr(cls, name, None)
159+
if getattr(value, "__isabstractmethod__", False):
160+
abstracts.add(name)
160161
# Also add any other newly added abstract methods.
161162
for name, value in cls.__dict__.items():
162163
if getattr(value, "__isabstractmethod__", False):

Lib/test/test_abc.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,8 +516,8 @@ def updated_foo(self):
516516

517517
A.foo = updated_foo
518518
abc.update_abstractmethods(A)
519-
msg = "class A with abstract methods bar, foo"
520519
self.assertEqual(A.__abstractmethods__, {'foo', 'bar'})
520+
msg = "class A with abstract methods bar, foo"
521521
self.assertRaisesRegex(TypeError, msg, A)
522522

523523
def test_update_implementation(self):
@@ -571,6 +571,26 @@ def updated_foo(self):
571571
A()
572572
self.assertFalse(hasattr(A, '__abstractmethods__'))
573573

574+
def test_update_del_implementation(self):
575+
class A(metaclass=abc_ABCMeta):
576+
@abc.abstractmethod
577+
def foo(self):
578+
pass
579+
580+
class B(A):
581+
def foo(self):
582+
pass
583+
584+
B()
585+
586+
del B.foo
587+
588+
abc.update_abstractmethods(B)
589+
590+
msg = "class B with abstract method foo"
591+
self.assertRaisesRegex(TypeError, msg, B)
592+
593+
574594

575595
class TestABCWithInitSubclass(unittest.TestCase):
576596
def test_works_with_init_subclass(self):

0 commit comments

Comments
 (0)
0