[Python-checkins] bpo-35357: Add _mock_ prefix to name/parent/from_kall attributes of _Call/_MagicProxy. (GH-10873)

Chris Withers webhook-mailer at python.org
Tue Dec 4 04:34:51 EST 2018


https://github.com/python/cpython/commit/70ca3fce9fe2bdd7bf97d5fe1299cfa5e32b3ad4
commit: 70ca3fce9fe2bdd7bf97d5fe1299cfa5e32b3ad4
branch: 3.6
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Chris Withers <chris at withers.org>
date: 2018-12-04T09:34:48Z
summary:

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 <andunai at gmail.com>

files:
A Misc/NEWS.d/next/Core and Builtins/2018-12-03-21-20-24.bpo-35357.rhhoiC.rst
M Lib/unittest/mock.py
M Lib/unittest/test/testmock/testcallable.py
M Lib/unittest/test/testmock/testmock.py

diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index a8f28cefc7a9..707ef0b734d8 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -2004,9 +2004,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):
@@ -2023,8 +2023,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 = ''
@@ -2068,17 +2068,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)
 
 
@@ -2089,8 +2089,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
@@ -2116,9 +2116,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 af1ce7ebbae4..34474c4c816e 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 c5c8f5ccbd81..14b1ecc84b33 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
 )
 
@@ -1625,6 +1625,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 000000000000..1dade5baf4e0
--- /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.



More information about the Python-checkins mailing list