'Call the callable with the arguments and keyword arguments
provided but inject the active context or environment as first
argument if the callable is a :func:`contextfunction` or
:func:`environmentfunction`.'

@internalcode
def call(__self, __obj, *args, **kwargs):

    if __debug__:
        __traceback_hide__ = True
    if hasattr(__obj, '__call__'):
        fn = __obj.__call__
        for fn_type in ('contextfunction', 'evalcontextfunction', 'environmentfunction'):
            if hasattr(fn, fn_type):
                __obj = fn
                break
    if isinstance(__obj, _context_function_types):
        if getattr(__obj, 'contextfunction', 0):
            args = ((__self,) + args)
        elif getattr(__obj, 'evalcontextfunction', 0):
            args = ((__self.eval_ctx,) + args)
        elif getattr(__obj, 'environmentfunction', 0):
            args = ((__self.environment,) + args)
    try:
        return __obj(*args, **kwargs)
    except StopIteration:
        return __self.environment.undefined('value    was    undefined    because    a    callable    raised    a    StopIteration    exception')
