Пример #1
0
def test_signature_from_str_positionaly_only_args():
    sig = inspect.signature_from_str('(a, b=0, /, c=1)')
    assert list(sig.parameters.keys()) == ['a', 'b', 'c']
    assert sig.parameters['a'].kind == Parameter.POSITIONAL_ONLY
    assert sig.parameters['a'].default == Parameter.empty
    assert sig.parameters['b'].kind == Parameter.POSITIONAL_ONLY
    assert sig.parameters['b'].default == '0'
    assert sig.parameters['c'].kind == Parameter.POSITIONAL_OR_KEYWORD
    assert sig.parameters['c'].default == '1'
Пример #2
0
def test_typing_overload_from_import():
    source = ('from typing import overload\n'
              '\n'
              '@overload\n'
              'def func(x: int, y: int) -> int: pass\n'
              '\n'
              '@overload\n'
              'def func(x: str, y: str) -> str: pass\n'
              '\n'
              'def func(x, y): pass\n')
    parser = Parser(source)
    parser.parse()
    assert parser.overloads == {
        'func': [
            signature_from_str('(x: int, y: int) -> int'),
            signature_from_str('(x: str, y: str) -> str')
        ]
    }
Пример #3
0
def test_signature_from_str_annotations():
    signature = '(a: int, *args: bytes, b: str = "blah", **kwargs: float) -> None'
    sig = inspect.signature_from_str(signature)
    assert list(sig.parameters.keys()) == ['a', 'args', 'b', 'kwargs']
    assert sig.parameters['a'].annotation == "int"
    assert sig.parameters['args'].annotation == "bytes"
    assert sig.parameters['b'].annotation == "str"
    assert sig.parameters['kwargs'].annotation == "float"
    assert sig.return_annotation == 'None'
Пример #4
0
def _parse_arglist(arglist: str) -> addnodes.desc_parameterlist:
    """Parse a list of arguments using AST parser"""
    params = addnodes.desc_parameterlist(arglist)
    sig = signature_from_str('(%s)' % arglist)
    last_kind = None
    for param in sig.parameters.values():
        if param.kind != param.POSITIONAL_ONLY and last_kind == param.POSITIONAL_ONLY:
            # PEP-570: Separator for Positional Only Parameter: /
            params += addnodes.desc_parameter(
                '', '', addnodes.desc_sig_operator('', '/'))
        if param.kind == param.KEYWORD_ONLY and last_kind in (
                param.POSITIONAL_OR_KEYWORD, param.POSITIONAL_ONLY, None):
            # PEP-3102: Separator for Keyword Only Parameter: *
            params += addnodes.desc_parameter(
                '', '', addnodes.desc_sig_operator('', '*'))

        node = addnodes.desc_parameter()
        if param.kind == param.VAR_POSITIONAL:
            node += addnodes.desc_sig_operator('', '*')
            node += addnodes.desc_sig_name('', param.name)
        elif param.kind == param.VAR_KEYWORD:
            node += addnodes.desc_sig_operator('', '**')
            node += addnodes.desc_sig_name('', param.name)
        else:
            node += addnodes.desc_sig_name('', param.name)

        if param.annotation is not param.empty:
            children = _parse_annotation(param.annotation)
            node += addnodes.desc_sig_punctuation('', ':')
            node += nodes.Text(' ')
            node += addnodes.desc_sig_name('', '', *children)  # type: ignore
        if param.default is not param.empty:
            if param.annotation is not param.empty:
                node += nodes.Text(' ')
                node += addnodes.desc_sig_operator('', '=')
                node += nodes.Text(' ')
            else:
                node += addnodes.desc_sig_operator('', '=')
            node += nodes.inline('',
                                 param.default,
                                 classes=['default_value'],
                                 support_smartquotes=False)

        params += node
        last_kind = param.kind

    if last_kind == Parameter.POSITIONAL_ONLY:
        # PEP-570: Separator for Positional Only Parameter: /
        params += addnodes.desc_parameter('', '',
                                          addnodes.desc_sig_operator('', '/'))

    return params
Пример #5
0
def test_signature_from_str_default_values():
    signature = ('(a=0, b=0.0, c="str", d=b"bytes", e=..., f=True, '
                 'g=[1, 2, 3], h={"a": 1}, i={1, 2, 3}, '
                 'j=lambda x, y: None, k=None, l=object(), m=foo.bar.CONSTANT)')
    sig = inspect.signature_from_str(signature)
    assert sig.parameters['a'].default == '0'
    assert sig.parameters['b'].default == '0.0'
    assert sig.parameters['c'].default == "'str'"
    assert sig.parameters['d'].default == "b'bytes'"
    assert sig.parameters['e'].default == '...'
    assert sig.parameters['f'].default == 'True'
    assert sig.parameters['g'].default == '[1, 2, 3]'
    assert sig.parameters['h'].default == "{'a': 1}"
    assert sig.parameters['i'].default == '{1, 2, 3}'
    assert sig.parameters['j'].default == 'lambda x, y: ...'
    assert sig.parameters['k'].default == 'None'
    assert sig.parameters['l'].default == 'object()'
    assert sig.parameters['m'].default == 'foo.bar.CONSTANT'
Пример #6
0
def _cleanup_signature(s: str) -> str:
    """Clean up signature using inspect.signautre() for mangle_signature()"""
    try:
        sig = signature_from_str(s)
        parameters = list(sig.parameters.values())
        for i, param in enumerate(parameters):
            if param.annotation is not Parameter.empty:
                # Remove typehints
                param = param.replace(annotation=Parameter.empty)
            if param.default is not Parameter.empty:
                # Replace default value by "None"
                param = param.replace(default=None)
            parameters[i] = param
        sig = sig.replace(parameters=parameters, return_annotation=Parameter.empty)
        return str(sig)
    except Exception:
        # Return the original signature string if failed to clean (ex. parsing error)
        return s
Пример #7
0
def _parse_arglist(arglist: str) -> addnodes.desc_parameterlist:
    """Parse a list of arguments using AST parser"""
    params = addnodes.desc_parameterlist(arglist)
    sig = signature_from_str('(%s)' % arglist)
    last_kind = None
    for param in sig.parameters.values():
        if param.kind != param.POSITIONAL_ONLY and last_kind == param.POSITIONAL_ONLY:
            # PEP-570: Separator for Positional Only Parameter: /
            params += addnodes.desc_parameter('', nodes.Text('/'))
        if param.kind == param.KEYWORD_ONLY and last_kind in (param.POSITIONAL_OR_KEYWORD,
                                                              param.POSITIONAL_ONLY,
                                                              None):
            # PEP-3102: Separator for Keyword Only Parameter: *
            params += addnodes.desc_parameter('', nodes.Text('*'))

        node = addnodes.desc_parameter()
        if param.kind == param.VAR_POSITIONAL:
            node += nodes.Text('*' + param.name)
        elif param.kind == param.VAR_KEYWORD:
            node += nodes.Text('**' + param.name)
        else:
            node += nodes.Text(param.name)

        if param.annotation is not param.empty:
            node += nodes.Text(': ' + param.annotation)
        if param.default is not param.empty:
            if param.annotation is not param.empty:
                node += nodes.Text(' = ' + str(param.default))
            else:
                node += nodes.Text('=' + str(param.default))

        params += node
        last_kind = param.kind

    if last_kind == Parameter.POSITIONAL_ONLY:
        # PEP-570: Separator for Positional Only Parameter: /
        params += addnodes.desc_parameter('', nodes.Text('/'))

    return params
Пример #8
0
def test_signature_from_str_invalid():
    with pytest.raises(SyntaxError):
        inspect.signature_from_str('')
Пример #9
0
def test_signature_from_str_complex_annotations():
    sig = inspect.signature_from_str('() -> Tuple[str, int, ...]')
    assert sig.return_annotation == 'Tuple[str, int, ...]'

    sig = inspect.signature_from_str('() -> Callable[[int, int], int]')
    assert sig.return_annotation == 'Callable[[int, int], int]'
Пример #10
0
def test_signature_from_str_positionaly_only_args():
    sig = inspect.signature_from_str('(a, /, b)')
    assert list(sig.parameters.keys()) == ['a', 'b']
    assert sig.parameters['a'].kind == Parameter.POSITIONAL_ONLY
    assert sig.parameters['b'].kind == Parameter.POSITIONAL_OR_KEYWORD