# Path: mockito/mockito.py
# def when2(fn, *args, **kwargs):
#     """Stub a function call with the given arguments
# 
#     Exposes a more pythonic interface than :func:`when`. See :func:`when` for
#     more documentation.
# 
#     Returns `AnswerSelector` interface which exposes `thenReturn`,
#     `thenRaise`, and `thenAnswer` as usual. Always `strict`.
# 
#     Usage::
# 
#         # Given `dog` is an instance of a `Dog`
#         when2(dog.bark, 'Miau').thenReturn('Wuff')
# 
#     .. note:: You must :func:`unstub` after stubbing, or use `with`
#         statement.
# 
#     """
#     obj, name = get_obj_attr_tuple(fn)
#     theMock = _get_mock(obj, strict=True)
#     return invocation.StubbedInvocation(theMock, name)(*args, **kwargs)
# 
# Path: mockito/invocation.py
# class RememberedProxyInvocation(Invocation):
#     '''Remeber params and proxy to method of original object.
# 
#     Calls method on original object and returns it's return value.
#     '''
#     def __init__(self, mock, method_name):
#         super(RememberedProxyInvocation, self).__init__(mock, method_name)
#         self.verified = False
#         self.verified_inorder = False
# 
#     def __call__(self, *params, **named_params):
#         self._remember_params(params, named_params)
#         self.mock.remember(self)
#         obj = self.mock.spec
#         try:
#             method = getattr(obj, self.method_name)
#         except AttributeError:
#             raise AttributeError(
#                 "You tried to call method '%s' which '%s' instance does not "
#                 "have." % (self.method_name, obj))
#         return method(*params, **named_params)
# 
# Path: mockito/mocking.py
# MYPY = False
# OMITTED = _OMITTED()
# class _Dummy(object):
# class Mock(object):
# class _OMITTED(object):
#     class Dummy(_Dummy):
#     def __call__(self, *args, **kwargs):
# def remembered_invocation_builder(mock, method_name, *args, **kwargs):
#     def __init__(self, mocked_obj, strict=True, spec=None):
#     def remember(self, invocation):
#     def finish_stubbing(self, stubbed_invocation):
#     def clear_invocations(self):
#     def get_original_method(self, method_name):
#     def set_method(self, method_name, new_method):
#     def replace_method(self, method_name, original_method):
#         def new_mocked_method(*args, **kwargs):
#     def stub(self, method_name):
#     def forget_stubbed_invocation(self, invocation):
#     def restore_method(self, method_name, original_method):
#     def unstub(self):
#     def has_method(self, method_name):
#     def get_signature(self, method_name):
#     def __repr__(self):
# def mock(config_or_spec=None, spec=None, strict=OMITTED):
#         def __getattr__(self, method_name):
#         def __repr__(self):
# 
# Path: mockito/utils.py
# def get_obj(path):
#     """Return obj for given dotted path.
# 
#     Typical inputs for `path` are 'os' or 'os.path' in which case you get a
#     module; or 'os.path.exists' in which case you get a function from that
#     module.
# 
#     Just returns the given input in case it is not a str.
# 
#     Note: Relative imports not supported.
#     Raises ImportError or AttributeError as appropriate.
# 
#     """
#     # Since we usually pass in mocks here; duck typing is not appropriate
#     # (mocks respond to every attribute).
#     if not isinstance(path, str):
#         return path
# 
#     if path.startswith('.'):
#         raise TypeError('relative imports are not supported')
# 
#     parts = path.split('.')
#     head, tail = parts[0], parts[1:]
# 
#     obj = importlib.import_module(head)
# 
#     # Normally a simple reduce, but we go the extra mile
#     # for good exception messages.
#     for i, name in enumerate(tail):
#         try:
#             obj = getattr(obj, name)
#         except AttributeError:
#             # Note the [:i] instead of [:i+1], so we get the path just
#             # *before* the AttributeError, t.i. the part of it that went ok.
#             module = '.'.join([head] + tail[:i])
#             try:
#                 importlib.import_module(module)
#             except ImportError:
#                 raise AttributeError(
#                     "object '%s' has no attribute '%s'" % (module, name))
#             else:
#                 raise AttributeError(
#                     "module '%s' has no attribute '%s'" % (module, name))
#     return obj


import inspect
from .mockito import when2
from .invocation import RememberedProxyInvocation
from .mocking import Mock, _Dummy, mock_registry
from .utils import get_obj
    obj = Spy()
    theMock = Mock(obj, strict=True, spec=object)

    mock_registry.register(obj, theMock)
    return obj


def spy2(fn):  # type: (...) -> None
    """Spy usage of given `fn`.

    Patches the module, class or object `fn` lives in, so that all
    interactions can be recorded; otherwise executes `fn` as before, so
    that all side effects happen as before.

    E.g.::

        import time
        spy2(time.time)
        do_work(...)  # nothing injected, uses global patched `time` module
        verify(time).time()

    Note that builtins often cannot be patched because they're read-only.


    """
    if isinstance(fn, str):
        answer = get_obj(fn)
    else:
        answer = fn


# Path: mockito/mockito.py
# def when2(fn, *args, **kwargs):
#     """Stub a function call with the given arguments
# 
#     Exposes a more pythonic interface than :func:`when`. See :func:`when` for
#     more documentation.
# 
#     Returns `AnswerSelector` interface which exposes `thenReturn`,
#     `thenRaise`, and `thenAnswer` as usual. Always `strict`.
# 
#     Usage::
# 
#         # Given `dog` is an instance of a `Dog`
#         when2(dog.bark, 'Miau').thenReturn('Wuff')
# 
#     .. note:: You must :func:`unstub` after stubbing, or use `with`
#         statement.
# 
#     """
#     obj, name = get_obj_attr_tuple(fn)
#     theMock = _get_mock(obj, strict=True)
#     return invocation.StubbedInvocation(theMock, name)(*args, **kwargs)
# 
# Path: mockito/invocation.py
# class RememberedProxyInvocation(Invocation):
#     '''Remeber params and proxy to method of original object.
# 
#     Calls method on original object and returns it's return value.
#     '''
#     def __init__(self, mock, method_name):
#         super(RememberedProxyInvocation, self).__init__(mock, method_name)
#         self.verified = False
#         self.verified_inorder = False
# 
#     def __call__(self, *params, **named_params):
#         self._remember_params(params, named_params)
#         self.mock.remember(self)
#         obj = self.mock.spec
#         try:
#             method = getattr(obj, self.method_name)
#         except AttributeError:
#             raise AttributeError(
#                 "You tried to call method '%s' which '%s' instance does not "
#                 "have." % (self.method_name, obj))
#         return method(*params, **named_params)
# 
# Path: mockito/mocking.py
# MYPY = False
# OMITTED = _OMITTED()
# class _Dummy(object):
# class Mock(object):
# class _OMITTED(object):
#     class Dummy(_Dummy):
#     def __call__(self, *args, **kwargs):
# def remembered_invocation_builder(mock, method_name, *args, **kwargs):
#     def __init__(self, mocked_obj, strict=True, spec=None):
#     def remember(self, invocation):
#     def finish_stubbing(self, stubbed_invocation):
#     def clear_invocations(self):
#     def get_original_method(self, method_name):
#     def set_method(self, method_name, new_method):
#     def replace_method(self, method_name, original_method):
#         def new_mocked_method(*args, **kwargs):
#     def stub(self, method_name):
#     def forget_stubbed_invocation(self, invocation):
#     def restore_method(self, method_name, original_method):
#     def unstub(self):
#     def has_method(self, method_name):
#     def get_signature(self, method_name):
#     def __repr__(self):
# def mock(config_or_spec=None, spec=None, strict=OMITTED):
#         def __getattr__(self, method_name):
#         def __repr__(self):
# 
# Path: mockito/utils.py
# def get_obj(path):
#     """Return obj for given dotted path.
# 
#     Typical inputs for `path` are 'os' or 'os.path' in which case you get a
#     module; or 'os.path.exists' in which case you get a function from that
#     module.
# 
#     Just returns the given input in case it is not a str.
# 
#     Note: Relative imports not supported.
#     Raises ImportError or AttributeError as appropriate.
# 
#     """
#     # Since we usually pass in mocks here; duck typing is not appropriate
#     # (mocks respond to every attribute).
#     if not isinstance(path, str):
#         return path
# 
#     if path.startswith('.'):
#         raise TypeError('relative imports are not supported')
# 
#     parts = path.split('.')
#     head, tail = parts[0], parts[1:]
# 
#     obj = importlib.import_module(head)
# 
#     # Normally a simple reduce, but we go the extra mile
#     # for good exception messages.
#     for i, name in enumerate(tail):
#         try:
#             obj = getattr(obj, name)
#         except AttributeError:
#             # Note the [:i] instead of [:i+1], so we get the path just
#             # *before* the AttributeError, t.i. the part of it that went ok.
#             module = '.'.join([head] + tail[:i])
#             try:
#                 importlib.import_module(module)
#             except ImportError:
#                 raise AttributeError(
#                     "object '%s' has no attribute '%s'" % (module, name))
#             else:
#                 raise AttributeError(
#                     "module '%s' has no attribute '%s'" % (module, name))
#     return obj


# Path: mockito/spying.py
import inspect
from .mockito import when2
from .invocation import RememberedProxyInvocation
from .mocking import Mock, _Dummy, mock_registry
from .utils import get_obj

    obj = Spy()
    theMock = Mock(obj, strict=True, spec=object)

    mock_registry.register(obj, theMock)
    return obj


def spy2(fn):  # type: (...) -> None
    """Spy usage of given `fn`.

    Patches the module, class or object `fn` lives in, so that all
    interactions can be recorded; otherwise executes `fn` as before, so
    that all side effects happen as before.

    E.g.::

        import time
        spy2(time.time)
        do_work(...)  # nothing injected, uses global patched `time` module
        verify(time).time()

    Note that builtins often cannot be patched because they're read-only.


    """
    if isinstance(fn, str):
        answer = get_obj(fn)
    else:
        answer = fn


    when2(fn, Ellipsis).thenAnswer(answer)