예제 #1
0
def test_docstring_parser2():
    example = """
        Will block thread until `num_tokens` could be consumed from token bucket `key`.

        Args:

            key (str): identifying a specific token bucket
            num_tokens (int): will block without consuming any tokens until
                this amount are availabe to be consumed
            timeout (int): seconds to block for
            retry_interval (Optional[float]): how long to wait between polling
                for tokens to be available. `None` means use default interval
                which is equal to time needed to replenish `num_tokens`.

        Returns:

            Tuple[
                int,
                str,
                ClassName,
            ]
        """
    expected = TypeSignature.factory(
        arg_types=ArgTypes.factory(
            name=ArgsSection.ARGS,
            args=OrderedDict(
                [
                    ("key", TypeDef.from_tuples((5, 17), ("str", []), (5, 20),)),
                    ("num_tokens", TypeDef.from_tuples((6, 24), ("int", []), (6, 27),)),
                    ("timeout", TypeDef.from_tuples((8, 21), ("int", []), (8, 24),)),
                    (
                        "retry_interval",
                        TypeDef.from_tuples(
                            (9, 28), ("Optional", [TypeAtom("float", [])]), (9, 43),
                        ),
                    ),
                ]
            ),
        ),
        return_type=ReturnType.factory(
            name=ReturnsSection.RETURNS,
            type_def=TypeDef.from_tuples(
                (15, 12),
                (
                    "Tuple",
                    [
                        TypeAtom("int", []),
                        TypeAtom("str", []),
                        TypeAtom("ClassName", []),
                    ],
                ),
                (19, 13),
            ),
        ),
    )

    result = docstring_parser.parse(example)
    assert result == expected
예제 #2
0
def test_p_arg_list():
    example = """
        Kwargs:
            key (str): identifying a specific token bucket
            num_tokens (int) : whitespace around the colon
            timeout (int): seconds to block for
            retry_interval (Optional[float]): how long to wait between polling
                for tokens to be available. `None` means use default interval
                which is equal to time needed to replenish `num_tokens`.
            *inner_args
            **inner_kwargs: passed to inner function
    """
    section = p_arg_list.parse(example)
    assert section.name == ArgsSection.ARGS  # normalised -> "Args" (Enum)
    assert section.args == OrderedDict(
        [
            ("key", TypeDef.from_tuples((2, 17), ("str", []), (2, 20),)),
            ("num_tokens", TypeDef.from_tuples((3, 24), ("int", []), (3, 27),)),
            ("timeout", TypeDef.from_tuples((4, 21), ("int", []), (4, 24),)),
            (
                "retry_interval",
                TypeDef.from_tuples(
                    (5, 28), ("Optional", [TypeAtom("float", [])]), (5, 43),
                ),
            ),
            ("*inner_args", None),
            ("**inner_kwargs", None),
        ]
    )
예제 #3
0
def generic_typeatom_f(draw, children):
    """
    A type var with params (i.e. is 'generic'), without being one of the
    special cases such as homogenous tuple, callable (others?)

    Args:
        draw: provided by @st.composite
        children: another hypothesis strategy to draw from
            (first arg to function returned by decorator)
    """
    return TypeAtom(name=draw(dotted_var_path_f()),
                    args=draw(small_lists_f(children)))
예제 #4
0
def test_arg_type(example, start_pos, end_pos):
    parser = arg_type << rest_of_line

    result = parser.parse(example)

    assert result == {
        "arg": "key",
        "type": TypeDef(start_pos, TypeAtom("str", []), end_pos,),
    }

    assert result["type"].name == "str"
    assert result["type"].args == []

    start, _, end = result["type"]
    assert slice_by_pos(example, start, end) == "str"
예제 #5
0
def test_docstring_parser():
    example = """
        Will block thread until `num_tokens` could be consumed from token bucket `key`.

        Keyword Arguments:
            key (str): identifying a specific token bucket
            num_tokens (int): will block without consuming any tokens until
                this amount are availabe to be consumed
            timeout (int): seconds to block for
            retry_interval (Optional[float]): how long to wait between polling
                for tokens to be available. `None` means use default interval
                which is equal to time needed to replenish `num_tokens`.
            **kwargs (Any)

        Returns:
            bool: whether we got the requested tokens or not
                (False if timed out)
        """
    expected = TypeSignature.factory(
        arg_types=ArgTypes.factory(
            name=ArgsSection.ARGS,
            args=OrderedDict(
                [
                    ("key", TypeDef.from_tuples((4, 17), ("str", []), (4, 20),)),
                    ("num_tokens", TypeDef.from_tuples((5, 24), ("int", []), (5, 27),)),
                    ("timeout", TypeDef.from_tuples((7, 21), ("int", []), (7, 24),)),
                    (
                        "retry_interval",
                        TypeDef.from_tuples(
                            (8, 28), ("Optional", [TypeAtom("float", [])]), (8, 43),
                        ),
                    ),
                    ("**kwargs", TypeDef.from_tuples((11, 22), ("Any", []), (11, 25),)),
                ]
            ),
        ),
        return_type=ReturnType.factory(
            name=ReturnsSection.RETURNS,
            type_def=TypeDef.from_tuples((14, 12), ("bool", []), (14, 16),),
        ),
    )

    result = docstring_parser.parse(example)
    assert result == expected
예제 #6
0
def _callable() -> parsy.Parser:
    """
    Self-referential helper for `type_atom` of Callable type

    AFAIK `Callable` is the only type where one of the expected atom positions
    (the args of the callable) is a list. Other code is nicer if we treat that
    bare list as a TypeAtom name=None.
    """
    return (
        yield parsy.seq(
            parsy.string("Callable"),
            between(
                parsy.regex(r"\[\s*"),
                parsy.regex(r",?\s*\]"),
                parsy.seq(
                    _nested.map(lambda args: TypeAtom(None, args))
                    << parsy.regex(r",\s*"),
                    type_atom,
                ),
            ),
        ).combine(TypeAtom)
    )
예제 #7
0
    ReturnsSection,
    ReturnType,
    TypeAtom,
    TypeSignature,
)


@pytest.mark.parametrize(
    "example,expected",
    [
        (
            TypeSignature.factory(
                arg_types=ArgTypes.factory(
                    name=ArgsSection.ARGS,
                    args=OrderedDict([
                        ("key", TypeAtom("str", [])),
                        ("num_tokens", TypeAtom("int", [])),
                        ("timeout", TypeAtom("int", [])),
                        (
                            "retry_interval",
                            TypeAtom("Optional", [TypeAtom("float", [])]),
                        ),
                    ]),
                ),
                return_type=ReturnType.factory(
                    name=ReturnsSection.RETURNS,
                    type_def=TypeAtom("bool", []),
                ),
            ),
            "# type: (str, int, int, Optional[float]) -> bool",
        ),
예제 #8
0
def callable_typeatom_f(draw, children):
    args_param = draw(small_lists_nonempty_f(children))
    returns_param = draw(children)
    return TypeAtom(name="Callable",
                    args=(TypeAtom(None, args_param), returns_param))
예제 #9
0
def homogenous_tuple_typeatom_f(draw, children):
    return TypeAtom(name="Tuple", args=(draw(children), TypeAtom("...", [])))
예제 #10
0
def noargs_typeatom_f(draw):
    return TypeAtom(
        name=draw(dotted_var_path_f()),
        args=(),
    )
예제 #11
0
from waterloo.types import (
    ArgsSection,
    ArgTypes,
    ImportStrategy,
    ReturnsSection,
    ReturnType,
    TypeAtom,
    TypeSignature,
)


@pytest.mark.parametrize(
    "expected,example",
    [
        ("str", TypeAtom("str", [])),
        ("Dict", TypeAtom("Dict", [])),
        (
            "Dict[int, str]",
            TypeAtom("Dict", [TypeAtom("int", []),
                              TypeAtom("str", [])]),
        ),
        (
            "Dict[int, db.models.User]",
            TypeAtom("Dict",
                     [TypeAtom("int", []),
                      TypeAtom("db.models.User", [])]),
        ),
        (
            "my.generic.Container[int]",
            TypeAtom("my.generic.Container", [TypeAtom("int", [])]),
예제 #12
0
def assert_annotation_roundtrip(example: str, result: TypeAtom):
    normalised = _normalise_annotation(example)
    assert normalised == result.to_annotation(None)
예제 #13
0
                    _nested.map(lambda args: TypeAtom(None, args))
                    << parsy.regex(r",\s*"),
                    type_atom,
                ),
            ),
        ).combine(TypeAtom)
    )


_type_token = dotted_var_path | parsy.string("...")

# mypy type definition, parsed into its nested components
type_atom = (
    _callable
    | parsy.seq(_type_token, _nested).combine(TypeAtom)
    | _type_token.map(lambda t: TypeAtom(t, []))
    | _nested  # recurse->
)


# in "Args" section the type def is in parentheses after the var name
# fmt: off
arg_type_def = lexeme(
    parsy.string("(") >> scn >> typed_mark(type_atom, TypeDef) << scn << parsy.string(")")
)
# fmt: on

optional_description = parsy.regex(r"[ |\t]*:") | (
    parsy.regex(r"[ |\t]*") << parsy.regex(r".+").should_fail("no description expected")
)
예제 #14
0
    assert result == example.rstrip()


@pytest.mark.parametrize(
    "example",
    ["dotted.path", "1name", "no-hyphens", "one two three", "A (A)", "***args"],
)
def test_var_name_invalid(example):
    with pytest.raises(parsy.ParseError):
        var_name.parse(example)


@pytest.mark.parametrize(
    "example,expected",
    [
        ("str", TypeAtom("str", [])),
        ("Dict", TypeAtom("Dict", [])),
        (
            "Dict[int, str]",
            TypeAtom("Dict", [TypeAtom("int", []), TypeAtom("str", [])]),
        ),
        (
            "Dict[int, db.models.User]",
            TypeAtom("Dict", [TypeAtom("int", []), TypeAtom("db.models.User", [])]),
        ),
        (
            "my.generic.Container[int]",
            TypeAtom("my.generic.Container", [TypeAtom("int", [])]),
        ),
        (
            "Tuple[int, ...]",