bpo-45156: fixes inifite loop on mock.seal() by sobolevn · Pull Request #28300 · python/cpython (original) (raw)

Expand Up

@@ -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()