1515 DocstringRaise ,
1616 DocstringReturn ,
1717 DocstringSectionKind ,
18+ Expr ,
19+ ExprBinOp ,
20+ ExprName ,
1821 Function ,
1922 Module ,
2023 Parameter ,
@@ -231,28 +234,62 @@ def test_parse__param_field_docs_type__param_section_with_type(parse_sphinx: Par
231234 assert actual .as_dict () == expected .as_dict ()
232235
233236
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 :
235239 """Parse parameters with separated types.
236240
237241 Parameters:
238242 parse_sphinx: Fixture parser.
243+ type_: The type to use in the type directive.
239244 """
240245 docstring = f"""
241246 Docstring with line continuation.
242247
243- :param foo : { SOME_TEXT }
244- :type foo: str
248+ :param { SOME_NAME } : { SOME_TEXT }
249+ :type { SOME_NAME } : { type_ }
245250 """
246251
247252 sections , _ = parse_sphinx (docstring )
248253 assert len (sections ) == 2
249254 assert sections [1 ].kind is DocstringSectionKind .parameters
250255 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 )
252257 assert isinstance (actual , type (expected ))
253258 assert actual .as_dict () == expected .as_dict ()
254259
255260
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+
256293def test_parse__param_field_type_field_first__param_section_with_type (parse_sphinx : ParserType ) -> None :
257294 """Parse parameters with separated types first.
258295
@@ -275,6 +312,33 @@ def test_parse__param_field_type_field_first__param_section_with_type(parse_sphi
275312 assert actual .as_dict () == expected .as_dict ()
276313
277314
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+
278342@pytest .mark .parametrize ("union" , ["str or None" , "None or str" , "str or int" , "str or int or float" ])
279343def test_parse__param_field_type_field_or_none__param_section_with_optional (
280344 parse_sphinx : ParserType ,
@@ -302,6 +366,47 @@ def test_parse__param_field_type_field_or_none__param_section_with_optional(
302366 assert actual .as_dict () == expected .as_dict ()
303367
304368
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+
305410def test_parse__param_field_annotate_type__param_section_with_type (parse_sphinx : ParserType ) -> None :
306411 """Parse a simple docstring.
307412
0 commit comments