docs: def simple_callable(decorator):
      '''Decorator used to create consistent decorators.
      Consistent in the meaning that the wrapper do not have to
      care if the wrapped callable is a function or a method,
      it will always receive a valid callable.
      If the decorator is used with a function, the wrapper will
      receive the function itself, but if the decorator is used
      with a method, the wrapper will receive a bound method
      callable directly and the first argument (self) will be removed.
      This allows writing decorators behaving consistently
      with function and method.
  
      Note that when using reflect or annotate module functions,
      depth should be incremented by one.
  
      Example::
  
          @decorator.simple_callable
          def mydecorator(original_function):
  
              def wrapper(callable, call, arguments):
                  # processing
                  return callable(call, arguments)
  
              return wrapper
  
          @mydecorator
          def myfunction():
              pass
  
      '''
  
      def meta_decorator(function):
  
          wrapper = decorator(function)
  
          if reflect.inside_class_definition(depth=2):
  
              def method_wrapper(*args, **kwargs):
                  obj, args = args[0], args[1:]
                  method = types.MethodType(function, obj, obj.__class__)
                  return wrapper(method, *args, **kwargs)
  
              meta_wrapper = _function_mimicry(function, method_wrapper)
  
          else:
  
              def function_wrapper(*args, **kwargs):
                  return wrapper(function, *args, **kwargs)
  
              meta_wrapper = _function_mimicry(function, function_wrapper)
  
          return meta_wrapper
  
      return meta_decorator