49
49
T = TypeVar ("T" )
50
50
U = TypeVar ("U" , covariant = True )
51
51
V = TypeVar ("V" , contravariant = True )
52
+ X = TypeVar ("X" , str , int )
53
+ Y = TypeVar ("Y" , bound = str )
54
+ Z = TypeVar ("Z" , bound = "A" )
55
+ S = TypeVar ("S" , bound = "miss" ) # type: ignore # miss not defined on purpose # noqa: F821
52
56
W = NewType ("W" , str )
53
57
54
58
@@ -61,8 +65,7 @@ class Inner:
61
65
62
66
63
67
class B (Generic [T ]):
64
- # This is set to make sure the correct class name ("B") is picked up
65
- name = "Foo"
68
+ name = "Foo" # This is set to make sure the correct class name ("B") is picked up
66
69
67
70
68
71
class C (B [str ]):
@@ -147,21 +150,35 @@ def test_parse_annotation(annotation: Any, module: str, class_name: str, args: t
147
150
(Type [A ], ":py:class:`~typing.Type`\\ [:py:class:`~%s.A`]" % __name__ ),
148
151
(Any , ":py:data:`~typing.Any`" ),
149
152
(AnyStr , ":py:data:`~typing.AnyStr`" ),
150
- (Generic [T ], ":py:class:`~typing.Generic`\\ [\\ ~T ]" ),
153
+ (Generic [T ], ":py:class:`~typing.Generic`\\ [:py:class:`~typing.TypeVar` \\ (``T``) ]" ),
151
154
(Mapping , ":py:class:`~typing.Mapping`" ),
152
- (Mapping [T , int ], ":py:class:`~typing.Mapping`\\ [\\ ~T, :py:class:`int`]" ),
153
- (Mapping [str , V ], ":py:class:`~typing.Mapping`\\ [:py:class:`str`, \\ -V]" ),
154
- (Mapping [T , U ], ":py:class:`~typing.Mapping`\\ [\\ ~T, \\ +U]" ),
155
+ (Mapping [T , int ], ":py:class:`~typing.Mapping`\\ [:py:class:`~typing.TypeVar`\\ (``T``), :py:class:`int`]" ),
156
+ (
157
+ Mapping [str , V ],
158
+ ":py:class:`~typing.Mapping`\\ [:py:class:`str`, :py:class:`~typing.TypeVar`\\ (``V``, contravariant=True)]" ,
159
+ ),
160
+ (
161
+ Mapping [T , U ],
162
+ ":py:class:`~typing.Mapping`\\ [:py:class:`~typing.TypeVar`\\ (``T``), "
163
+ ":py:class:`~typing.TypeVar`\\ (``U``, covariant=True)]" ,
164
+ ),
155
165
(Mapping [str , bool ], ":py:class:`~typing.Mapping`\\ [:py:class:`str`, " ":py:class:`bool`]" ),
156
166
(Dict , ":py:class:`~typing.Dict`" ),
157
- (Dict [T , int ], ":py:class:`~typing.Dict`\\ [\\ ~T, :py:class:`int`]" ),
158
- (Dict [str , V ], ":py:class:`~typing.Dict`\\ [:py:class:`str`, \\ -V]" ),
159
- (Dict [T , U ], ":py:class:`~typing.Dict`\\ [\\ ~T, \\ +U]" ),
167
+ (Dict [T , int ], ":py:class:`~typing.Dict`\\ [:py:class:`~typing.TypeVar`\\ (``T``), :py:class:`int`]" ),
168
+ (
169
+ Dict [str , V ],
170
+ ":py:class:`~typing.Dict`\\ [:py:class:`str`, :py:class:`~typing.TypeVar`\\ (``V``, contravariant=True)]" ,
171
+ ),
172
+ (
173
+ Dict [T , U ],
174
+ ":py:class:`~typing.Dict`\\ [:py:class:`~typing.TypeVar`\\ (``T``),"
175
+ " :py:class:`~typing.TypeVar`\\ (``U``, covariant=True)]" ,
176
+ ),
160
177
(Dict [str , bool ], ":py:class:`~typing.Dict`\\ [:py:class:`str`, " ":py:class:`bool`]" ),
161
178
(Tuple , ":py:data:`~typing.Tuple`" ),
162
179
(Tuple [str , bool ], ":py:data:`~typing.Tuple`\\ [:py:class:`str`, " ":py:class:`bool`]" ),
163
180
(Tuple [int , int , int ], ":py:data:`~typing.Tuple`\\ [:py:class:`int`, " ":py:class:`int`, :py:class:`int`]" ),
164
- (Tuple [str , ...], ":py:data:`~typing.Tuple`\\ [:py:class:`str`, ...]" ),
181
+ (Tuple [str , ...], ":py:data:`~typing.Tuple`\\ [:py:class:`str`, :py:data:` ...<Ellipsis>` ]" ),
165
182
(Union , ":py:data:`~typing.Union`" ),
166
183
(Union [str , bool ], ":py:data:`~typing.Union`\\ [:py:class:`str`, " ":py:class:`bool`]" ),
167
184
(Union [str , bool , None ], ":py:data:`~typing.Union`\\ [:py:class:`str`, " ":py:class:`bool`, :py:obj:`None`]" ),
@@ -178,7 +195,7 @@ def test_parse_annotation(annotation: Any, module: str, class_name: str, args: t
178
195
":py:data:`~typing.Union`\\ [:py:class:`str`, " ":py:class:`bool`, :py:obj:`None`]" ,
179
196
),
180
197
(Callable , ":py:data:`~typing.Callable`" ),
181
- (Callable [..., int ], ":py:data:`~typing.Callable`\\ [..., :py:class:`int`]" ),
198
+ (Callable [..., int ], ":py:data:`~typing.Callable`\\ [:py:data:` ...<Ellipsis>` , :py:class:`int`]" ),
182
199
(Callable [[int ], int ], ":py:data:`~typing.Callable`\\ [\\ [:py:class:`int`], " ":py:class:`int`]" ),
183
200
(
184
201
Callable [[int , str ], bool ],
@@ -188,7 +205,11 @@ def test_parse_annotation(annotation: Any, module: str, class_name: str, args: t
188
205
Callable [[int , str ], None ],
189
206
":py:data:`~typing.Callable`\\ [\\ [:py:class:`int`, " ":py:class:`str`], :py:obj:`None`]" ,
190
207
),
191
- (Callable [[T ], T ], ":py:data:`~typing.Callable`\\ [\\ [\\ ~T], \\ ~T]" ),
208
+ (
209
+ Callable [[T ], T ],
210
+ ":py:data:`~typing.Callable`\\ [\\ [:py:class:`~typing.TypeVar`\\ (``T``)],"
211
+ " :py:class:`~typing.TypeVar`\\ (``T``)]" ,
212
+ ),
192
213
(Pattern , ":py:class:`~typing.Pattern`" ),
193
214
(Pattern [str ], ":py:class:`~typing.Pattern`\\ [:py:class:`str`]" ),
194
215
(IO , ":py:class:`~typing.IO`" ),
@@ -202,14 +223,21 @@ def test_parse_annotation(annotation: Any, module: str, class_name: str, args: t
202
223
(E , ":py:class:`~%s.E`" % __name__ ),
203
224
(E [int ], ":py:class:`~%s.E`\\ [:py:class:`int`]" % __name__ ),
204
225
(W , f':py:{ "class" if PY310_PLUS else "func" } :' f"`~typing.NewType`\\ (``W``, :py:class:`str`)" ),
226
+ (T , ":py:class:`~typing.TypeVar`\\ (``T``)" ),
227
+ (U , ":py:class:`~typing.TypeVar`\\ (``U``, covariant=True)" ),
228
+ (V , ":py:class:`~typing.TypeVar`\\ (``V``, contravariant=True)" ),
229
+ (X , ":py:class:`~typing.TypeVar`\\ (``X``, :py:class:`str`, :py:class:`int`)" ),
230
+ (Y , ":py:class:`~typing.TypeVar`\\ (``Y``, bound= :py:class:`str`)" ),
231
+ (Z , ":py:class:`~typing.TypeVar`\\ (``Z``, bound= :py:class:`~test_sphinx_autodoc_typehints.A`)" ),
232
+ (S , ":py:class:`~typing.TypeVar`\\ (``S``, bound= miss)" ),
205
233
# ## These test for correct internal tuple rendering, even if not all are valid Tuple types
206
234
# Zero-length tuple remains
207
235
(Tuple [()], ":py:data:`~typing.Tuple`\\ [()]" ),
208
236
# Internal single tuple with simple types is flattened in the output
209
237
(Tuple [(int ,)], ":py:data:`~typing.Tuple`\\ [:py:class:`int`]" ),
210
238
(Tuple [(int , int )], ":py:data:`~typing.Tuple`\\ [:py:class:`int`, :py:class:`int`]" ),
211
239
# Ellipsis in single tuple also gets flattened
212
- (Tuple [(int , ...)], ":py:data:`~typing.Tuple`\\ [:py:class:`int`, ...]" ),
240
+ (Tuple [(int , ...)], ":py:data:`~typing.Tuple`\\ [:py:class:`int`, :py:data:` ...<Ellipsis>` ]" ),
213
241
# Internal tuple with following additional type cannot be flattened (specific to nptyping?)
214
242
# These cases will fail if nptyping restructures its internal module hierarchy
215
243
(
@@ -236,7 +264,7 @@ def test_parse_annotation(annotation: Any, module: str, class_name: str, args: t
236
264
(
237
265
nptyping .NDArray [(Any , ...), nptyping .Float ],
238
266
(
239
- ":py:class:`~nptyping.types._ndarray.NDArray`\\ [(:py:data:`~typing.Any`, ...), "
267
+ ":py:class:`~nptyping.types._ndarray.NDArray`\\ [(:py:data:`~typing.Any`, :py:data:` ...<Ellipsis>` ), "
240
268
":py:class:`~nptyping.types._number.Float`]"
241
269
),
242
270
),
@@ -249,12 +277,15 @@ def test_parse_annotation(annotation: Any, module: str, class_name: str, args: t
249
277
),
250
278
(
251
279
nptyping .NDArray [(3 , ...), nptyping .Float ],
252
- (":py:class:`~nptyping.types._ndarray.NDArray`\\ [(3, ...), :py:class:`~nptyping.types._number.Float`]" ),
280
+ (
281
+ ":py:class:`~nptyping.types._ndarray.NDArray`\\ [(3, :py:data:`...<Ellipsis>`),"
282
+ " :py:class:`~nptyping.types._number.Float`]"
283
+ ),
253
284
),
254
285
],
255
286
)
256
287
def test_format_annotation (inv : Inventory , annotation : Any , expected_result : str ) -> None :
257
- conf = create_autospec (Config )
288
+ conf = create_autospec (Config , _annotation_globals = globals () )
258
289
result = format_annotation (annotation , conf )
259
290
assert result == expected_result
260
291
@@ -266,21 +297,23 @@ def test_format_annotation(inv: Inventory, annotation: Any, expected_result: str
266
297
# encapsulate Union in typing.Optional
267
298
expected_result_not_simplified = ":py:data:`~typing.Optional`\\ [" + expected_result_not_simplified
268
299
expected_result_not_simplified += "]"
269
- conf = create_autospec (Config , simplify_optional_unions = False )
300
+ conf = create_autospec (Config , simplify_optional_unions = False , _annotation_globals = globals () )
270
301
assert format_annotation (annotation , conf ) == expected_result_not_simplified
271
302
272
303
# Test with the "fully_qualified" flag turned on
273
304
if "typing" in expected_result_not_simplified :
274
305
expected_result_not_simplified = expected_result_not_simplified .replace ("~typing" , "typing" )
275
- conf = create_autospec (Config , typehints_fully_qualified = True , simplify_optional_unions = False )
306
+ conf = create_autospec (
307
+ Config , typehints_fully_qualified = True , simplify_optional_unions = False , _annotation_globals = globals ()
308
+ )
276
309
assert format_annotation (annotation , conf ) == expected_result_not_simplified
277
310
278
311
# Test with the "fully_qualified" flag turned on
279
312
if "typing" in expected_result or "nptyping" in expected_result or __name__ in expected_result :
280
313
expected_result = expected_result .replace ("~typing" , "typing" )
281
314
expected_result = expected_result .replace ("~nptyping" , "nptyping" )
282
315
expected_result = expected_result .replace ("~" + __name__ , __name__ )
283
- conf = create_autospec (Config , typehints_fully_qualified = True )
316
+ conf = create_autospec (Config , typehints_fully_qualified = True , _annotation_globals = globals () )
284
317
assert format_annotation (annotation , conf ) == expected_result
285
318
286
319
# Test for the correct role (class vs data) using the official Sphinx inventory
0 commit comments