Skip to content

Mock 100% coverage #13045

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
May 1, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 5 additions & 56 deletions Lib/unittest/mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,7 @@ def _get_signature_object(func, as_instance, eat_self):
"""
if isinstance(func, type) and not as_instance:
# If it's a type and should be modelled as a type, use __init__.
try:
func = func.__init__
except AttributeError:
return None
func = func.__init__
# Skip the `self` argument in __init__
eat_self = True
elif not isinstance(func, FunctionTypes):
Expand Down Expand Up @@ -147,8 +144,6 @@ def _set_signature(mock, original, instance=False):
# creates a function with signature (*args, **kwargs) that delegates to a
# mock. It still does signature checking by calling a lambda with the same
# signature as the original.
if not _callable(original):
return

skipfirst = isinstance(original, type)
result = _get_signature_object(original, instance, skipfirst)
Expand All @@ -175,10 +170,6 @@ def checksig(*args, **kwargs):
def _setup_func(funcopy, mock, sig):
funcopy.mock = mock

# can't use isinstance with mocks
if not _is_instance_mock(mock):
return

def assert_called_with(*args, **kwargs):
return mock.assert_called_with(*args, **kwargs)
def assert_called(*args, **kwargs):
Expand Down Expand Up @@ -263,12 +254,6 @@ def __reduce__(self):
_deleted = sentinel.DELETED


def _copy(value):
if type(value) in (dict, list, tuple, set):
return type(value)(value)
return value


_allowed_names = {
'return_value', '_mock_return_value', 'side_effect',
'_mock_side_effect', '_mock_parent', '_mock_new_parent',
Expand Down Expand Up @@ -351,8 +336,6 @@ def _check_and_set_parent(parent, value, name, new_name):
class _MockIter(object):
def __init__(self, obj):
self.obj = iter(obj)
def __iter__(self):
return self
def __next__(self):
return next(self.obj)

Expand Down Expand Up @@ -452,7 +435,7 @@ def _mock_add_spec(self, spec, spec_set, _spec_as_instance=False,
if isinstance(spec, type):
_spec_class = spec
else:
_spec_class = _get_class(spec)
_spec_class = type(spec)
res = _get_signature_object(spec,
_spec_as_instance, _eat_self)
_spec_signature = res and res[1]
Expand Down Expand Up @@ -624,7 +607,7 @@ def _extract_mock_name(self):
dot = '.'
if _name_list == ['()']:
dot = ''
seen = set()

while _parent is not None:
last = _parent

Expand All @@ -635,11 +618,6 @@ def _extract_mock_name(self):

_parent = _parent._mock_new_parent

# use ids here so as not to call __hash__ on the mocks
if id(_parent) in seen:
break
seen.add(id(_parent))

_name_list = list(reversed(_name_list))
_first = last._mock_name or 'mock'
if len(_name_list) > 1:
Expand Down Expand Up @@ -753,8 +731,6 @@ def _format_mock_failure_message(self, args, kwargs):
message = 'expected call not found.\nExpected: %s\nActual: %s'
expected_string = self._format_mock_call_signature(args, kwargs)
call_args = self.call_args
if len(call_args) == 3:
call_args = call_args[1:]
actual_string = self._format_mock_call_signature(*call_args)
return message % (expected_string, actual_string)

Expand Down Expand Up @@ -992,8 +968,6 @@ def _mock_call(_mock_self, *args, **kwargs):
self.call_args = _call
self.call_args_list.append(_call)

seen = set()

# initial stuff for method_calls:
do_method_calls = self._mock_parent is not None
method_call_name = self._mock_name
Expand Down Expand Up @@ -1029,13 +1003,6 @@ def _mock_call(_mock_self, *args, **kwargs):
# follow the parental chain:
_new_parent = _new_parent._mock_new_parent

# check we're not in an infinite loop:
# ( use ids here so as not to call __hash__ on the mocks)
_new_parent_id = id(_new_parent)
if _new_parent_id in seen:
break
seen.add(_new_parent_id)

effect = self.side_effect
if effect is not None:
if _is_exception(effect):
Expand Down Expand Up @@ -1858,12 +1825,7 @@ def _set_return_value(mock, method, name):

return_calulator = _calculate_return_value.get(name)
if return_calulator is not None:
try:
return_value = return_calulator(mock)
except AttributeError:
# XXXX why do we return AttributeError here?
# set it as a side_effect instead?
return_value = AttributeError(name)
return_value = return_calulator(mock)
method.return_value = return_value
return

Expand Down Expand Up @@ -1943,10 +1905,6 @@ def __init__(self, name, parent):
self.name = name
self.parent = parent

def __call__(self, *args, **kwargs):
m = self.create_mock()
return m(*args, **kwargs)

def create_mock(self):
entry = self.name
parent = self.parent
Expand Down Expand Up @@ -2330,19 +2288,10 @@ def _must_skip(spec, entry, is_type):
else:
return False

# shouldn't get here unless function is a dynamically provided attribute
# XXXX untested behaviour
# function is a dynamically provided attribute
return is_type


def _get_class(obj):
try:
return obj.__class__
except AttributeError:
# it is possible for objects to have no __class__
return type(obj)


class _SpecState(object):

def __init__(self, spec, spec_set=False, parent=None,
Expand Down
3 changes: 1 addition & 2 deletions Lib/unittest/test/testmock/support.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ def is_instance(obj, klass):
class SomeClass(object):
class_attribute = None

def wibble(self):
pass
def wibble(self): pass


class X(object):
Expand Down
3 changes: 1 addition & 2 deletions Lib/unittest/test/testmock/testcallable.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,7 @@ def test_patch_spec_set_instance(self):

def test_patch_spec_callable_class(self):
class CallableX(X):
def __call__(self):
pass
def __call__(self): pass

class Sub(CallableX):
pass
Expand Down
Loading