From 1c545e5fc54391a4c2ca8e6e3747d8f7baf8671c Mon Sep 17 00:00:00 2001 From: sobolevn Date: Fri, 3 Dec 2021 11:20:25 +0300 Subject: [PATCH 1/4] bpo-45756: do not execute `@property` descrs while creating mock autospecs --- Lib/unittest/mock.py | 4 +++ Lib/unittest/test/testmock/testmock.py | 30 +++++++++++++++++++ .../2021-12-03-11-19-44.bpo-45756.nSDJWj.rst | 2 ++ 3 files changed, 36 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 9f99a5aa5bcdcb..652a80cdd1a030 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -494,6 +494,10 @@ def _mock_add_spec(self, spec, spec_set, _spec_as_instance=False, _spec_asyncs = [] for attr in dir(spec): + if isinstance(inspect.getattr_static(spec, attr, None), property): + # We don't want to execute `@property` decorators with `getattr`. + # It might affect user's code in unknown way. + continue if iscoroutinefunction(getattr(spec, attr, None)): _spec_asyncs.append(attr) diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py index fdba543b53511d..d76d83f1717773 100644 --- a/Lib/unittest/test/testmock/testmock.py +++ b/Lib/unittest/test/testmock/testmock.py @@ -896,6 +896,36 @@ def set_attr(): self.assertRaises(AttributeError, set_attr) + def test_class_with_property(self): + class X: + @property + def some(self): + raise ValueError('Should not be raised') + + mock = Mock(spec=X) + self.assertIsInstance(mock, X) + + mock = Mock(spec=X()) + self.assertIsInstance(mock, X) + + + def test_class_with_settable_property(self): + class X: + @property + def some(self): + raise ValueError('Should not be raised') + + @some.setter + def some(self, value): + raise TypeError('Should not be raised') + + mock = Mock(spec=X) + self.assertIsInstance(mock, X) + + mock = Mock(spec=X()) + self.assertIsInstance(mock, X) + + def test_copy(self): current = sys.getrecursionlimit() self.addCleanup(sys.setrecursionlimit, current) diff --git a/Misc/NEWS.d/next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst b/Misc/NEWS.d/next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst new file mode 100644 index 00000000000000..ca8a96e7d0d0dc --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst @@ -0,0 +1,2 @@ +We no longer execute ``@property`` descriptors while creating autospecs in +``mock.py``. This was not safe and could affect user's code in unknown way. From 49a5451fdd9082433e2fc12fb782174720cf10d2 Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Wed, 12 Jan 2022 11:55:24 +0300 Subject: [PATCH 2/4] Update Lib/unittest/mock.py Co-authored-by: Kumar Aditya <59607654+kumaraditya303@users.noreply.github.com> --- Lib/unittest/mock.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 652a80cdd1a030..ff5ae392ccf6da 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -495,7 +495,7 @@ def _mock_add_spec(self, spec, spec_set, _spec_as_instance=False, for attr in dir(spec): if isinstance(inspect.getattr_static(spec, attr, None), property): - # We don't want to execute `@property` decorators with `getattr`. + # Don't execute `property` decorators with `getattr`. # It might affect user's code in unknown way. continue if iscoroutinefunction(getattr(spec, attr, None)): From 345c3f419f88d7dd1195b630e055d17c45d3371d Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Wed, 12 Jan 2022 11:56:29 +0300 Subject: [PATCH 3/4] Update 2021-12-03-11-19-44.bpo-45756.nSDJWj.rst --- .../next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst b/Misc/NEWS.d/next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst index ca8a96e7d0d0dc..beb10985a565e5 100644 --- a/Misc/NEWS.d/next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst +++ b/Misc/NEWS.d/next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst @@ -1,2 +1,2 @@ -We no longer execute ``@property`` descriptors while creating autospecs in -``mock.py``. This was not safe and could affect user's code in unknown way. +Do not execute ``@property`` descriptors while creating autospecs in :mod:`unittest.mock`. +This was not safe and could affect users' code in unknown way. From 78cbfc63796601499a06dce97d072b4c36c3fb0b Mon Sep 17 00:00:00 2001 From: Nikita Sobolev Date: Wed, 12 Jan 2022 12:08:41 +0300 Subject: [PATCH 4/4] Update 2021-12-03-11-19-44.bpo-45756.nSDJWj.rst --- .../next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst b/Misc/NEWS.d/next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst index beb10985a565e5..36e2ca4b56c150 100644 --- a/Misc/NEWS.d/next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst +++ b/Misc/NEWS.d/next/Library/2021-12-03-11-19-44.bpo-45756.nSDJWj.rst @@ -1,2 +1,2 @@ -Do not execute ``@property`` descriptors while creating autospecs in :mod:`unittest.mock`. +Do not execute ``@property`` descriptors while creating autospecs in :mod:`unittest.mock`. This was not safe and could affect users' code in unknown way.