From 6b18c719a6be167dee6b43686c28fa98db25ec3e Mon Sep 17 00:00:00 2001 From: Andrew Dunai Date: Tue, 4 Dec 2018 11:08:45 +0200 Subject: [PATCH] bpo-35357: Add _mock_ prefix to name/parent/from_kall attributes of _Call/_MagicProxy. (GH-10873) Fix minor typo in test function name. (cherry picked from commit e63e617ebbe481c498bdf037a62e09f4f9f3963f) Co-authored-by: Andrew Dunai --- Lib/unittest/mock.py | 28 +++++++++---------- Lib/unittest/test/testmock/testcallable.py | 2 +- Lib/unittest/test/testmock/testmock.py | 16 ++++++++++- .../2018-12-03-21-20-24.bpo-35357.rhhoiC.rst | 4 +++ 4 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2018-12-03-21-20-24.bpo-35357.rhhoiC.rst diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index 69a08ece919b3f..0a6535d0fc4415 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -2016,9 +2016,9 @@ def __new__(cls, value=(), name='', parent=None, two=False, def __init__(self, value=(), name=None, parent=None, two=False, from_kall=True): - self.name = name - self.parent = parent - self.from_kall = from_kall + self._mock_name = name + self._mock_parent = parent + self._mock_from_kall = from_kall def __eq__(self, other): @@ -2035,8 +2035,8 @@ def __eq__(self, other): else: self_name, self_args, self_kwargs = self - if (getattr(self, 'parent', None) and getattr(other, 'parent', None) - and self.parent != other.parent): + if (getattr(self, '_mock_parent', None) and getattr(other, '_mock_parent', None) + and self._mock_parent != other._mock_parent): return False other_name = '' @@ -2080,17 +2080,17 @@ def __eq__(self, other): def __call__(self, *args, **kwargs): - if self.name is None: + if self._mock_name is None: return _Call(('', args, kwargs), name='()') - name = self.name + '()' - return _Call((self.name, args, kwargs), name=name, parent=self) + name = self._mock_name + '()' + return _Call((self._mock_name, args, kwargs), name=name, parent=self) def __getattr__(self, attr): - if self.name is None: + if self._mock_name is None: return _Call(name=attr, from_kall=False) - name = '%s.%s' % (self.name, attr) + name = '%s.%s' % (self._mock_name, attr) return _Call(name=name, parent=self, from_kall=False) @@ -2101,8 +2101,8 @@ def index(self, *args, **kwargs): return self.__getattr__('index')(*args, **kwargs) def __repr__(self): - if not self.from_kall: - name = self.name or 'call' + if not self._mock_from_kall: + name = self._mock_name or 'call' if name.startswith('()'): name = 'call%s' % name return name @@ -2128,9 +2128,9 @@ def call_list(self): vals = [] thing = self while thing is not None: - if thing.from_kall: + if thing._mock_from_kall: vals.append(thing) - thing = thing.parent + thing = thing._mock_parent return _CallList(reversed(vals)) diff --git a/Lib/unittest/test/testmock/testcallable.py b/Lib/unittest/test/testmock/testcallable.py index af1ce7ebbae4da..34474c4c816e0a 100644 --- a/Lib/unittest/test/testmock/testcallable.py +++ b/Lib/unittest/test/testmock/testcallable.py @@ -128,7 +128,7 @@ class Multi(SomeClass, Sub): result.foo.assert_called_once_with(3, 2, 1) - def test_create_autopsec(self): + def test_create_autospec(self): mock = create_autospec(X) instance = mock() self.assertRaises(TypeError, instance) diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py index fa2ac34fc3d108..401a01277b0603 100644 --- a/Lib/unittest/test/testmock/testmock.py +++ b/Lib/unittest/test/testmock/testmock.py @@ -8,7 +8,7 @@ from unittest.mock import ( call, DEFAULT, patch, sentinel, MagicMock, Mock, NonCallableMock, - NonCallableMagicMock, _CallList, + NonCallableMagicMock, _Call, _CallList, create_autospec ) @@ -1635,6 +1635,20 @@ def test_class_assignable(self): self.assertIsInstance(mock, int) mock.foo + def test_name_attribute_of_call(self): + # bpo-35357: _Call should not disclose any attributes whose names + # may clash with popular ones (such as ".name") + self.assertIsNotNone(call.name) + self.assertEqual(type(call.name), _Call) + self.assertEqual(type(call.name().name), _Call) + + def test_parent_attribute_of_call(self): + # bpo-35357: _Call should not disclose any attributes whose names + # may clash with popular ones (such as ".parent") + self.assertIsNotNone(call.parent) + self.assertEqual(type(call.parent), _Call) + self.assertEqual(type(call.parent().parent), _Call) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-12-03-21-20-24.bpo-35357.rhhoiC.rst b/Misc/NEWS.d/next/Core and Builtins/2018-12-03-21-20-24.bpo-35357.rhhoiC.rst new file mode 100644 index 00000000000000..1dade5baf4e013 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2018-12-03-21-20-24.bpo-35357.rhhoiC.rst @@ -0,0 +1,4 @@ +Internal attributes' names of unittest.mock._Call and +unittest.mock.MagicProxy (name, parent & from_kall) are now prefixed with +_mock_ in order to prevent clashes with widely used object attributes. +Fixed minor typo in test function name.