summaryrefslogtreecommitdiff
path: root/Lib
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2019-06-06 03:39:30 -0700
committerGitHub <noreply@github.com>2019-06-06 03:39:30 -0700
commit28be388e69c6e88d5c04abcc714db5ec526e4f5e (patch)
tree8effe3d039ccb38af0ba67be056a16ea65996825 /Lib
parentf62a372928fbf6a2ba722f12f069b75ca6ad16fb (diff)
downloadcpython-git-28be388e69c6e88d5c04abcc714db5ec526e4f5e.tar.gz
Don't report deleted attributes in __dir__ (GHGH-10148)
When an attribute is deleted from a Mock, a sentinel is added rather than just deleting the attribute. This commit checks for such sentinels when returning the child mocks in the __dir__ method as users won't expect deleted attributes to appear when performing dir(mock). (cherry picked from commit 0df635c7f8aa69e56a092bd4f142f0f164741ab2) Co-authored-by: Mario Corchero <mariocj89@gmail.com>
Diffstat (limited to 'Lib')
-rw-r--r--Lib/unittest/mock.py6
-rw-r--r--Lib/unittest/test/testmock/testmock.py9
2 files changed, 13 insertions, 2 deletions
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 1e577dff2f..569a5146c8 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -684,12 +684,14 @@ class NonCallableMock(Base):
extras = self._mock_methods or []
from_type = dir(type(self))
from_dict = list(self.__dict__)
+ from_child_mocks = [
+ m_name for m_name, m_value in self._mock_children.items()
+ if m_value is not _deleted]
from_type = [e for e in from_type if not e.startswith('_')]
from_dict = [e for e in from_dict if not e.startswith('_') or
_is_magic(e)]
- return sorted(set(extras + from_type + from_dict +
- list(self._mock_children)))
+ return sorted(set(extras + from_type + from_dict + from_child_mocks))
def __setattr__(self, name, value):
diff --git a/Lib/unittest/test/testmock/testmock.py b/Lib/unittest/test/testmock/testmock.py
index 76a648e57f..f92b921fe6 100644
--- a/Lib/unittest/test/testmock/testmock.py
+++ b/Lib/unittest/test/testmock/testmock.py
@@ -870,6 +870,15 @@ class MockTest(unittest.TestCase):
patcher.stop()
+ def test_dir_does_not_include_deleted_attributes(self):
+ mock = Mock()
+ mock.child.return_value = 1
+
+ self.assertIn('child', dir(mock))
+ del mock.child
+ self.assertNotIn('child', dir(mock))
+
+
def test_configure_mock(self):
mock = Mock(foo='bar')
self.assertEqual(mock.foo, 'bar')