2020-10-08 05:46:58 +00:00
|
|
|
import sys
|
|
|
|
|
2017-09-12 17:59:21 +00:00
|
|
|
import astroid
|
2024-03-26 04:14:35 +00:00
|
|
|
from autoapi import _astroid_utils
|
|
|
|
from autoapi import _objects
|
2017-09-12 17:59:21 +00:00
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
|
|
def generate_module_names():
|
|
|
|
for i in range(1, 5):
|
2019-01-27 05:20:45 +00:00
|
|
|
yield ".".join("module{}".format(j) for j in range(i))
|
2017-09-12 17:59:21 +00:00
|
|
|
|
2019-01-27 05:20:45 +00:00
|
|
|
yield "package.repeat.repeat"
|
2017-09-12 17:59:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
def imported_basename_cases():
|
|
|
|
for module_name in generate_module_names():
|
2019-01-27 05:20:45 +00:00
|
|
|
import_ = "import {}".format(module_name)
|
|
|
|
basename = "{}.ImportedClass".format(module_name)
|
2017-09-12 17:59:21 +00:00
|
|
|
expected = basename
|
|
|
|
|
|
|
|
yield (import_, basename, expected)
|
|
|
|
|
2019-01-27 05:20:45 +00:00
|
|
|
import_ = "import {} as aliased".format(module_name)
|
|
|
|
basename = "aliased.ImportedClass"
|
2017-09-12 17:59:21 +00:00
|
|
|
|
|
|
|
yield (import_, basename, expected)
|
|
|
|
|
2019-01-27 05:20:45 +00:00
|
|
|
if "." in module_name:
|
|
|
|
from_name, attribute = module_name.rsplit(".", 1)
|
|
|
|
import_ = "from {} import {}".format(from_name, attribute)
|
|
|
|
basename = "{}.ImportedClass".format(attribute)
|
2017-09-12 17:59:21 +00:00
|
|
|
yield (import_, basename, expected)
|
|
|
|
|
2019-01-27 05:20:45 +00:00
|
|
|
import_ += " as aliased"
|
|
|
|
basename = "aliased.ImportedClass"
|
2017-09-12 17:59:21 +00:00
|
|
|
yield (import_, basename, expected)
|
|
|
|
|
2019-01-27 05:20:45 +00:00
|
|
|
import_ = "from {} import ImportedClass".format(module_name)
|
|
|
|
basename = "ImportedClass"
|
2017-09-12 17:59:21 +00:00
|
|
|
yield (import_, basename, expected)
|
|
|
|
|
2019-01-27 05:20:45 +00:00
|
|
|
import_ = "from {} import ImportedClass as AliasedClass".format(module_name)
|
|
|
|
basename = "AliasedClass"
|
2017-09-12 17:59:21 +00:00
|
|
|
yield (import_, basename, expected)
|
|
|
|
|
|
|
|
|
|
|
|
def generate_args():
|
|
|
|
for i in range(5):
|
2019-01-27 05:20:45 +00:00
|
|
|
yield ", ".join("arg{}".format(j) for j in range(i))
|
2017-09-12 17:59:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
def imported_call_cases():
|
|
|
|
for args in generate_args():
|
|
|
|
for import_, basename, expected in imported_basename_cases():
|
2019-01-27 05:20:45 +00:00
|
|
|
basename += "({})".format(args)
|
|
|
|
expected += "()"
|
2017-09-12 17:59:21 +00:00
|
|
|
yield import_, basename, expected
|
|
|
|
|
|
|
|
|
2021-04-04 02:01:27 +00:00
|
|
|
class TestAstroidUtils:
|
2017-09-12 17:59:21 +00:00
|
|
|
@pytest.mark.parametrize(
|
2019-01-27 05:20:45 +00:00
|
|
|
("import_", "basename", "expected"), list(imported_basename_cases())
|
2017-09-12 17:59:21 +00:00
|
|
|
)
|
|
|
|
def test_can_get_full_imported_basename(self, import_, basename, expected):
|
2019-01-27 05:20:45 +00:00
|
|
|
source = """
|
2017-09-12 17:59:21 +00:00
|
|
|
{}
|
|
|
|
class ThisClass({}): #@
|
|
|
|
pass
|
2019-01-27 05:20:45 +00:00
|
|
|
""".format(
|
|
|
|
import_, basename
|
2017-09-12 17:59:21 +00:00
|
|
|
)
|
2019-01-27 05:20:45 +00:00
|
|
|
node = astroid.extract_node(source)
|
2024-03-26 04:14:35 +00:00
|
|
|
basenames = _astroid_utils.resolve_qualname(node.bases[0], node.basenames[0])
|
2017-09-12 17:59:21 +00:00
|
|
|
assert basenames == expected
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
2019-01-27 05:20:45 +00:00
|
|
|
("import_", "basename", "expected"), list(imported_call_cases())
|
2017-09-12 17:59:21 +00:00
|
|
|
)
|
|
|
|
def test_can_get_full_function_basename(self, import_, basename, expected):
|
2019-01-27 05:20:45 +00:00
|
|
|
source = """
|
2017-09-12 17:59:21 +00:00
|
|
|
{}
|
|
|
|
class ThisClass({}): #@
|
|
|
|
pass
|
2019-01-27 05:20:45 +00:00
|
|
|
""".format(
|
|
|
|
import_, basename
|
2017-09-12 17:59:21 +00:00
|
|
|
)
|
2019-01-27 05:20:45 +00:00
|
|
|
node = astroid.extract_node(source)
|
2024-03-26 04:14:35 +00:00
|
|
|
basenames = _astroid_utils.resolve_qualname(node.bases[0], node.basenames[0])
|
2017-09-12 17:59:21 +00:00
|
|
|
assert basenames == expected
|
|
|
|
|
2019-01-27 05:20:45 +00:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
("source", "expected"),
|
|
|
|
[
|
2024-04-02 05:23:52 +00:00
|
|
|
('a = "a"', ("a", "'a'")),
|
|
|
|
("a = 1", ("a", "1")),
|
2019-01-27 05:20:45 +00:00
|
|
|
("a, b, c = (1, 2, 3)", None),
|
|
|
|
("a = b = 1", None),
|
2024-04-02 05:23:52 +00:00
|
|
|
("a = [1, 2, [3, 4]]", ("a", "[1, 2, [3, 4]]")),
|
|
|
|
("a = [1, 2, variable[subscript]]", ("a", None)),
|
|
|
|
('a = """multiline\nstring"""', ("a", '"""multiline\nstring"""')),
|
|
|
|
('a = ["""multiline\nstring"""]', ("a", None)),
|
|
|
|
("a = (1, 2, 3)", ("a", "(1, 2, 3)")),
|
|
|
|
("a = (1, 'two', 3)", ("a", "(1, 'two', 3)")),
|
|
|
|
("a = None", ("a", "None")),
|
2019-01-27 05:20:45 +00:00
|
|
|
],
|
|
|
|
)
|
2017-09-12 17:59:21 +00:00
|
|
|
def test_can_get_assign_values(self, source, expected):
|
|
|
|
node = astroid.extract_node(source)
|
2024-03-26 04:14:35 +00:00
|
|
|
value = _astroid_utils.get_assign_value(node)
|
2017-09-12 17:59:21 +00:00
|
|
|
assert value == expected
|
2020-10-08 05:18:43 +00:00
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"signature,expected",
|
|
|
|
[
|
2021-04-03 02:24:18 +00:00
|
|
|
(
|
|
|
|
"a: bool, b: int = 5",
|
|
|
|
[(None, "a", "bool", None), (None, "b", "int", "5")],
|
|
|
|
),
|
2020-10-08 05:46:58 +00:00
|
|
|
pytest.param(
|
|
|
|
"a: bool, /, b: int, *, c: str",
|
2021-04-03 02:24:18 +00:00
|
|
|
[
|
|
|
|
(None, "a", "bool", None),
|
|
|
|
("/", None, None, None),
|
|
|
|
(None, "b", "int", None),
|
|
|
|
("*", None, None, None),
|
|
|
|
(None, "c", "str", None),
|
|
|
|
],
|
2020-10-08 05:46:58 +00:00
|
|
|
marks=pytest.mark.skipif(
|
|
|
|
sys.version_info[:2] < (3, 8), reason="Uses Python 3.8+ syntax"
|
|
|
|
),
|
|
|
|
),
|
|
|
|
pytest.param(
|
2020-10-08 05:18:43 +00:00
|
|
|
"a: bool, /, b: int, *args, c: str, **kwargs",
|
2021-04-03 02:24:18 +00:00
|
|
|
[
|
|
|
|
(None, "a", "bool", None),
|
|
|
|
("/", None, None, None),
|
|
|
|
(None, "b", "int", None),
|
|
|
|
("*", "args", None, None),
|
|
|
|
(None, "c", "str", None),
|
|
|
|
("**", "kwargs", None, None),
|
|
|
|
],
|
2020-10-08 05:46:58 +00:00
|
|
|
marks=pytest.mark.skipif(
|
|
|
|
sys.version_info[:2] < (3, 8), reason="Uses Python 3.8+ syntax"
|
|
|
|
),
|
|
|
|
),
|
|
|
|
pytest.param(
|
|
|
|
"a: int, *args, b: str, **kwargs",
|
2021-04-03 02:24:18 +00:00
|
|
|
[
|
|
|
|
(None, "a", "int", None),
|
|
|
|
("*", "args", None, None),
|
|
|
|
(None, "b", "str", None),
|
|
|
|
("**", "kwargs", None, None),
|
|
|
|
],
|
2020-10-08 05:46:58 +00:00
|
|
|
marks=pytest.mark.skipif(
|
|
|
|
sys.version_info[:2] < (3, 8), reason="Uses Python 3.8+ syntax"
|
|
|
|
),
|
2020-10-08 05:18:43 +00:00
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_parse_annotations(self, signature, expected):
|
|
|
|
node = astroid.extract_node(
|
|
|
|
"""
|
|
|
|
def func({}) -> str: #@
|
|
|
|
pass
|
|
|
|
""".format(
|
|
|
|
signature
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2024-03-26 04:14:35 +00:00
|
|
|
annotations = _astroid_utils.get_args_info(node.args)
|
2020-10-08 05:18:43 +00:00
|
|
|
assert annotations == expected
|
|
|
|
|
2023-05-31 02:03:32 +00:00
|
|
|
def test_parse_split_type_comments(self):
|
|
|
|
node = astroid.extract_node(
|
|
|
|
"""
|
|
|
|
def func(
|
|
|
|
a, # type: int
|
|
|
|
b, # type: int
|
|
|
|
): # type: (...) -> str
|
|
|
|
pass
|
|
|
|
"""
|
|
|
|
)
|
|
|
|
|
2024-03-26 04:14:35 +00:00
|
|
|
annotations = _astroid_utils.get_args_info(node.args)
|
2023-05-31 02:03:32 +00:00
|
|
|
|
|
|
|
expected = [
|
|
|
|
(None, "a", "int", None),
|
|
|
|
(None, "b", "int", None),
|
|
|
|
]
|
|
|
|
assert annotations == expected
|
|
|
|
|
2020-10-08 05:18:43 +00:00
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"signature,expected",
|
|
|
|
[
|
|
|
|
("a: bool, b: int = 5, c='hi'", "a: bool, b: int = 5, c='hi'"),
|
2020-10-08 05:46:58 +00:00
|
|
|
pytest.param(
|
|
|
|
"a: bool, /, b: int, *, c: str",
|
|
|
|
"a: bool, /, b: int, *, c: str",
|
|
|
|
marks=pytest.mark.skipif(
|
|
|
|
sys.version_info[:2] < (3, 8), reason="Uses Python 3.8+ syntax"
|
|
|
|
),
|
|
|
|
),
|
|
|
|
pytest.param(
|
2020-10-08 05:18:43 +00:00
|
|
|
"a: bool, /, b: int, *args, c: str, **kwargs",
|
|
|
|
"a: bool, /, b: int, *args, c: str, **kwargs",
|
2020-10-08 05:46:58 +00:00
|
|
|
marks=pytest.mark.skipif(
|
|
|
|
sys.version_info[:2] < (3, 8), reason="Uses Python 3.8+ syntax"
|
|
|
|
),
|
2020-10-08 05:18:43 +00:00
|
|
|
),
|
2022-05-31 07:45:54 +00:00
|
|
|
pytest.param(
|
|
|
|
"*, a: int, b: int",
|
|
|
|
"*, a: int, b: int",
|
|
|
|
marks=pytest.mark.skipif(
|
|
|
|
sys.version_info[:2] < (3, 8), reason="Uses Python 3.8+ syntax"
|
|
|
|
),
|
|
|
|
),
|
2020-10-08 05:18:43 +00:00
|
|
|
("a: int, *args, b: str, **kwargs", "a: int, *args, b: str, **kwargs"),
|
|
|
|
("a: 'A'", "a: A"),
|
2024-03-03 07:19:09 +00:00
|
|
|
("a: Literal[1]", "a: Literal[1]"),
|
|
|
|
("a: Literal['x']", "a: Literal['x']"),
|
|
|
|
("a: Literal['x', 'y', 'z']", "a: Literal['x', 'y', 'z']"),
|
2020-10-08 05:18:43 +00:00
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_format_args(self, signature, expected):
|
|
|
|
node = astroid.extract_node(
|
|
|
|
"""
|
|
|
|
def func({}) -> str: #@
|
|
|
|
pass
|
|
|
|
""".format(
|
|
|
|
signature
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2024-03-26 04:14:35 +00:00
|
|
|
args_info = _astroid_utils.get_args_info(node.args)
|
|
|
|
formatted = _objects._format_args(args_info)
|
2020-10-08 05:18:43 +00:00
|
|
|
assert formatted == expected
|