From d7d4e0b0b65101247275179dd88cf8a74b71f0b0 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sun, 23 Jan 2022 17:38:45 +0000 Subject: [PATCH 1/3] bpo-41403: Improve error message for invalid mock target --- Lib/unittest/mock.py | 2 +- Lib/unittest/test/testmock/testpatch.py | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 9f99a5aa5bcdcb..517a9fe936255d 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1589,7 +1589,7 @@ def stop(self): def _get_target(target): try: target, attribute = target.rsplit('.', 1) - except (TypeError, ValueError): + except (TypeError, ValueError, AttributeError): raise TypeError("Need a valid target to patch. You supplied: %r" % (target,)) return partial(pkgutil.resolve_name, target), attribute diff --git a/Lib/unittest/test/testmock/testpatch.py b/Lib/unittest/test/testmock/testpatch.py index 233a5afffaed4a..8ab63a1317d3df 100644 --- a/Lib/unittest/test/testmock/testpatch.py +++ b/Lib/unittest/test/testmock/testpatch.py @@ -1933,8 +1933,13 @@ def test(mock): def test_invalid_target(self): - with self.assertRaises(TypeError): - patch('') + class Foo: + pass + + for target in ['', 12, Foo()]: + with self.subTest(target=target): + with self.assertRaises(TypeError): + patch(target) def test_cant_set_kwargs_when_passing_a_mock(self): From 6460ea15430875fb518aca966c2700da13fd4d4a Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sun, 23 Jan 2022 18:05:11 +0000 Subject: [PATCH 2/3] add news --- .../next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst diff --git a/Misc/NEWS.d/next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst b/Misc/NEWS.d/next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst new file mode 100644 index 00000000000000..ede159b25641f3 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-01-23-18-04-45.bpo-41403.SgoHqV.rst @@ -0,0 +1,3 @@ +Make :meth:`mock.patch` raise a :exc:`TypeError` with a relevant error +message on invalid arg. Previously it allowed a cryptic +:exc:`AttributeError` to escape. From 461e59e4f4ac839c2bbdecf478cca1fec93068a9 Mon Sep 17 00:00:00 2001 From: Irit Katriel Date: Sun, 23 Jan 2022 18:12:40 +0000 Subject: [PATCH 3/3] use format string --- Lib/unittest/mock.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 517a9fe936255d..9137501930000c 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -1590,8 +1590,8 @@ def _get_target(target): try: target, attribute = target.rsplit('.', 1) except (TypeError, ValueError, AttributeError): - raise TypeError("Need a valid target to patch. You supplied: %r" % - (target,)) + raise TypeError( + f"Need a valid target to patch. You supplied: {target!r}") return partial(pkgutil.resolve_name, target), attribute