From 5563d4459579ee45c8a2869fa81f274b6269e27f Mon Sep 17 00:00:00 2001 From: Aaron Gallagher Date: Fri, 10 Feb 2017 14:57:03 -0800 Subject: [PATCH 1/3] Fix autospec's behavior on method-bound builtins. Cython will, in the right circumstances, offer a MethodType instance where im_func is a builtin function. Any instance of MethodType is automatically assumed to be a python-defined function (more specifically, a function that has an inspectable signature), but _set_signature was still conservative in its assumptions. As a result _set_signature would return early with None instead of a mock since the im_func had no inspectable signature. This causes problems deeper inside mock, as _set_signature is assumed to _always_ return a mock, and nothing checked its return value. In similar corner cases, autospec will simply not check the spec of the function, so _set_signature is amended to now return early with the original, not-wrapped mock object. --- Lib/unittest/mock.py | 2 +- Lib/unittest/test/testmock/testhelpers.py | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 6989dc792eb763..94e344234878d6 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -155,7 +155,7 @@ def _set_signature(mock, original, instance=False): skipfirst = isinstance(original, type) result = _get_signature_object(original, instance, skipfirst) if result is None: - return + return mock func, sig = result def checksig(*args, **kwargs): sig.bind(*args, **kwargs) diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/unittest/test/testmock/testhelpers.py index d2202a7b4132e9..7a6fabb87dd218 100644 --- a/Lib/unittest/test/testmock/testhelpers.py +++ b/Lib/unittest/test/testmock/testhelpers.py @@ -1,3 +1,5 @@ +import time +import types import unittest from unittest.mock import ( @@ -883,6 +885,19 @@ def test_args_list_contains_call_list(self): self.assertNotIn([call('fish')], mock.call_args_list) + def test_autospec_on_bound_builtin_function(self): + meth = types.MethodType(time.ctime, time.time()) + self.assertIsInstance(meth(), str) + mocked = create_autospec(meth) + + # no signature, so no spec to check against + mocked() + mocked.assert_called_once_with() + mocked.reset_mock() + mocked(4, 5, 6) + mocked.assert_called_once_with(4, 5, 6) + + def test_call_list_str(self): mock = Mock() mock(1, 2) From 989e99a0133b1ebccc61b11a5680ebef318fdfc5 Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Thu, 20 Jul 2017 02:31:27 +0300 Subject: [PATCH 2/3] Add blurb entry --- .../next/Library/2017-07-20-02-29-49.bpo-29403.3RinCV.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2017-07-20-02-29-49.bpo-29403.3RinCV.rst diff --git a/Misc/NEWS.d/next/Library/2017-07-20-02-29-49.bpo-29403.3RinCV.rst b/Misc/NEWS.d/next/Library/2017-07-20-02-29-49.bpo-29403.3RinCV.rst new file mode 100644 index 00000000000000..95bcd1007de05a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-07-20-02-29-49.bpo-29403.3RinCV.rst @@ -0,0 +1,2 @@ +Fix ``unittest.mock``'s autospec to not fail on method-bound builtin +functions. Patch by Aaron Gallagher. From 4f4ed0209b42706737c01f84aa435c702f7884af Mon Sep 17 00:00:00 2001 From: Berker Peksag Date: Thu, 20 Jul 2017 02:38:59 +0300 Subject: [PATCH 3/3] Move test to correct test case --- Lib/unittest/test/testmock/testhelpers.py | 26 +++++++++++------------ 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/unittest/test/testmock/testhelpers.py index 7a6fabb87dd218..7919482ae99c7f 100644 --- a/Lib/unittest/test/testmock/testhelpers.py +++ b/Lib/unittest/test/testmock/testhelpers.py @@ -858,6 +858,19 @@ def check_data_descriptor(mock_attr): check_data_descriptor(foo.desc) + def test_autospec_on_bound_builtin_function(self): + meth = types.MethodType(time.ctime, time.time()) + self.assertIsInstance(meth(), str) + mocked = create_autospec(meth) + + # no signature, so no spec to check against + mocked() + mocked.assert_called_once_with() + mocked.reset_mock() + mocked(4, 5, 6) + mocked.assert_called_once_with(4, 5, 6) + + class TestCallList(unittest.TestCase): def test_args_list_contains_call_list(self): @@ -885,19 +898,6 @@ def test_args_list_contains_call_list(self): self.assertNotIn([call('fish')], mock.call_args_list) - def test_autospec_on_bound_builtin_function(self): - meth = types.MethodType(time.ctime, time.time()) - self.assertIsInstance(meth(), str) - mocked = create_autospec(meth) - - # no signature, so no spec to check against - mocked() - mocked.assert_called_once_with() - mocked.reset_mock() - mocked(4, 5, 6) - mocked.assert_called_once_with(4, 5, 6) - - def test_call_list_str(self): mock = Mock() mock(1, 2) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy