gh-119600: mock: do not access attributes of original when new_callable is set (#119601)

In order to patch flask.g e.g. as in #84982, that
proxies getattr must not be invoked. For that,
mock must not try to read from the original
object. In some cases that is unavoidable, e.g.
when doing autospec. However, patch("flask.g",
new_callable=MagicMock) should be entirely safe.
This commit is contained in:
Robert Collins 2024-06-11 07:41:12 +02:00 committed by GitHub
parent 6efe346069
commit 422c4fc855
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 29 additions and 5 deletions

View File

@ -14,3 +14,14 @@ class SomeClass(object):
class X(object):
pass
# A standin for weurkzeug.local.LocalProxy - issue 119600
def _inaccessible(*args, **kwargs):
raise AttributeError
class OpaqueProxy:
__getattribute__ = _inaccessible
g = OpaqueProxy()

View File

@ -2045,6 +2045,13 @@ class PatchTest(unittest.TestCase):
with self.assertRaises(TypeError):
test()
def test_patch_proxy_object(self):
@patch("test.test_unittest.testmock.support.g", new_callable=MagicMock())
def test(_):
pass
test()
if __name__ == '__main__':
unittest.main()

View File

@ -1508,13 +1508,12 @@ class _patch(object):
if isinstance(original, type):
# If we're patching out a class and there is a spec
inherit = True
if spec is None and _is_async_obj(original):
Klass = AsyncMock
else:
Klass = MagicMock
_kwargs = {}
# Determine the Klass to use
if new_callable is not None:
Klass = new_callable
elif spec is None and _is_async_obj(original):
Klass = AsyncMock
elif spec is not None or spec_set is not None:
this_spec = spec
if spec_set is not None:
@ -1527,7 +1526,12 @@ class _patch(object):
Klass = AsyncMock
elif not_callable:
Klass = NonCallableMagicMock
else:
Klass = MagicMock
else:
Klass = MagicMock
_kwargs = {}
if spec is not None:
_kwargs['spec'] = spec
if spec_set is not None:

View File

@ -0,0 +1,2 @@
Fix :func:`unittest.mock.patch` to not read attributes of the target when
``new_callable`` is set. Patch by Robert Collins.