# Path: doubles/class_double.py
# class ClassDouble(InstanceDouble):
#     """
#     A pure double representing the target class.
# 
#     ::
# 
#         User = ClassDouble('myapp.User')
# 
#     :param str path: The absolute module path to the class.
#     """
# 
#     is_class = True
# 
#     def __init__(self, path):
#         super(ClassDouble, self).__init__(path)
#         self._doubles_target = patch_class(self._doubles_target)
#         self._target = Target(self._doubles_target)
# 
#     def __call__(self, *args, **kwargs):
#         """Verify arguments and proxy to _doubles__new__
# 
#         :rtype obj:
#         :raises VerifyingDoubleArgumentError: If args/kwargs don't match the expected arguments of
#             __init__ of the underlying class.
#         """
#         verify_arguments(self._target, '_doubles__new__', args, kwargs)
#         return self._doubles__new__(*args, **kwargs)
# 
#     def _doubles__new__(self, *args, **kwargs):
#         """Raises an UnallowedMethodCallError
# 
#         NOTE: This method is here only to raise if it has not been stubbed
#         """
#         raise UnallowedMethodCallError('Cannot call __new__ on a ClassDouble without stubbing it')
# 
# Path: doubles/exceptions.py
# class ConstructorDoubleError(AssertionError):
#     """
#     An exception raised when attempting to double the constructor of a non ClassDouble.
#     """
# 
# Path: doubles/lifecycle.py
# def current_space():
#     """An accessor for the current thread's active ``Space``.
# 
#     :return: The active ``Space``.
#     :rtype: Space
#     """
# 
#     if not hasattr(_thread_local_data, 'current_space'):
#         _thread_local_data.current_space = Space()
# 
#     return _thread_local_data.current_space


import inspect
from doubles.class_double import ClassDouble
from doubles.exceptions import ConstructorDoubleError
from doubles.lifecycle import current_space



def expect(target):
    """
    Prepares a target object for a method call expectation (mock). The name of the method to expect
    should be called as a method on the return value of this function::

        expect(foo).bar

    Accessing the ``bar`` attribute will return an ``Expectation`` which provides additional methods
    to configure the mock.

    :param object target: The object that will be mocked.
    :return: An ``ExpectationTarget`` for the target object.
    """

    return ExpectationTarget(target)


def expect_constructor(target):
    """
    Set an expectation on a ``ClassDouble`` constructor

    :param ClassDouble target:  The ClassDouble to set the expectation on.
    :return: an ``Expectation`` for the __new__ method.
    :raise: ``ConstructorDoubleError`` if target is not a ClassDouble.
    """

# Path: doubles/class_double.py
# class ClassDouble(InstanceDouble):
#     """
#     A pure double representing the target class.
# 
#     ::
# 
#         User = ClassDouble('myapp.User')
# 
#     :param str path: The absolute module path to the class.
#     """
# 
#     is_class = True
# 
#     def __init__(self, path):
#         super(ClassDouble, self).__init__(path)
#         self._doubles_target = patch_class(self._doubles_target)
#         self._target = Target(self._doubles_target)
# 
#     def __call__(self, *args, **kwargs):
#         """Verify arguments and proxy to _doubles__new__
# 
#         :rtype obj:
#         :raises VerifyingDoubleArgumentError: If args/kwargs don't match the expected arguments of
#             __init__ of the underlying class.
#         """
#         verify_arguments(self._target, '_doubles__new__', args, kwargs)
#         return self._doubles__new__(*args, **kwargs)
# 
#     def _doubles__new__(self, *args, **kwargs):
#         """Raises an UnallowedMethodCallError
# 
#         NOTE: This method is here only to raise if it has not been stubbed
#         """
#         raise UnallowedMethodCallError('Cannot call __new__ on a ClassDouble without stubbing it')
# 
# Path: doubles/exceptions.py
# class ConstructorDoubleError(AssertionError):
#     """
#     An exception raised when attempting to double the constructor of a non ClassDouble.
#     """
# 
# Path: doubles/lifecycle.py
# def current_space():
#     """An accessor for the current thread's active ``Space``.
# 
#     :return: The active ``Space``.
#     :rtype: Space
#     """
# 
#     if not hasattr(_thread_local_data, 'current_space'):
#         _thread_local_data.current_space = Space()
# 
#     return _thread_local_data.current_space


# Path: doubles/targets/expectation_target.py
import inspect
from doubles.class_double import ClassDouble
from doubles.exceptions import ConstructorDoubleError
from doubles.lifecycle import current_space




def expect(target):
    """
    Prepares a target object for a method call expectation (mock). The name of the method to expect
    should be called as a method on the return value of this function::

        expect(foo).bar

    Accessing the ``bar`` attribute will return an ``Expectation`` which provides additional methods
    to configure the mock.

    :param object target: The object that will be mocked.
    :return: An ``ExpectationTarget`` for the target object.
    """

    return ExpectationTarget(target)


def expect_constructor(target):
    """
    Set an expectation on a ``ClassDouble`` constructor

    :param ClassDouble target:  The ClassDouble to set the expectation on.
    :return: an ``Expectation`` for the __new__ method.
    :raise: ``ConstructorDoubleError`` if target is not a ClassDouble.
    """

    if not isinstance(target, ClassDouble):