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)
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
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)
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)
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)
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')
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')
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')
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
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)
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
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')
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')
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)
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')
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)
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)
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
def subsegment_decorator(wrapped, instance, args, kwargs): decorated_func = wrapt.decorator(wrapped)(*args, **kwargs) set_as_recording(decorated_func, wrapped) return decorated_func
def decorator(fn): def wrapper(wrapped, instance, args, kwargs): return call(wrapped, args, kwargs) return wrapt.decorator(wrapper)(function)