Coverage for tests / test_extensions / test_dataclasses.py: 100.00%

70 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-02-11 11:48 +0100

1"""Test the dataclasses extension.""" 

2 

3from griffe import ParameterKind, load_extensions, temporary_visited_package 

4 

5 

6def test_dataclass_support() -> None: 

7 """Test our `dataclass` support.""" 

8 code = """ 

9 from dataclasses import dataclass 

10 

11 @dataclass 

12 class Point: 

13 x: int 

14 '''Docstring for x.''' 

15 y: int 

16 '''Docstring for y.''' 

17 """ 

18 with temporary_visited_package( 

19 "pkg", 

20 {"__init__.py": code}, 

21 extensions=load_extensions("dataclasses"), 

22 ) as pkg: 

23 point = pkg["Point"] 

24 assert "__init__" in point.members 

25 init = point["__init__"] 

26 assert len(init.parameters) == 3 

27 assert "self" in init.parameters 

28 assert "x" in init.parameters 

29 assert "y" in init.parameters 

30 assert str(init.parameters["x"].annotation) == "int" 

31 assert str(init.parameters["y"].annotation) == "int" 

32 assert init.parameters["x"].docstring.value == "Docstring for x." 

33 assert init.parameters["y"].docstring.value == "Docstring for y." 

34 assert init.returns == "None" 

35 

36 

37def test_non_init_fields() -> None: 

38 """Test that non-init fields are not included in the `__init__` method.""" 

39 code = """ 

40 from dataclasses import dataclass, field 

41 

42 @dataclass 

43 class Point: 

44 x: int 

45 '''Docstring for x.''' 

46 y: int = field(init=False) 

47 '''Docstring for y.''' 

48 """ 

49 with temporary_visited_package( 

50 "pkg", 

51 {"__init__.py": code}, 

52 extensions=load_extensions("dataclasses"), 

53 ) as pkg: 

54 point = pkg["Point"] 

55 assert "__init__" in point.members 

56 init = point["__init__"] 

57 assert len(init.parameters) == 2 

58 assert "self" in init.parameters 

59 assert "x" in init.parameters 

60 assert "y" not in init.parameters 

61 

62 

63def test_classvar_fields() -> None: 

64 """Test that `ClassVar` fields are not included in the `__init__` method.""" 

65 code = """ 

66 from dataclasses import dataclass 

67 from typing import ClassVar 

68 

69 @dataclass 

70 class Point: 

71 x: int 

72 '''Docstring for x.''' 

73 y: ClassVar[int] 

74 '''Docstring for y.''' 

75 """ 

76 with temporary_visited_package( 

77 "pkg", 

78 {"__init__.py": code}, 

79 extensions=load_extensions("dataclasses"), 

80 ) as pkg: 

81 point = pkg["Point"] 

82 assert "__init__" in point.members 

83 init = point["__init__"] 

84 assert len(init.parameters) == 2 

85 assert "self" in init.parameters 

86 assert "x" in init.parameters 

87 assert "y" not in init.parameters 

88 

89 

90def test_kw_only_fields() -> None: 

91 """Test that `kw_only` fields are included as keyword-only parameters in the `__init__` method.""" 

92 code = """ 

93 from dataclasses import dataclass, field 

94 

95 @dataclass 

96 class Point: 

97 x: int 

98 '''Docstring for x.''' 

99 y: int = field(kw_only=True) 

100 '''Docstring for y.''' 

101 """ 

102 with temporary_visited_package( 

103 "pkg", 

104 {"__init__.py": code}, 

105 extensions=load_extensions("dataclasses"), 

106 ) as pkg: 

107 point = pkg["Point"] 

108 assert "__init__" in point.members 

109 init = point["__init__"] 

110 assert len(init.parameters) == 3 

111 assert "self" in init.parameters 

112 assert "x" in init.parameters 

113 assert "y" in init.parameters 

114 assert init.parameters["y"].kind is ParameterKind.keyword_only 

115 

116 

117def test_kw_only_sentinel() -> None: 

118 """Test that the `KW_ONLY` sentinel works.""" 

119 code = """ 

120 from dataclasses import dataclass, KW_ONLY 

121 

122 @dataclass 

123 class Point: 

124 x: int 

125 '''Docstring for x.''' 

126 _: KW_ONLY 

127 y: int 

128 '''Docstring for y.''' 

129 """ 

130 with temporary_visited_package( 

131 "pkg", 

132 {"__init__.py": code}, 

133 extensions=load_extensions("dataclasses"), 

134 ) as pkg: 

135 point = pkg["Point"] 

136 assert "__init__" in point.members 

137 init = point["__init__"] 

138 assert len(init.parameters) == 3 

139 assert "self" in init.parameters 

140 assert "x" in init.parameters 

141 assert "y" in init.parameters 

142 assert init.parameters["y"].kind is ParameterKind.keyword_only 

143 

144 

145def test_all_kw_only_fields() -> None: 

146 """Test that all fields can be made keyword-only.""" 

147 code = """ 

148 from dataclasses import dataclass 

149 

150 @dataclass(kw_only=True) 

151 class Point: 

152 x: int 

153 '''Docstring for x.''' 

154 y: int 

155 '''Docstring for y.''' 

156 """ 

157 with temporary_visited_package( 

158 "pkg", 

159 {"__init__.py": code}, 

160 extensions=load_extensions("dataclasses"), 

161 ) as pkg: 

162 point = pkg["Point"] 

163 assert "__init__" in point.members 

164 init = point["__init__"] 

165 assert len(init.parameters) == 3 

166 assert "self" in init.parameters 

167 assert "x" in init.parameters 

168 assert "y" in init.parameters 

169 assert init.parameters["x"].kind is ParameterKind.keyword_only 

170 assert init.parameters["y"].kind is ParameterKind.keyword_only