Ejemplo n.º 1
0
def _install_request_parser_annotation(f, base_generic_type: Type):
    handler_type_hints = get_handler_original_typehints(f)
    path_params: List[RequestParserAnnotationSpec] = []

    for name, _type in handler_type_hints.items():
        if is_base_type(_type, base_generic_type):
            generic_type_args = get_args(_type)
            if not generic_type_args:
                raise TypeError(
                    f"{base_generic_type} must be Generic Type. Your handler {get_handler_original_qualname(f)} declares a parametrer that's not {base_generic_type}[T]"
                )
            if generic_type_args:
                path_params.append(
                    RequestParserAnnotationSpec(name=name,
                                                base=_type,
                                                arg_type=generic_type_args[0]))

    @wraps(f)
    async def _wrap(wrapper: RequestWrapper):
        for p in path_params:
            try:
                typed_val = await p.base.from_request(request=wrapper,
                                                      arg_name=p.name,
                                                      arg_type=p.arg_type)
                wrapper.types_registry.set(typed_val,
                                           p.base,
                                           param_name=p.name)
            except ValueError as e:
                raise HTTPBadRequest(text=e.args[0])
        return await call_http_handler(wrapper, f)

    return _wrap
    async def test_does_not_have_attribute(self):
        def func(a: int, b: bool):
            pass

        self.assertEqual(
            get_handler_original_typehints(func), {"a": int, "b": bool}
        )
        self.assertFalse(hasattr(func, "asyncworker_original_annotations"))
Ejemplo n.º 3
0
    async def test_with_one_first_decorator(self):
        @handler_register
        @_deco
        async def _func(q: int, b: bool):
            pass

        final_func = await _func()
        self.assertEqual(final_func.__annotations__, {"s": str})
        self.assertEqual(
            get_handler_original_typehints(final_func), {"q": int, "b": bool}
        )
        self.assertEqual(
            "TestWrapsDecorator.test_with_one_first_decorator.<locals>._func",
            final_func.asyncworker_original_qualname,
        )
Ejemplo n.º 4
0
    async def test_with_three_decorators(self):
        @handler_register
        @_deco3
        @_deco2
        @_deco
        async def _func(other: int, integer: int, feature: bool):
            pass

        final_func = await _func()
        self.assertEqual(
            final_func.__annotations__, {"flag": bool, "other": str}
        )
        self.assertEqual(
            get_handler_original_typehints(final_func),
            {"other": int, "integer": int, "feature": bool},
        )
Ejemplo n.º 5
0
    async def test_with_two_second_decorators(self):
        @handler_register
        @_deco2
        @_deco
        async def _func(other: int, integer: int, feature: bool):
            pass

        final_func = await _func()
        self.assertEqual(final_func.__annotations__, {"param": bool, "i": int})
        self.assertEqual(
            get_handler_original_typehints(final_func),
            {"other": int, "integer": int, "feature": bool},
        )

        self.assertEqual(
            "TestWrapsDecorator.test_with_two_second_decorators.<locals>._func",
            final_func.asyncworker_original_qualname,
        )
Ejemplo n.º 6
0
def parse_path(handler):
    """
    Decorator que permite receber dinamicamente parametros do Request Path
    Basta que o nome do parametro na assinatura do handler seja igual ao nome do parametro
    declarado no Path HTTP.
    """
    """
    Aqui usamos essa função `_dummy` apenas para aproveitar a implementação
    já existente em `typing.get_type_hints()`. 
    Como essa implementação exige que passamos uma function, mas temos nesse momento
    apenas um dict.
    Então criamos essa função "vazia" e colocmos nela as anotações do handler
    original.
    """

    handler_types_args = get_handler_original_typehints(handler)
    handler_args_names = list(handler_types_args.keys())

    @wraps(handler)
    async def _wrap(wrapper: RequestWrapper):
        req = wrapper.http_request

        for param_name in handler_args_names:
            if param_name in req.match_info:
                try:
                    value = handler_types_args[param_name](
                        req.match_info[param_name])
                    wrapper.types_registry.set(value, param_name=param_name)
                except ValueError:
                    await logger.exception({
                        "event":
                        "incompatible-types-handler-arg",
                        "arg-type":
                        handler_types_args[param_name],
                        "arg-value":
                        req.match_info[param_name],
                    })
                    raise

        return await call_http_handler(wrapper, handler)

    return _wrap
Ejemplo n.º 7
0
    async def test_when_decorator_has_parameters(self):
        def _deco_with_params(a: int):
            def _wrap1(handler):
                @wraps(handler)
                async def _final_wrap(param: bool):
                    pass

                return _final_wrap

            return _wrap1

        @handler_register
        @_deco_with_params(42)
        async def _func(x: bool, y: int):
            pass

        final_func = await _func()
        self.assertEqual(final_func.__annotations__, {"param": bool})
        self.assertEqual(
            get_handler_original_typehints(final_func), {"x": bool, "y": int}
        )
    async def test_is_base_when_not_generic(self):
        def _func(b: MyGeneric):
            pass

        _type = get_handler_original_typehints(_func)
        self.assertTrue(is_base_type(_type["b"], MyGeneric))
 async def _wrap():
     return get_handler_original_typehints(handler)
    async def test_is_base_when_arg_primitive_base_generic(self):
        def _func(b: int):
            pass

        _type = get_handler_original_typehints(_func)
        self.assertFalse(is_base_type(_type["b"], MyGeneric))