15
15
DocstringRaise ,
16
16
DocstringReturn ,
17
17
DocstringSectionKind ,
18
+ Expr ,
19
+ ExprBinOp ,
20
+ ExprName ,
18
21
Function ,
19
22
Module ,
20
23
Parameter ,
@@ -231,28 +234,62 @@ def test_parse__param_field_docs_type__param_section_with_type(parse_sphinx: Par
231
234
assert actual .as_dict () == expected .as_dict ()
232
235
233
236
234
- def test_parse__param_field_type_field__param_section_with_type (parse_sphinx : ParserType ) -> None :
237
+ @pytest .mark .parametrize ("type_" , ["str" , "int" ])
238
+ def test_parse__param_field_type_field__param_section_with_type (parse_sphinx : ParserType , type_ : str ) -> None :
235
239
"""Parse parameters with separated types.
236
240
237
241
Parameters:
238
242
parse_sphinx: Fixture parser.
243
+ type_: The type to use in the type directive.
239
244
"""
240
245
docstring = f"""
241
246
Docstring with line continuation.
242
247
243
- :param foo : { SOME_TEXT }
244
- :type foo: str
248
+ :param { SOME_NAME } : { SOME_TEXT }
249
+ :type { SOME_NAME } : { type_ }
245
250
"""
246
251
247
252
sections , _ = parse_sphinx (docstring )
248
253
assert len (sections ) == 2
249
254
assert sections [1 ].kind is DocstringSectionKind .parameters
250
255
actual = sections [1 ].value [0 ]
251
- expected = DocstringParameter (SOME_NAME , annotation = "str " , description = SOME_TEXT )
256
+ expected = DocstringParameter (SOME_NAME , annotation = f" { type_ } " , description = SOME_TEXT )
252
257
assert isinstance (actual , type (expected ))
253
258
assert actual .as_dict () == expected .as_dict ()
254
259
255
260
261
+ @pytest .mark .parametrize ("type_" , ["str" , "int" ])
262
+ def test_parse__param_field_type_field__param_section_with_type_with_parent (
263
+ parse_sphinx : ParserType ,
264
+ type_ : str ,
265
+ ) -> None :
266
+ """Parse parameters with separated types.
267
+
268
+ Parameters:
269
+ parse_sphinx: Fixture parser.
270
+ type_: The type to use in the type directive.
271
+ """
272
+ docstring = f"""
273
+ Docstring with line continuation.
274
+
275
+ :param { SOME_NAME } : { SOME_TEXT }
276
+ :type { SOME_NAME } : { type_ }
277
+ """
278
+ parent_fn = Function ("func" , parameters = Parameters (Parameter (SOME_NAME )))
279
+ sections , _ = parse_sphinx (docstring , parent = parent_fn )
280
+ assert len (sections ) == 2
281
+ assert sections [1 ].kind is DocstringSectionKind .parameters
282
+ actual = sections [1 ].value [0 ]
283
+ expected_annotation = ExprName (name = f"{ type_ } " )
284
+ expected = DocstringParameter (SOME_NAME , annotation = expected_annotation , description = SOME_TEXT )
285
+ assert isinstance (actual , type (expected ))
286
+ assert actual .as_dict () == expected .as_dict ()
287
+ assert isinstance (actual .annotation , type (expected .annotation ))
288
+ assert isinstance (actual .annotation , ExprName )
289
+ assert isinstance (actual .annotation , Expr )
290
+ assert actual .annotation .as_dict () == expected_annotation .as_dict ()
291
+
292
+
256
293
def test_parse__param_field_type_field_first__param_section_with_type (parse_sphinx : ParserType ) -> None :
257
294
"""Parse parameters with separated types first.
258
295
@@ -275,6 +312,33 @@ def test_parse__param_field_type_field_first__param_section_with_type(parse_sphi
275
312
assert actual .as_dict () == expected .as_dict ()
276
313
277
314
315
+ def test_parse__param_field_type_field_first__param_section_with_type_with_parent (parse_sphinx : ParserType ) -> None :
316
+ """Parse parameters with separated types first.
317
+
318
+ Parameters:
319
+ parse_sphinx: Fixture parser.
320
+ """
321
+ docstring = f"""
322
+ Docstring with line continuation.
323
+
324
+ :type { SOME_NAME } : str
325
+ :param { SOME_NAME } : { SOME_TEXT }
326
+ """
327
+ parent_fn = Function ("func" , parameters = Parameters (Parameter (SOME_NAME )))
328
+ sections , _ = parse_sphinx (docstring , parent = parent_fn )
329
+ assert len (sections ) == 2
330
+ assert sections [1 ].kind is DocstringSectionKind .parameters
331
+ actual = sections [1 ].value [0 ]
332
+ expected_annotation = ExprName ("str" , parent = Class ("C" ))
333
+ expected = DocstringParameter (SOME_NAME , annotation = expected_annotation , description = SOME_TEXT )
334
+ assert isinstance (actual , type (expected ))
335
+ assert actual .as_dict () == expected .as_dict ()
336
+ assert isinstance (actual .annotation , type (expected .annotation ))
337
+ assert isinstance (actual .annotation , ExprName )
338
+ assert isinstance (actual .annotation , Expr )
339
+ assert actual .annotation .as_dict () == expected_annotation .as_dict ()
340
+
341
+
278
342
@pytest .mark .parametrize ("union" , ["str or None" , "None or str" , "str or int" , "str or int or float" ])
279
343
def test_parse__param_field_type_field_or_none__param_section_with_optional (
280
344
parse_sphinx : ParserType ,
@@ -302,6 +366,47 @@ def test_parse__param_field_type_field_or_none__param_section_with_optional(
302
366
assert actual .as_dict () == expected .as_dict ()
303
367
304
368
369
+ @pytest .mark .parametrize (
370
+ ("union" , "expected_annotation" ),
371
+ [
372
+ ("str or None" , ExprBinOp (ExprName ("str" ), "|" , "None" )),
373
+ ("None or str" , ExprBinOp ("None" , "|" , ExprName ("str" ))),
374
+ ("str or int" , ExprBinOp (ExprName ("str" ), "|" , ExprName ("int" ))),
375
+ ("str or int or float" , ExprBinOp (ExprBinOp (ExprName ("str" ), "|" , ExprName ("int" )), "|" , ExprName ("float" ))),
376
+ ],
377
+ )
378
+ def test_parse__param_field_type_field_or_none__param_section_with_optional_with_parent (
379
+ parse_sphinx : ParserType ,
380
+ union : str ,
381
+ expected_annotation : Expr ,
382
+ ) -> None :
383
+ """Parse parameters with separated union types.
384
+
385
+ Parameters:
386
+ parse_sphinx: Fixture parser.
387
+ union: A parametrized union type.
388
+ expected_annotation: The expected annotation as an expression
389
+ """
390
+ docstring = f"""
391
+ Docstring with line continuation.
392
+
393
+ :param { SOME_NAME } : { SOME_TEXT }
394
+ :type { SOME_NAME } : { union }
395
+ """
396
+
397
+ parent_fn = Function ("func" , parameters = Parameters (Parameter (SOME_NAME )))
398
+ sections , _ = parse_sphinx (docstring , parent = parent_fn )
399
+ assert len (sections ) == 2
400
+ assert sections [1 ].kind is DocstringSectionKind .parameters
401
+ actual = sections [1 ].value [0 ]
402
+ expected = DocstringParameter (SOME_NAME , annotation = expected_annotation , description = SOME_TEXT )
403
+ assert isinstance (actual , type (expected ))
404
+ assert actual .as_dict () == expected .as_dict ()
405
+ assert isinstance (actual .annotation , type (expected .annotation ))
406
+ assert isinstance (actual .annotation , Expr )
407
+ assert actual .annotation .as_dict () == expected_annotation .as_dict ()
408
+
409
+
305
410
def test_parse__param_field_annotate_type__param_section_with_type (parse_sphinx : ParserType ) -> None :
306
411
"""Parse a simple docstring.
307
412
0 commit comments