Patches lazy-loaded methods of classes. Patching at the class definition overrides the __getattr__ method for the class with a new version that patches any callables returned by __getattr__ with a key matching the last element of the dot path given

    :param str import_path: The absolute path to the lazy-loaded method to patch. It can be either abstract, or defined by calling __getattr__
    :param mixed rvalue: The value that should be immediately returned without executing the target.
    :param mixed side_effect: The side effect to execute. Either a callable with the same parameters as the target, or an exception.
    :param caliendo.Ignore ignore: The parameters that should be ignored when determining cachekeys. These are typically the dynamic values such as datetime.datetime.now() or a setting from an environment specific file.
    :param function callback: The callback function to execute when
    :param function callback: A pickleable callback to execute when the patched method is called and the cache is hit. (has to have been cached the first time).
    :param caliendo.hooks.Context ctxt: The context this patch should be executed under. Generally reserved for internal use. The vast majority of use cases should leave this parameter alone.

    :returns: The patched calling method.

def patch_lazy(import_path, rvalue=UNDEFINED, side_effect=UNDEFINED, ignore=UNDEFINED, callback=UNDEFINED, ctxt=UNDEFINED):
    """
    Patches lazy-loaded methods of classes. Patching at the class definition overrides the __getattr__ method for the class with a new version that patches any callables returned by __getattr__ with a key matching the last element of the dot path given

    :param str import_path: The absolute path to the lazy-loaded method to patch. It can be either abstract, or defined by calling __getattr__
    :param mixed rvalue: The value that should be immediately returned without executing the target.
    :param mixed side_effect: The side effect to execute. Either a callable with the same parameters as the target, or an exception.
    :param caliendo.Ignore ignore: The parameters that should be ignored when determining cachekeys. These are typically the dynamic values such as datetime.datetime.now() or a setting from an environment specific file.
    :param function callback: The callback function to execute when
    :param function callback: A pickleable callback to execute when the patched method is called and the cache is hit. (has to have been cached the first time).
    :param caliendo.hooks.Context ctxt: The context this patch should be executed under. Generally reserved for internal use. The vast majority of use cases should leave this parameter alone.

    :returns: The patched calling method.
    """
    def patch_method(unpatched_method):
        context = get_context(unpatched_method)

        getter, attribute = _get_target(import_path)
        klass = getter()

        getattr_path = ".".join(import_path.split('.')[0:-1] + ['__getattr__'])

        def wrapper(wrapped_method, instance, attr):
            lazy_loaded = wrapped_method.original(instance, attr)

            if attr != attribute:
                return lazy_loaded

            return get_replacement_method(lazy_loaded,
                                          side_effect=side_effect,
                                          rvalue=rvalue,
                                          ignore=ignore,
                                          callback=callback,
                                          context=context)

        @patch(getattr_path, side_effect=WrappedMethod(klass.__getattr__, wrapper), ctxt=context)
        def patched_method(*args, **kwargs):
            try:
                return unpatched_method(*args, **kwargs)
            finally:
                context.exit()

        return patched_method
    return patch_method