Coverage for tests/test_expressions.py: 100.00%

27 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2024-08-15 16:47 +0200

1"""Test names and expressions methods.""" 

2 

3from __future__ import annotations 

4 

5import ast 

6 

7import pytest 

8 

9from griffe import Module, Parser, get_expression, temporary_visited_module 

10from tests.test_nodes import syntax_examples 

11 

12 

13@pytest.mark.parametrize( 

14 ("annotation", "items"), 

15 [ 

16 ("tuple[int, float] | None", 2), 

17 ("None | tuple[int, float]", 2), 

18 ("Optional[tuple[int, float]]", 2), 

19 ("typing.Optional[tuple[int, float]]", 2), 

20 ], 

21) 

22def test_explode_return_annotations(annotation: str, items: int) -> None: 

23 """Check that we correctly split items from return annotations. 

24 

25 Parameters: 

26 annotation: The return annotation. 

27 items: The number of items to write in the docstring returns section. 

28 """ 

29 newline = "\n " 

30 returns = newline.join(f"x{_}: Some value." for _ in range(items)) 

31 code = f""" 

32 import typing 

33 from typing import Optional 

34 

35 def function() -> {annotation}: 

36 '''This function returns either two ints or None 

37 

38 Returns: 

39 {returns} 

40 ''' 

41 """ 

42 with temporary_visited_module(code) as module: 

43 sections = module["function"].docstring.parse(Parser.google) 

44 assert sections[1].value 

45 

46 

47@pytest.mark.parametrize( 

48 "annotation", 

49 [ 

50 "int", 

51 "tuple[int]", 

52 "dict[str, str]", 

53 "Optional[tuple[int, float]]", 

54 ], 

55) 

56def test_full_expressions(annotation: str) -> None: 

57 """Assert we can transform expressions to their full form without errors.""" 

58 code = f"x: {annotation}" 

59 with temporary_visited_module(code) as module: 

60 assert str(module["x"].annotation) == annotation 

61 

62 

63def test_resolving_full_names() -> None: 

64 """Assert expressions are correctly transformed to their fully-resolved form.""" 

65 with temporary_visited_module( 

66 """ 

67 from package import module 

68 attribute1: module.Class 

69 

70 from package import module as mod 

71 attribute2: mod.Class 

72 """, 

73 ) as module: 

74 assert module["attribute1"].annotation.canonical_path == "package.module.Class" 

75 assert module["attribute2"].annotation.canonical_path == "package.module.Class" 

76 

77 

78@pytest.mark.parametrize("code", syntax_examples) 

79def test_expressions(code: str) -> None: 

80 """Test building annotations from AST nodes. 

81 

82 Parameters: 

83 code: An expression (parametrized). 

84 """ 

85 top_node = compile(code, filename="<>", mode="exec", flags=ast.PyCF_ONLY_AST, optimize=2) 

86 expression = get_expression(top_node.body[0].value, parent=Module("module")) # type: ignore[attr-defined] 

87 assert str(expression) == code