Skip to content

Commit 0df635c

Browse files
mariocj89cjw296
authored andcommitted
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).
1 parent d537ab0 commit 0df635c

File tree

3 files changed

+15
-2
lines changed

3 files changed

+15
-2
lines changed

Lib/unittest/mock.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -684,12 +684,14 @@ def __dir__(self):
684684
extras = self._mock_methods or []
685685
from_type = dir(type(self))
686686
from_dict = list(self.__dict__)
687+
from_child_mocks = [
688+
m_name for m_name, m_value in self._mock_children.items()
689+
if m_value is not _deleted]
687690

688691
from_type = [e for e in from_type if not e.startswith('_')]
689692
from_dict = [e for e in from_dict if not e.startswith('_') or
690693
_is_magic(e)]
691-
return sorted(set(extras + from_type + from_dict +
692-
list(self._mock_children)))
694+
return sorted(set(extras + from_type + from_dict + from_child_mocks))
693695

694696

695697
def __setattr__(self, name, value):

Lib/unittest/test/testmock/testmock.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,15 @@ def test_filter_dir(self):
885885
patcher.stop()
886886

887887

888+
def test_dir_does_not_include_deleted_attributes(self):
889+
mock = Mock()
890+
mock.child.return_value = 1
891+
892+
self.assertIn('child', dir(mock))
893+
del mock.child
894+
self.assertNotIn('child', dir(mock))
895+
896+
888897
def test_configure_mock(self):
889898
mock = Mock(foo='bar')
890899
self.assertEqual(mock.foo, 'bar')
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Don't return deleted attributes when calling dir on a
2+
:class:`unittest.mock.Mock`.

0 commit comments

Comments
 (0)