bpo-45156: Fixes inifite loop on unittest.mock.seal() (GH-28300) (GH-28326)

Fixes infinite loop on unittest.mock.seal() of mocks created by
unittest.create_autospec().

Co-authored-by: Dong-hee Na <donghee.na92@gmail.com>
(cherry picked from commit 7f60c9e1c6)

Co-authored-by: Nikita Sobolev <mail@sobolevn.me>
This commit is contained in:
Miss Islington (bot) 2021-09-14 04:00:16 -07:00 committed by GitHub
parent a390bb6d66
commit fd74d2680e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 6 deletions

View file

@ -171,6 +171,67 @@ def test_call_chain_is_maintained(self):
m.test1().test2.test3().test4()
self.assertIn("mock.test1().test2.test3().test4", str(cm.exception))
def test_seal_with_autospec(self):
# https://bugs.python.org/issue45156
class Foo:
foo = 0
def bar1(self):
return 1
def bar2(self):
return 2
class Baz:
baz = 3
def ban(self):
return 4
for spec_set in (True, False):
with self.subTest(spec_set=spec_set):
foo = mock.create_autospec(Foo, spec_set=spec_set)
foo.bar1.return_value = 'a'
foo.Baz.ban.return_value = 'b'
mock.seal(foo)
self.assertIsInstance(foo.foo, mock.NonCallableMagicMock)
self.assertIsInstance(foo.bar1, mock.MagicMock)
self.assertIsInstance(foo.bar2, mock.MagicMock)
self.assertIsInstance(foo.Baz, mock.MagicMock)
self.assertIsInstance(foo.Baz.baz, mock.NonCallableMagicMock)
self.assertIsInstance(foo.Baz.ban, mock.MagicMock)
self.assertEqual(foo.bar1(), 'a')
foo.bar1.return_value = 'new_a'
self.assertEqual(foo.bar1(), 'new_a')
self.assertEqual(foo.Baz.ban(), 'b')
foo.Baz.ban.return_value = 'new_b'
self.assertEqual(foo.Baz.ban(), 'new_b')
with self.assertRaises(TypeError):
foo.foo()
with self.assertRaises(AttributeError):
foo.bar = 1
with self.assertRaises(AttributeError):
foo.bar2()
foo.bar2.return_value = 'bar2'
self.assertEqual(foo.bar2(), 'bar2')
with self.assertRaises(AttributeError):
foo.missing_attr
with self.assertRaises(AttributeError):
foo.missing_attr = 1
with self.assertRaises(AttributeError):
foo.missing_method()
with self.assertRaises(TypeError):
foo.Baz.baz()
with self.assertRaises(AttributeError):
foo.Baz.missing_attr
with self.assertRaises(AttributeError):
foo.Baz.missing_attr = 1
with self.assertRaises(AttributeError):
foo.Baz.missing_method()
if __name__ == "__main__":
unittest.main()