[Python-checkins] Don't report deleted attributes in __dir__ (GH#10148)
Chris Withers
webhook-mailer at python.org
Tue Apr 30 14:56:50 EDT 2019
https://github.com/python/cpython/commit/0df635c7f8aa69e56a092bd4f142f0f164741ab2
commit: 0df635c7f8aa69e56a092bd4f142f0f164741ab2
branch: master
author: Mario Corchero <mariocj89 at gmail.com>
committer: Chris Withers <chris at withers.org>
date: 2019-04-30T19:56:36+01:00
summary:
Don't report deleted attributes in __dir__ (GH#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).
files:
A Misc/NEWS.d/next/Library/2018-10-27-11-54-12.bpo-35082.HDj1nr.rst
M Lib/unittest/mock.py
M Lib/unittest/test/testmock/testmock.py
diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py
index 1636073ff009..997af7172566 100644
--- a/Lib/unittest/mock.py
+++ b/Lib/unittest/mock.py
@@ -684,12 +684,14 @@ def __dir__(self):
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 bdaebbe66b74..0e7e4a1d8c93 100644
--- a/Lib/unittest/test/testmock/testmock.py
+++ b/Lib/unittest/test/testmock/testmock.py
@@ -885,6 +885,15 @@ def test_filter_dir(self):
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')
diff --git a/Misc/NEWS.d/next/Library/2018-10-27-11-54-12.bpo-35082.HDj1nr.rst b/Misc/NEWS.d/next/Library/2018-10-27-11-54-12.bpo-35082.HDj1nr.rst
new file mode 100644
index 000000000000..45a0729506e3
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-10-27-11-54-12.bpo-35082.HDj1nr.rst
@@ -0,0 +1,2 @@
+Don't return deleted attributes when calling dir on a
+:class:`unittest.mock.Mock`.
More information about the Python-checkins
mailing list