Ejemplo n.º 1
0
    def __call__(self, function):
        function._command = self

        def wrapper(wrapped, instance, args, kwargs):
            if not self.auth():
                raise Unauthorized
            args = list(args)  # mutable
            _args = []
            _kwargs = {}
            for name, param in inspect.signature(wrapped).parameters.items():
                if not args:
                    break  # missing argument(s) will be caught in call to method
                elif param.kind == param.POSITIONAL_OR_KEYWORD:
                    arg = args.pop(0)
                    try:
                        _args.append(
                            wrapped.__annotations__.get(name, cmd._str).str_decode(arg)
                        )
                    except s.SchemaError:
                        raise Error(f"Invalid {name}: {arg}.")
                elif param.kind == param.VAR_KEYWORD:
                    for arg in args:
                        try:
                            key, value = arg.split("=", 1)
                        except ValueError:
                            raise Error(f"Invalid key-value: {arg}")
                        _kwargs[key] = value
                    args.clear()
                else:
                    raise TypeError("unsupported command parameter type")
            if args:
                raise TypeError(f"{wrapped.__name__}: too many arguments")
            return wrapped(*_args, **_kwargs)

        return wrapt.decorator(wrapper)(function)
Ejemplo n.º 2
0
 def decorator(function):
     _name = name
     _type = type
     _description = description or function.__doc__ or function.__name__
     __summary = summary or _summary(function)
     if _name is None:
         _name = function.__name__
     if _type is None and _name in ["create", "read", "update", "delete"]:
         _type = _name
     valid_types = ["create", "read", "update", "delete", "query", "action"]
     if _type not in valid_types:
         raise ValueError("operation type must be one of: {}".format(valid_types))
     def wrapper(wrapped, instance, args, kwargs):
         with context.push(context_type="operation", operation_resource=wrapped.__self__, operation_name=_name):
             authorize(security)
             return wrapped(*args, **kwargs)
     _params = s.function_params(function, params)
     decorated = s.validate(_params, returns)(wrapt.decorator(wrapper)(function))
     operation = dict(function=decorated, name=_name, type=_type,
         summary=__summary, description=_description, params=_params,
         returns=returns, security=security, publish=publish, deprecated=deprecated)
     try:
         resource = getattr(function, "__self__")
         resource._register_operation(**{**operation, "resource": resource})
     except AttributeError:  # not yet bound to an instance
         function._roax_operation = operation  # __init__ will register it
     return decorated
Ejemplo n.º 3
0
    def decorator(function):
        _params = function_params(function, params)

        def wrapper(wrapped, instance, args, kwargs):
            return call(wrapped, args, kwargs, _params, returns)

        return wrapt.decorator(wrapper)(function)
Ejemplo n.º 4
0
        def decorator(function):
            def wrapper(function, _, args, kwargs):
                @self.run_in_reactor
                def run():
                    if iscoroutinefunction(function):
                        return ensureDeferred(function(*args, **kwargs))
                    else:
                        return function(*args, **kwargs)

                eventual_result = run()
                try:
                    return eventual_result.wait(timeout)
                except TimeoutError:
                    eventual_result.cancel()
                    raise

            if iscoroutinefunction(function):
                # Create a non-async wrapper with same signature.
                @wraps(function)
                def non_async_wrapper():
                    pass
            else:
                # Just use default behavior of looking at underlying object.
                non_async_wrapper = None

            wrapper = wrapt.decorator(wrapper, adapter=non_async_wrapper)
            return wrapper(function)
Ejemplo n.º 5
0
def get_wrapper_builder(configuration, excluded_fields=None):
    if excluded_fields is None:
        excluded_fields = set()

    excluded_fields |= {"__class__", "__new__"}

    def build_wrapper(wrapped, instance, args, kwargs):
        if instance is None:
            if inspect.isclass(wrapped):
                # Decorator was applied to a class
                root = None
                if is_type_of_type(wrapped, typing.Generic, covariant=True):
                    wrapped = GenericProxy(wrapped)
                    root = wrapped.__enforcer__.validator

                for attr_name in dir(wrapped):
                    try:
                        if attr_name in excluded_fields:
                            raise AttributeError
                        old_attr = getattr(wrapped, attr_name)

                        if old_attr.__class__ is property:
                            old_fset = old_attr.fset
                            new_fset = decorate(
                                old_fset,
                                configuration,
                                obj_instance=None,
                                parent_root=root,
                            )
                            new_attr = old_attr.setter(new_fset)
                        else:
                            new_attr = decorate(
                                old_attr,
                                configuration,
                                obj_instance=None,
                                parent_root=root,
                            )
                        setattr(wrapped, attr_name, new_attr)
                    except AttributeError:
                        pass
                return wrapped
            else:
                # Decorator was applied to a function or staticmethod.
                if issubclass(type(wrapped), staticmethod):
                    return staticmethod(
                        decorate(wrapped.__func__, configuration, None))
                return decorate(wrapped, configuration, None)
        else:
            if inspect.isclass(instance):
                # Decorator was applied to a classmethod.
                return decorate(wrapped, configuration, None)
            else:
                # Decorator was applied to an instancemethod.
                return decorate(wrapped, configuration, instance)

    return decorator(build_wrapper)
Ejemplo n.º 6
0
    def test_function_attributes(self):
        def decorator1(wrapped, instance, args, kwargs):
            return wrapped(*args, **kwargs)
        decorator2 = wrapt.decorator(decorator1)

        def function1(*args, **kwargs):
            return args, kwargs
        function2 = decorator2(function1)

        self.assertEqual(function2.__wrapped__, function1)
        self.assertEqual(function2._self_wrapper, decorator1)
        self.assertEqual(function2._self_binding, 'function')
Ejemplo n.º 7
0
    def test_function_attributes(self):
        def decorator1(wrapped, instance, args, kwargs):
            return wrapped(*args, **kwargs)
        decorator2 = wrapt.decorator(decorator1)

        def function1(*args, **kwargs):
            return args, kwargs
        function2 = decorator2(function1)

        self.assertEqual(function2.__wrapped__, function1)
        self.assertEqual(function2._self_wrapper, decorator1)
        self.assertEqual(function2._self_binding, 'function')
Ejemplo n.º 8
0
    def test_staticmethod_attributes(self):
        def decorator1(wrapped, instance, args, kwargs):
            return wrapped(*args, **kwargs)
        decorator2 = wrapt.decorator(decorator1)

        class Class(object):
            @staticmethod
            def function1(*args, **kwargs):
                return args, kwargs
            function2 = decorator2(function1)

            self.assertEqual(function2.__wrapped__, function1)
            self.assertEqual(function2._self_wrapper, decorator1)
            self.assertEqual(function2._self_binding, 'staticmethod')
Ejemplo n.º 9
0
    def test_classmethod_attributes_external_instance(self):
        def decorator1(wrapped, instance, args, kwargs):
            return wrapped(*args, **kwargs)
        decorator2 = wrapt.decorator(decorator1)

        class Class(object):
            @classmethod
            def function1(cls, *args, **kwargs):
                return args, kwargs

        function2 = decorator2(Class().function1)

        self.assertEqual(function2._self_wrapper, decorator2)
        self.assertEqual(function2._self_binding, 'classmethod')
Ejemplo n.º 10
0
    def decorator(function):
        _name = name
        _type = type
        _description = description or function.__doc__ or function.__name__
        __summary = summary or _summary(function)
        if _name is None:
            _name = function.__name__
        if _type is None and _name in {
                "create", "read", "update", "delete", "patch"
        }:
            _type = _name
        if _type not in _valid_types:
            raise ValueError(f"operation type must be one of: {_valid_types}")

        def wrapper(wrapped, instance, args, kwargs):
            operation = wrapped.__self__.operations[wrapped.__name__]
            tags = {
                "operation": operation.name,
                "resource": operation.resource.name
            }
            with context.push({"context": "roax.operation", **tags}):
                with roax.monitor.timer({
                        "name": "operation_duration_seconds",
                        **tags
                }):
                    with roax.monitor.counter({
                            "name": "operation_calls_total",
                            **tags
                    }):
                        authorize(operation.security)
                        return wrapped(*args, **kwargs)

        decorated = roax.schema.validate(wrapt.decorator(wrapper)(function))
        operation = dict(
            function=function.__name__,
            name=_name,
            type=_type,
            summary=__summary,
            description=_description,
            params=_params(function),
            returns=function.__annotations__.get("return"),
            security=security,
            publish=publish,
            deprecated=deprecated,
        )
        try:
            getattr(function, "__self__")._register_operation(**operation)
        except AttributeError:  # not yet bound to an instance
            function._roax_operation_ = operation  # __init__ will register it
        return decorated
Ejemplo n.º 11
0
def get_wrapper_builder(configuration, excluded_fields=None):
    if excluded_fields is None:
        excluded_fields = set()

    excluded_fields |= {'__class__', '__new__'}

    def build_wrapper(wrapped, instance, args, kwargs):
        if instance is None:
            if inspect.isclass(wrapped):
                # Decorator was applied to a class
                root = None
                if is_type_of_type(wrapped, typing.Generic, covariant=True):
                    wrapped = GenericProxy(wrapped)
                    root = wrapped.__enforcer__.validator

                for attr_name in dir(wrapped):
                    try:
                        if attr_name in excluded_fields:
                            raise AttributeError
                        old_attr = getattr(wrapped, attr_name)

                        if old_attr.__class__ is property:
                            old_fset = old_attr.fset
                            new_fset = decorate(old_fset, configuration, obj_instance=None, parent_root=root)
                            new_attr = old_attr.setter(new_fset)
                        else:
                            new_attr = decorate(old_attr, configuration, obj_instance=None, parent_root=root)
                        setattr(wrapped, attr_name, new_attr)
                    except AttributeError:
                        pass
                return wrapped
            else:
                # Decorator was applied to a function or staticmethod.
                if issubclass(type(wrapped), staticmethod):
                    return staticmethod(decorate(wrapped.__func__, configuration, None))
                return decorate(wrapped, configuration, None)
        else:
            if inspect.isclass(instance):
                # Decorator was applied to a classmethod.
                return decorate(wrapped, configuration, None)
            else:
                # Decorator was applied to an instancemethod.
                return decorate(wrapped, configuration, instance)

    return decorator(build_wrapper)
Ejemplo n.º 12
0
    def decorator(function):
        _name = name
        _type = type
        _description = description or function.__doc__ or function.__name__
        __summary = summary or _summary(function)
        if _name is None:
            _name = function.__name__
        if _type is None and _name in {
                "create", "read", "update", "delete", "patch"
        }:
            _type = _name
        valid_types = {
            "create", "read", "update", "delete", "query", "action", "patch"
        }
        if _type not in valid_types:
            raise ValueError(
                "operation type must be one of: {}".format(valid_types))

        def wrapper(wrapped, instance, args, kwargs):
            tags = {"resource": wrapped.__self__.name, "operation": _name}
            with context.push({**tags, "context": "operation"}):
                monitor.record({
                    **tags, "name": "operation_calls_total"
                }, _now(), "absolute", 1)
                with timer({**tags, "name": "operation_duration_seconds"}):
                    authorize(security)
                    return wrapped(*args, **kwargs)

        decorated = s.validate(params,
                               returns)(wrapt.decorator(wrapper)(function))
        operation = dict(function=function.__name__,
                         name=_name,
                         type=_type,
                         summary=__summary,
                         description=_description,
                         params=s.function_params(function, params),
                         returns=returns,
                         security=security,
                         publish=publish,
                         deprecated=deprecated)
        try:
            getattr(function, "__self__")._register_operation(**operation)
        except AttributeError:  # not yet bound to an instance
            function._roax_operation_ = operation  # __init__ will register it
        return decorated
Ejemplo n.º 13
0
    def test_instancemethod_attributes_external_class(self):
        def decorator1(wrapped, instance, args, kwargs):
            return wrapped(*args, **kwargs)
        decorator2 = wrapt.decorator(decorator1)

        class Class(object):
            def function1(self, *args, **kwargs):
                return args, kwargs

        function2 = decorator2(Class.function1)

        self.assertEqual(function2._self_wrapper, decorator2)

        # We can't identify this as being an instance method in
        # Python 3 because there is no concept of unbound methods.
        # We therefore don't try for Python 2 either.

        self.assertEqual(function2._self_binding, 'function')
Ejemplo n.º 14
0
    def test_staticmethod_attributes_external_instance(self):
        def decorator1(wrapped, instance, args, kwargs):
            return wrapped(*args, **kwargs)
        decorator2 = wrapt.decorator(decorator1)

        class Class(object):
            @staticmethod
            def function1(*args, **kwargs):
                return args, kwargs

        function2 = decorator2(Class().function1)

        self.assertEqual(function2._self_wrapper, decorator2)

        # We can't identify this as being a static method because
        # the binding has resulted in a normal function being returned.

        self.assertEqual(function2._self_binding, 'function')
Ejemplo n.º 15
0
def get_universal_decorator():
    def universal(wrapped, instance, args, kwargs):
        """
        This function will be returned by the decorator. It adds type checking before triggering
        the original function and then it checks for the output type. Only then it returns the
        output of original function.
        """
        with RunLock:
            enforcer = wrapped.__enforcer__
            skip = False

            # In order to avoid problems with TypeVar-s, validator must be reset
            enforcer.reset()

            instance_method = False
            if instance is not None and not inspect.isclass(instance):
                instance_method = True

            if hasattr(wrapped, '__no_type_check__'):
                skip = True

            if instance_method:
                parameters = Parameters([instance, *args], kwargs, skip)
            else:
                parameters = Parameters(args, kwargs, skip)

            # First, check argument types (every key not labelled 'return')
            _args, _kwargs, _ = enforcer.validate_inputs(parameters)

            if instance_method:
                if len(_args) > 1:
                    _args = _args[1:]
                else:
                    _args = tuple()

            result = wrapped(*_args, **_kwargs)

            # we *only* return result if all type checks passed
            if skip:
                return result
            else:
                return enforcer.validate_outputs(result)

    return decorator(universal)
Ejemplo n.º 16
0
def get_universal_decorator():
    def universal(wrapped, instance, args, kwargs):
        """
        This function will be returned by the decorator. It adds type checking before triggering
        the original function and then it checks for the output type. Only then it returns the
        output of original function.
        """
        with RunLock:
            enforcer = wrapped.__enforcer__
            skip = False

            # In order to avoid problems with TypeVar-s, validator must be reset
            enforcer.reset()

            instance_method = False
            if instance is not None and not inspect.isclass(instance):
                instance_method = True

            if hasattr(wrapped, '__no_type_check__'):
                skip = True

            if instance_method:
                parameters = Parameters([instance, *args], kwargs, skip)
            else:
                parameters = Parameters(args, kwargs, skip)

            # First, check argument types (every key not labelled 'return')
            _args, _kwargs, _ = enforcer.validate_inputs(parameters)

            if instance_method:
                if len(_args) > 1:
                    _args = _args[1:]
                else:
                    _args = tuple()

            result = wrapped(*_args, **_kwargs)

            # we *only* return result if all type checks passed
            if skip:
                return result
            else:
                return enforcer.validate_outputs(result)

    return decorator(universal)
Ejemplo n.º 17
0
    def test_instancemethod_attributes_external_instance(self):
        def decorator1(wrapped, instance, args, kwargs):
            return wrapped(*args, **kwargs)
        decorator2 = wrapt.decorator(decorator1)

        class Class(object):
            def function1(self, *args, **kwargs):
                return args, kwargs

        function2 = decorator2(Class().function1)

        self.assertEqual(function2._self_wrapper, decorator2)

        # We can't identify this as being an instance method in
        # Python 3 when it is a class so have to disable the check
        # for Python 2. This has flow on effect of not working
        # in the case of an instance either.

        self.assertEqual(function2._self_binding, 'function')
Ejemplo n.º 18
0
    def test_instancemethod_attributes(self):
        def decorator1(wrapped, instance, args, kwargs):
            return wrapped(*args, **kwargs)
        decorator2 = wrapt.decorator(decorator1)

        class Class(object):
            def function1(self, *args, **kwargs):
                return args, kwargs
            function2 = decorator2(function1)

            self.assertEqual(function2.__wrapped__, function1)
            self.assertEqual(function2._self_wrapper, decorator1)
            self.assertEqual(function2._self_binding, 'function')

        instance = Class()

        self.assertEqual(instance.function2.__wrapped__, instance.function1)
        self.assertEqual(instance.function2._self_instance, instance)
        self.assertEqual(instance.function2._self_wrapper, decorator1)
Ejemplo n.º 19
0
    def test_instancemethod_attributes(self):
        def decorator1(wrapped, instance, args, kwargs):
            return wrapped(*args, **kwargs)
        decorator2 = wrapt.decorator(decorator1)

        class Class(object):
            def function1(self, *args, **kwargs):
                return args, kwargs
            function2 = decorator2(function1)

            self.assertEqual(function2.__wrapped__, function1)
            self.assertEqual(function2._self_wrapper, decorator1)
            self.assertEqual(function2._self_binding, 'function')

        instance = Class()

        self.assertEqual(instance.function2.__wrapped__, instance.function1)
        self.assertEqual(instance.function2._self_instance, instance)
        self.assertEqual(instance.function2._self_wrapper, decorator1)
Ejemplo n.º 20
0
    def run_in_reactor(self, function):
        """
        A decorator that ensures the wrapped function runs in the
        reactor thread.

        When the wrapped function is called, an EventualResult is returned.
        """
        def _run_in_reactor(wrapped, _, args, kwargs):
            """
            Implementation: A decorator that ensures the wrapped function runs in
            the reactor thread.

            When the wrapped function is called, an EventualResult is returned.
            """

            if iscoroutinefunction(wrapped):

                def runs_in_reactor(result, args, kwargs):
                    d = ensureDeferred(wrapped(*args, **kwargs))
                    result._connect_deferred(d)
            else:

                def runs_in_reactor(result, args, kwargs):
                    d = maybeDeferred(wrapped, *args, **kwargs)
                    result._connect_deferred(d)

            result = EventualResult(None, self._reactor)
            self._registry.register(result)
            self._reactor.callFromThread(runs_in_reactor, result, args, kwargs)
            return result

        if iscoroutinefunction(function):
            # Create a non-async wrapper with same signature.
            @wraps(function)
            def non_async_wrapper():
                pass
        else:
            # Just use default behavior of looking at underlying object.
            non_async_wrapper = None

        return wrapt.decorator(_run_in_reactor,
                               adapter=non_async_wrapper)(function)
Ejemplo n.º 21
0
 def new_wrapper(f):
     x = wrapt.decorator(_wrapper)(f)
     x._annotations = getattr(x, '_annotations', {})
     x._annotations.update(annotations)
     x._self_pico_request_decorator = True
     return x
Ejemplo n.º 22
0
def subsegment_decorator(wrapped, instance, args, kwargs):
    decorated_func = wrapt.decorator(wrapped)(*args, **kwargs)
    set_as_recording(decorated_func, wrapped)
    return decorated_func
Ejemplo n.º 23
0
    def decorator(fn):
        def wrapper(wrapped, instance, args, kwargs):
            return call(wrapped, args, kwargs)

        return wrapt.decorator(wrapper)(function)