summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2019-09-12 03:52:49 -0700
committerMichael Foord <voidspace@users.noreply.github.com>2019-09-12 12:52:49 +0200
commitdb0d8a5b2c803d30d9df436e00b6627ec8e09a13 (patch)
tree4eb7a4ddb5ed695da5bb71a643ed20531fc824e5
parentf60fd95dcc189ace8c0a2177a394b9cc20389a1e (diff)
downloadcpython-git-db0d8a5b2c803d30d9df436e00b6627ec8e09a13.tar.gz
bpo-37972: unittest.mock._Call now passes on __getitem__ to the __getattr__ chaining so that call() can be subscriptable (GH-15565) (GH-15965)
* bpo-37972: unittest.mock._Call now passes on __getitem__ to the __getattr__ chaining so that call() can be subscriptable * 📜🤖 Added by blurb_it. * Update 2019-08-28-21-40-12.bpo-37972.kP-n4L.rst added name of the contributor * bpo-37972: made all dunder methods chainable for _Call * bpo-37972: delegate only attributes of tuple instead to __getattr__ (cherry picked from commit 72c359912d36705a94fca8b63d80451905a14ae4) Co-authored-by: blhsing <github@ydooby.com>
-rw-r--r--Lib/unittest/mock.py6
-rw-r--r--Lib/unittest/test/testmock/testhelpers.py20
-rw-r--r--Misc/NEWS.d/next/Library/2019-08-28-21-40-12.bpo-37972.kP-n4L.rst5
3 files changed, 31 insertions, 0 deletions
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 7bfbfc92ee..cbc4d76b85 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -2464,6 +2464,12 @@ class _Call(tuple):
return _Call(name=name, parent=self, from_kall=False)
+ def __getattribute__(self, attr):
+ if attr in tuple.__dict__:
+ raise AttributeError
+ return tuple.__getattribute__(self, attr)
+
+
def count(self, /, *args, **kwargs):
return self.__getattr__('count')(*args, **kwargs)
diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/unittest/test/testmock/testhelpers.py
index 301bca430c..f3c7acb98c 100644
--- a/Lib/unittest/test/testmock/testhelpers.py
+++ b/Lib/unittest/test/testmock/testhelpers.py
@@ -334,6 +334,26 @@ class CallTest(unittest.TestCase):
self.assertEqual(_Call((('bar', 'barz'),),)[0], '')
self.assertEqual(_Call((('bar', 'barz'), {'hello': 'world'}),)[0], '')
+ def test_dunder_call(self):
+ m = MagicMock()
+ m().foo()['bar']()
+ self.assertEqual(
+ m.mock_calls,
+ [call(), call().foo(), call().foo().__getitem__('bar'), call().foo().__getitem__()()]
+ )
+ m = MagicMock()
+ m().foo()['bar'] = 1
+ self.assertEqual(
+ m.mock_calls,
+ [call(), call().foo(), call().foo().__setitem__('bar', 1)]
+ )
+ m = MagicMock()
+ iter(m().foo())
+ self.assertEqual(
+ m.mock_calls,
+ [call(), call().foo(), call().foo().__iter__()]
+ )
+
class SpecSignatureTest(unittest.TestCase):
diff --git a/Misc/NEWS.d/next/Library/2019-08-28-21-40-12.bpo-37972.kP-n4L.rst b/Misc/NEWS.d/next/Library/2019-08-28-21-40-12.bpo-37972.kP-n4L.rst
new file mode 100644
index 0000000000..73d9ef7776
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2019-08-28-21-40-12.bpo-37972.kP-n4L.rst
@@ -0,0 +1,5 @@
+Subscripts to the `unittest.mock.call` objects now receive the same chaining mechanism as any other custom attributes, so that the following usage no longer raises a `TypeError`:
+
+ call().foo().__getitem__('bar')
+
+Patch by blhsing