Skip to content

Commit ed81f34

Browse files
committed
Minor refactoring for comprehensibility reasons.
1 parent df2bfaf commit ed81f34

File tree

1 file changed

+29
-17
lines changed

1 file changed

+29
-17
lines changed

umock.py

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,21 @@
3535
is_micropython = "micropython" in sys.version.lower()
3636

3737

38-
#: Attributes of the Mock class that should be handled as "normal" attributes
39-
#: rather than treated as mocked attributes.
40-
_RESERVED_MOCK_ATTRIBUTES = ("side_effect", "return_value")
38+
#: Attributes of the Mock/AsyncMock classes that should be handled as "normal"
39+
#: attributes rather than treated as mocked attributes.
40+
_RESERVED_ATTRIBUTES = ("side_effect", "return_value")
41+
_RESERVED_MOCK_ATTRIBUTES = _RESERVED_ATTRIBUTES + (
42+
"call_count",
43+
"called",
44+
"call_args",
45+
"call_args_list",
46+
)
47+
_RESERVED_ASYNCMOCK_ATTRIBUTES = _RESERVED_ATTRIBUTES + (
48+
"await_count",
49+
"awaited",
50+
"await_args",
51+
"await_args_list",
52+
)
4153

4254

4355
def is_awaitable(obj):
@@ -151,6 +163,9 @@ class or instance) that acts as the specification for the mock
151163
self.side_effect = iter(side_effect)
152164
else:
153165
self.side_effect = side_effect
166+
# The _mock_value is used to ensure the same mock object is returned if
167+
# no return_value or side_effect is specified.
168+
self._mock_value = None
154169
self.reset_mock()
155170
for key, value in kwargs.items():
156171
setattr(self, key, value)
@@ -296,12 +311,9 @@ def __call__(self, *args, **kwargs):
296311
return self.return_value
297312
else:
298313
# Return a mock object (ensuring it's the same one each time).
299-
if hasattr(self, "_mock_value"):
300-
return self._mock_value
301-
else:
302-
new_mock = Mock()
303-
self._mock_value = new_mock
304-
return new_mock
314+
if not self._mock_value:
315+
self._mock_value = Mock()
316+
return self._mock_value
305317

306318
def __getattr__(self, name):
307319
"""
@@ -412,6 +424,9 @@ class or instance) that acts as the specification for the mock
412424
self.side_effect = iter(side_effect)
413425
else:
414426
self.side_effect = side_effect
427+
# The _mock_value is used to ensure the same mock object is returned if
428+
# no return_value or side_effect is specified.
429+
self._mock_value = None
415430
self.reset_mock()
416431
for key, value in kwargs.items():
417432
setattr(self, key, value)
@@ -560,12 +575,9 @@ async def __call__(self, *args, **kwargs):
560575
return self.return_value
561576
else:
562577
# Return a mock object (ensuring it's the same one each time).
563-
if hasattr(self, "_mock_value"):
564-
return self._mock_value
565-
else:
566-
new_mock = AsyncMock()
567-
self._mock_value = new_mock
568-
return new_mock
578+
if not self._mock_value:
579+
self._mock_value = AsyncMock()
580+
return self._mock_value
569581

570582
def __getattr__(self, name):
571583
"""
@@ -577,7 +589,7 @@ def __getattr__(self, name):
577589
instance has a `_spec` attribute that does not contain the attribute
578590
name.
579591
"""
580-
if name.startswith("_") or name in _RESERVED_MOCK_ATTRIBUTES:
592+
if name.startswith("_") or name in _RESERVED_ASYNCMOCK_ATTRIBUTES:
581593
# Special attributes are handled as normal attributes.
582594
return self.__dict__.get(name)
583595
elif name in self.__dict__:
@@ -589,7 +601,7 @@ def __getattr__(self, name):
589601
f"AsyncMock object has no attribute '{name}'."
590602
)
591603
else:
592-
# Otherwise, create a new mock object for the attribute.
604+
# Otherwise, create a new async mock object for the attribute.
593605
new_mock = AsyncMock()
594606
setattr(self, name, new_mock)
595607
return new_mock

0 commit comments

Comments
 (0)