Coverage for tests / test_docstrings / test_google.py: 100.00%
584 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-11 11:48 +0100
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-11 11:48 +0100
1"""Tests for the [Google-style parser][griffe.docstrings.google]."""
3from __future__ import annotations
5import inspect
6from typing import TYPE_CHECKING
8import pytest
10from griffe import (
11 Attribute,
12 Class,
13 Docstring,
14 DocstringReceive,
15 DocstringReturn,
16 DocstringSectionKind,
17 DocstringYield,
18 ExprName,
19 Function,
20 Module,
21 Parameter,
22 Parameters,
23 TypeParameter,
24 TypeParameterKind,
25 TypeParameters,
26 parse_docstring_annotation,
27)
29if TYPE_CHECKING:
30 from tests.test_docstrings.helpers import ParserType
33# =============================================================================================
34# Markup flow (multilines, indentation, etc.)
35def test_simple_docstring(parse_google: ParserType) -> None:
36 """Parse a simple docstring.
38 Parameters:
39 parse_google: Fixture parser.
40 """
41 sections, warnings = parse_google("A simple docstring.")
42 assert len(sections) == 1
43 assert not warnings
46def test_multiline_docstring(parse_google: ParserType) -> None:
47 """Parse a multi-line docstring.
49 Parameters:
50 parse_google: Fixture parser.
51 """
52 sections, warnings = parse_google(
53 """
54 A somewhat longer docstring.
56 Blablablabla.
57 """,
58 )
59 assert len(sections) == 1
60 assert not warnings
63def test_parse_partially_indented_lines(parse_google: ParserType) -> None:
64 """Properly handle partially indented lines.
66 Parameters:
67 parse_google: Fixture parser.
68 """
69 docstring = """
70 The available formats are:
71 - JSON
73 The unavailable formats are:
74 - YAML
75 """
76 sections, warnings = parse_google(docstring)
77 assert len(sections) == 2
78 assert sections[0].kind is DocstringSectionKind.admonition
79 assert sections[1].kind is DocstringSectionKind.admonition
80 assert not warnings
83def test_multiple_lines_in_sections_items(parse_google: ParserType) -> None:
84 """Parse multi-line item description.
86 Parameters:
87 parse_google: Fixture parser.
88 """
89 docstring = """
90 Parameters:
91 p (int): This parameter
92 has a description
93 spawning on multiple lines.
95 It even has blank lines in it.
96 Some of these lines
97 are indented for no reason.
98 q (int):
99 What if the first line is blank?
100 """
102 sections, warnings = parse_google(docstring)
103 assert len(sections) == 1
104 assert len(sections[0].value) == 2
105 assert warnings
106 for warning in warnings:
107 assert "should be 4 * 2 = 8 spaces, not" in warning
110def test_code_blocks(parse_google: ParserType) -> None:
111 """Parse code blocks.
113 Parameters:
114 parse_google: Fixture parser.
115 """
116 docstring = """
117 This docstring contains a code block!
119 ```python
120 print("hello")
121 ```
122 """
124 sections, warnings = parse_google(docstring)
125 assert len(sections) == 1
126 assert not warnings
129def test_indented_code_block(parse_google: ParserType) -> None:
130 """Parse indented code blocks.
132 Parameters:
133 parse_google: Fixture parser.
134 """
135 docstring = """
136 This docstring contains a docstring in a code block o_O!
138 \"\"\"
139 This docstring is contained in another docstring O_o!
141 Parameters:
142 s: A string.
143 \"\"\"
144 """
146 sections, warnings = parse_google(docstring)
147 assert len(sections) == 1
148 assert not warnings
151def test_different_indentation(parse_google: ParserType) -> None:
152 """Parse different indentations, warn on confusing indentation.
154 Parameters:
155 parse_google: Fixture parser.
156 """
157 docstring = """
158 Raises:
159 StartAt5: this section's items starts with 5 spaces of indentation.
160 Well indented continuation line.
161 Badly indented continuation line (will trigger a warning).
163 Empty lines are preserved, as well as extra-indentation (this line is a code block).
164 AnyOtherLine: ...starting with exactly 5 spaces is a new item.
165 AnyLine: ...indented with less than 5 spaces signifies the end of the section.
166 """
168 sections, warnings = parse_google(docstring)
169 assert len(sections) == 2
170 assert len(sections[0].value) == 2
171 assert sections[0].value[0].description == (
172 "this section's items starts with 5 spaces of indentation.\n"
173 "Well indented continuation line.\n"
174 "Badly indented continuation line (will trigger a warning).\n"
175 "\n"
176 " Empty lines are preserved, as well as extra-indentation (this line is a code block)."
177 )
178 assert sections[1].value == " AnyLine: ...indented with less than 5 spaces signifies the end of the section."
179 assert len(warnings) == 1
180 assert "should be 5 * 2 = 10 spaces, not 6" in warnings[0]
183def test_empty_indented_lines_in_section_with_items(parse_google: ParserType) -> None:
184 """In sections with items, don't treat lines with just indentation as items.
186 Parameters:
187 parse_google: Fixture parser.
188 """
189 docstring = "Returns:\n only_item: Description.\n \n \n\nSomething."
190 sections, _ = parse_google(docstring)
191 assert len(sections) == 2
192 assert len(sections[0].value) == 1
195@pytest.mark.parametrize(
196 "section",
197 [
198 "Attributes",
199 "Other Parameters",
200 "Parameters",
201 "Type Parameters",
202 "Raises",
203 "Receives",
204 "Returns",
205 "Warns",
206 "Type aliases",
207 "Yields",
208 ],
209)
210def test_starting_item_description_on_new_line(parse_google: ParserType, section: str) -> None:
211 """In sections with items, allow starting item descriptions on a new (indented) line.
213 Parameters:
214 parse_google: Fixture parser.
215 section: A parametrized section name.
216 """
217 docstring = f"\n{section}:\n only_item:\n Description."
218 sections, _ = parse_google(docstring)
219 assert len(sections) == 1
220 assert len(sections[0].value) == 1
221 assert sections[0].value[0].description.strip() == "Description."
224# =============================================================================================
225# Annotations
226def test_parse_without_parent(parse_google: ParserType) -> None:
227 """Parse a docstring without a parent function.
229 Parameters:
230 parse_google: Fixture parser.
231 """
232 sections, warnings = parse_google(
233 """
234 Parameters:
235 void: SEGFAULT.
236 niet: SEGFAULT.
237 nada: SEGFAULT.
238 rien: SEGFAULT.
240 Keyword Args:
241 keywd: SEGFAULT.
243 Exceptions:
244 GlobalError: when nothing works as expected.
246 Returns:
247 Itself.
248 """,
249 )
251 assert len(sections) == 4
252 assert len(warnings) == 6 # Missing annotations for parameters and return.
253 for warning in warnings[:-1]:
254 assert "parameter" in warning
255 assert "return" in warnings[-1]
258def test_parse_without_annotations(parse_google: ParserType) -> None:
259 """Parse a function docstring without signature annotations.
261 Parameters:
262 parse_google: Fixture parser.
263 """
264 docstring = """
265 Parameters:
266 x: X value.
268 Keyword Args:
269 y: Y value.
271 Returns:
272 Sum X + Y + Z.
273 """
275 sections, warnings = parse_google(
276 docstring,
277 parent=Function(
278 "func",
279 parameters=Parameters(
280 Parameter("x"),
281 Parameter("y"),
282 ),
283 ),
284 )
285 assert len(sections) == 3
286 assert len(warnings) == 3
287 for warning in warnings[:-1]:
288 assert "parameter" in warning
289 assert "return" in warnings[-1]
292def test_parse_with_annotations(parse_google: ParserType) -> None:
293 """Parse a function docstring with signature annotations.
295 Parameters:
296 parse_google: Fixture parser.
297 """
298 docstring = """
299 Parameters:
300 x: X value.
302 Keyword Parameters:
303 y: Y value.
305 Returns:
306 Sum X + Y.
307 """
309 sections, warnings = parse_google(
310 docstring,
311 parent=Function(
312 "func",
313 parameters=Parameters(
314 Parameter("x", annotation="int"),
315 Parameter("y", annotation="int"),
316 ),
317 returns="int",
318 ),
319 )
320 assert len(sections) == 3
321 assert not warnings
324# =============================================================================================
325# Sections
326def test_parse_attributes_section(parse_google: ParserType) -> None:
327 """Parse Attributes sections.
329 Parameters:
330 parse_google: Fixture parser.
331 """
332 docstring = """
333 Attributes:
334 hey: Hey.
335 ho: Ho.
336 """
338 sections, warnings = parse_google(docstring)
339 assert len(sections) == 1
340 assert not warnings
343def test_parse_functions_section(parse_google: ParserType) -> None:
344 """Parse Functions/Methods sections.
346 Parameters:
347 parse_google: Fixture parser.
348 """
349 docstring = """
350 Functions:
351 f(a, b=2): Hello.
352 g: Hi.
354 Methods:
355 f(a, b=2): Hello.
356 g: Hi.
357 """
359 sections, warnings = parse_google(docstring)
360 assert len(sections) == 2
361 for section in sections:
362 assert section.kind is DocstringSectionKind.functions
363 func_f = section.value[0]
364 assert func_f.name == "f"
365 assert func_f.signature == "f(a, b=2)"
366 assert func_f.description == "Hello."
367 func_g = section.value[1]
368 assert func_g.name == "g"
369 assert func_g.signature is None
370 assert func_g.description == "Hi."
371 assert not warnings
374def test_parse_classes_section(parse_google: ParserType) -> None:
375 """Parse Classes sections.
377 Parameters:
378 parse_google: Fixture parser.
379 """
380 docstring = """
381 Classes:
382 C(a, b=2): Hello.
383 D: Hi.
384 """
386 sections, warnings = parse_google(docstring)
387 assert len(sections) == 1
388 assert sections[0].kind is DocstringSectionKind.classes
389 class_c = sections[0].value[0]
390 assert class_c.name == "C"
391 assert class_c.signature == "C(a, b=2)"
392 assert class_c.description == "Hello."
393 class_d = sections[0].value[1]
394 assert class_d.name == "D"
395 assert class_d.signature is None
396 assert class_d.description == "Hi."
397 assert not warnings
400def test_parse_type_aliases_section(parse_google: ParserType) -> None:
401 """Parse Type Aliases sections.
403 Parameters:
404 parse_google: Fixture parser.
405 """
406 docstring = """
407 Type Aliases:
408 TC: Hello.
409 TD: Hi.
410 """
412 sections, warnings = parse_google(docstring)
413 assert len(sections) == 1
414 assert sections[0].kind is DocstringSectionKind.type_aliases
415 type_alias_c = sections[0].value[0]
416 assert type_alias_c.name == "TC"
417 assert type_alias_c.description == "Hello."
418 type_alias_d = sections[0].value[1]
419 assert type_alias_d.name == "TD"
420 assert type_alias_d.description == "Hi."
421 assert not warnings
424def test_parse_modules_section(parse_google: ParserType) -> None:
425 """Parse Modules sections.
427 Parameters:
428 parse_google: Fixture parser.
429 """
430 docstring = """
431 Modules:
432 m: Hello.
433 n: Hi.
434 """
436 sections, warnings = parse_google(docstring)
437 assert len(sections) == 1
438 assert sections[0].kind is DocstringSectionKind.modules
439 module_m = sections[0].value[0]
440 assert module_m.name == "m"
441 assert module_m.description == "Hello."
442 module_n = sections[0].value[1]
443 assert module_n.name == "n"
444 assert module_n.description == "Hi."
445 assert not warnings
448def test_parse_examples_sections(parse_google: ParserType) -> None:
449 """Parse a function docstring with examples.
451 Parameters:
452 parse_google: Fixture parser.
453 """
454 docstring = """
455 Examples:
456 Some examples that will create a unified code block:
458 >>> 2 + 2 == 5
459 False
460 >>> print("examples")
461 "examples"
463 This is just a random comment in the examples section.
465 These examples will generate two different code blocks. Note the blank line.
467 >>> print("I'm in the first code block!")
468 "I'm in the first code block!"
470 >>> print("I'm in other code block!")
471 "I'm in other code block!"
473 We also can write multiline examples:
475 >>> x = 3 + 2 # doctest: +SKIP
476 >>> y = x + 10
477 >>> y
478 15
480 This is just a typical Python code block:
482 ```python
483 print("examples")
484 return 2 + 2
485 ```
487 Even if it contains doctests, the following block is still considered a normal code-block.
489 ```pycon
490 >>> print("examples")
491 "examples"
492 >>> 2 + 2
493 4
494 ```
496 The blank line before an example is optional.
497 >>> x = 3
498 >>> y = "apple"
499 >>> z = False
500 >>> l = [x, y, z]
501 >>> my_print_list_function(l)
502 3
503 "apple"
504 False
505 """
507 sections, warnings = parse_google(
508 docstring,
509 parent=Function(
510 "func",
511 parameters=Parameters(
512 Parameter("x", annotation="int"),
513 Parameter("y", annotation="int"),
514 ),
515 returns="int",
516 ),
517 trim_doctest_flags=False,
518 )
519 assert len(sections) == 1
520 examples = sections[0]
521 assert len(examples.value) == 9
522 assert examples.value[6][1].startswith(">>> x = 3 + 2 # doctest: +SKIP")
523 assert not warnings
526def test_parse_yields_section(parse_google: ParserType) -> None:
527 """Parse Yields section.
529 Parameters:
530 parse_google: Fixture parser.
531 """
532 docstring = """
533 Yields:
534 x: Floats.
535 (int): Integers.
536 y (int): Same.
537 """
539 sections, warnings = parse_google(docstring)
540 assert len(sections) == 1
541 annotated = sections[0].value[0]
542 assert annotated.name == "x"
543 assert annotated.annotation is None
544 assert annotated.description == "Floats."
545 annotated = sections[0].value[1]
546 assert annotated.name == ""
547 assert annotated.annotation == "int"
548 assert annotated.description == "Integers."
549 annotated = sections[0].value[2]
550 assert annotated.name == "y"
551 assert annotated.annotation == "int"
552 assert annotated.description == "Same."
553 assert len(warnings) == 1
554 assert "'x'" in warnings[0]
557def test_invalid_sections(parse_google: ParserType) -> None:
558 """Warn on invalid sections.
560 Parameters:
561 parse_google: Fixture parser.
562 """
563 docstring = """
564 Parameters:
565 Exceptions:
566 Exceptions:
568 Returns:
569 Note:
571 Important:
572 """
574 sections, warnings = parse_google(docstring)
575 assert len(sections) == 1
576 assert not warnings
579def test_no_empty_text_section(parse_google: ParserType) -> None:
580 """Don't create a single empty text section for an empty docstring.
582 Parameters:
583 parse_google: Fixture parser.
584 """
585 sections, warnings = parse_google("")
586 assert not sections
587 assert not warnings
590# =============================================================================================
591# Parameters sections
592def test_parse_args_and_kwargs(parse_google: ParserType) -> None:
593 """Parse args and kwargs.
595 Parameters:
596 parse_google: Fixture parser.
597 """
598 docstring = """
599 Parameters:
600 a (str): a parameter.
601 *args (str): args parameters.
602 **kwargs (str): kwargs parameters.
603 """
605 sections, warnings = parse_google(docstring)
606 assert len(sections) == 1
607 expected_parameters = {"a": "a parameter.", "*args": "args parameters.", "**kwargs": "kwargs parameters."}
608 for parameter in sections[0].value:
609 assert parameter.name in expected_parameters
610 assert expected_parameters[parameter.name] == parameter.description
611 assert not warnings
614def test_parse_args_kwargs_keyword_only(parse_google: ParserType) -> None:
615 """Parse args and kwargs.
617 Parameters:
618 parse_google: Fixture parser.
619 """
620 docstring = """
621 Parameters:
622 a (str): a parameter.
623 *args (str): args parameters.
625 Keyword Args:
626 **kwargs (str): kwargs parameters.
627 """
629 sections, warnings = parse_google(docstring)
630 assert len(sections) == 2
631 expected_parameters = {"a": "a parameter.", "*args": "args parameters."}
632 for parameter in sections[0].value:
633 assert parameter.name in expected_parameters
634 assert expected_parameters[parameter.name] == parameter.description
636 expected_parameters = {"**kwargs": "kwargs parameters."}
637 for kwarg in sections[1].value:
638 assert kwarg.name in expected_parameters
639 assert expected_parameters[kwarg.name] == kwarg.description
641 assert not warnings
644def test_parse_types_in_docstring(parse_google: ParserType) -> None:
645 """Parse types in docstring.
647 Parameters:
648 parse_google: Fixture parser.
649 """
650 docstring = """
651 Parameters:
652 x (int): X value.
654 Keyword Args:
655 y (int): Y value.
657 Returns:
658 s (int): Sum X + Y + Z.
659 """
661 sections, warnings = parse_google(
662 docstring,
663 parent=Function(
664 "func",
665 parameters=Parameters(
666 Parameter("x"),
667 Parameter("y"),
668 ),
669 ),
670 )
671 assert len(sections) == 3
672 assert not warnings
674 assert sections[0].kind is DocstringSectionKind.parameters
675 assert sections[1].kind is DocstringSectionKind.other_parameters
676 assert sections[2].kind is DocstringSectionKind.returns
678 (argx,) = sections[0].value
679 (argy,) = sections[1].value
680 (returns,) = sections[2].value
682 assert argx.name == "x"
683 assert argx.annotation.name == "int"
684 assert argx.annotation.canonical_path == "int"
685 assert argx.description == "X value."
686 assert argx.value is None
688 assert argy.name == "y"
689 assert argy.annotation.name == "int"
690 assert argy.annotation.canonical_path == "int"
691 assert argy.description == "Y value."
692 assert argy.value is None
694 assert returns.annotation.name == "int"
695 assert returns.annotation.canonical_path == "int"
696 assert returns.description == "Sum X + Y + Z."
699def test_parse_optional_type_in_docstring(parse_google: ParserType) -> None:
700 """Parse optional types in docstring.
702 Parameters:
703 parse_google: Fixture parser.
704 """
705 docstring = """
706 Parameters:
707 x (int): X value.
708 y (int, optional): Y value.
710 Keyword Args:
711 z (int, optional): Z value.
712 """
714 sections, warnings = parse_google(
715 docstring,
716 parent=Function(
717 "func",
718 parameters=Parameters(
719 Parameter("x", default="1"),
720 Parameter("y", default="None"),
721 Parameter("z", default="None"),
722 ),
723 ),
724 )
725 assert len(sections) == 2
726 assert not warnings
728 assert sections[0].kind is DocstringSectionKind.parameters
729 assert sections[1].kind is DocstringSectionKind.other_parameters
731 argx, argy = sections[0].value
732 (argz,) = sections[1].value
734 assert argx.name == "x"
735 assert argx.annotation.name == "int"
736 assert argx.annotation.canonical_path == "int"
737 assert argx.description == "X value."
738 assert argx.value == "1"
740 assert argy.name == "y"
741 assert argy.annotation.name == "int"
742 assert argy.annotation.canonical_path == "int"
743 assert argy.description == "Y value."
744 assert argy.value == "None"
746 assert argz.name == "z"
747 assert argz.annotation.name == "int"
748 assert argz.annotation.canonical_path == "int"
749 assert argz.description == "Z value."
750 assert argz.value == "None"
753def test_prefer_docstring_types_over_annotations(parse_google: ParserType) -> None:
754 """Prefer the docstring type over the annotation.
756 Parameters:
757 parse_google: Fixture parser.
758 """
759 docstring = """
760 Parameters:
761 x (str): X value.
763 Keyword Args:
764 y (str): Y value.
766 Returns:
767 (str): Sum X + Y + Z.
768 """
770 sections, warnings = parse_google(
771 docstring,
772 parent=Function(
773 "func",
774 parameters=Parameters(
775 Parameter("x", annotation="int"),
776 Parameter("y", annotation="int"),
777 ),
778 returns="int",
779 ),
780 )
781 assert len(sections) == 3
782 assert not warnings
784 assert sections[0].kind is DocstringSectionKind.parameters
785 assert sections[1].kind is DocstringSectionKind.other_parameters
786 assert sections[2].kind is DocstringSectionKind.returns
788 (argx,) = sections[0].value
789 (argy,) = sections[1].value
790 (returns,) = sections[2].value
792 assert argx.name == "x"
793 assert argx.annotation.name == "str"
794 assert argx.annotation.canonical_path == "str"
795 assert argx.description == "X value."
797 assert argy.name == "y"
798 assert argy.annotation.name == "str"
799 assert argy.annotation.canonical_path == "str"
800 assert argy.description == "Y value."
802 assert returns.annotation.name == "str"
803 assert returns.annotation.canonical_path == "str"
804 assert returns.description == "Sum X + Y + Z."
807def test_parameter_line_without_colon(parse_google: ParserType) -> None:
808 """Warn when missing colon.
810 Parameters:
811 parse_google: Fixture parser.
812 """
813 docstring = """
814 Parameters:
815 x is an integer.
816 """
818 sections, warnings = parse_google(docstring)
819 assert len(sections) == 0 # Empty sections are discarded.
820 assert len(warnings) == 1
821 assert "pair" in warnings[0]
824def test_parameter_line_without_colon_keyword_only(parse_google: ParserType) -> None:
825 """Warn when missing colon.
827 Parameters:
828 parse_google: Fixture parser.
829 """
830 docstring = """
831 Keyword Args:
832 x is an integer.
833 """
835 sections, warnings = parse_google(docstring)
836 assert len(sections) == 0 # Empty sections are discarded.
837 assert len(warnings) == 1
838 assert "pair" in warnings[0]
841def test_warn_about_unknown_parameters(parse_google: ParserType) -> None:
842 """Warn about unknown parameters in "Parameters" sections.
844 Parameters:
845 parse_google: Fixture parser.
846 """
847 docstring = """
848 Parameters:
849 x (int): Integer.
850 y (int): Integer.
851 """
853 _, warnings = parse_google(
854 docstring,
855 parent=Function(
856 "func",
857 parameters=Parameters(
858 Parameter("a"),
859 Parameter("y"),
860 ),
861 ),
862 )
863 assert len(warnings) == 1
864 assert "'x' does not appear in the function signature" in warnings[0]
867def test_never_warn_about_unknown_other_parameters(parse_google: ParserType) -> None:
868 """Never warn about unknown parameters in "Other parameters" sections.
870 Parameters:
871 parse_google: Fixture parser.
872 """
873 docstring = """
874 Other Parameters:
875 x (int): Integer.
876 z (int): Integer.
877 """
879 _, warnings = parse_google(
880 docstring,
881 parent=Function(
882 "func",
883 parameters=Parameters(
884 Parameter("a"),
885 Parameter("y"),
886 ),
887 ),
888 )
889 assert not warnings
892def test_unknown_params_scan_doesnt_crash_without_parameters(parse_google: ParserType) -> None:
893 """Assert we don't crash when parsing parameters sections and parent object does not have parameters.
895 Parameters:
896 parse_google: Fixture parser.
897 """
898 docstring = """
899 Parameters:
900 this (str): This.
901 that (str): That.
902 """
904 _, warnings = parse_google(docstring, parent=Module("mod"))
905 assert not warnings
908def test_class_uses_init_parameters(parse_google: ParserType) -> None:
909 """Assert we use the `__init__` parameters when parsing classes' parameters sections.
911 Parameters:
912 parse_google: Fixture parser.
913 """
914 docstring = """
915 Parameters:
916 x: X value.
917 """
918 parent = Class("c")
919 parent["__init__"] = Function("__init__", parameters=Parameters(Parameter("x", annotation="int")))
920 sections, warnings = parse_google(docstring, parent=parent)
921 assert not warnings
922 argx = sections[0].value[0]
923 assert argx.name == "x"
924 assert argx.annotation == "int"
925 assert argx.description == "X value."
928def test_parse_parameters_and_type_without_space(parse_google: ParserType) -> None:
929 """Parse parameter name and type without space.
931 Parameters:
932 parse_google: Fixture parser.
933 """
934 docstring = """
935 Parameters:
936 x(int): X value.
937 """
939 sections, warnings = parse_google(docstring)
940 assert len(sections) == 1
941 assert not warnings
942 argx = sections[0].value[0]
943 assert argx.name == "x"
944 assert argx.annotation == "int"
945 assert argx.description == "X value."
948# TODO: possible feature
949# def test_missing_parameter(parse_google: ParserType) -> None:
950# """Warn on missing parameter in docstring.
951#
952# Parameters:
953# parse_google: Fixture parser.
954# """
955# docstring = """
956# Parameters:
957# x: Integer.
958# """
959# assert not warnings
962# =============================================================================================
963# Type parameters sections
964def test_parse_type_var_tuples_and_param_specs(parse_google: ParserType) -> None:
965 """Parse type variable tuples and parameter specifications.
967 Parameters:
968 parse_google: Fixture parser.
969 """
970 docstring = """
971 Type Parameters:
972 T: A type parameter.
973 C (str, (int, float)): A constrained type parameter.
974 D complex: A bounded type parameter.
975 """
977 sections, warnings = parse_google(docstring)
978 assert len(sections) == 1
979 expected_type_parameters = {
980 "T": ("A type parameter.", None),
981 "C": ("A constrained type parameter.", "str, (int, float)"),
982 "D": ("A bounded type parameter.", "complex"),
983 }
984 for type_parameter in sections[0].value:
985 assert type_parameter.name in expected_type_parameters
986 assert expected_type_parameters[type_parameter.name][0] == type_parameter.description
987 assert expected_type_parameters[type_parameter.name][1] == type_parameter.annotation
988 assert not warnings
991def test_prefer_docstring_bounds_over_annotations(parse_google: ParserType) -> None:
992 """Prefer the docstring bound over the annotation.
994 Parameters:
995 parse_google: Fixture parser.
996 """
997 docstring = """
998 Type Parameters:
999 X (str): X type.
1000 Y str, int: Y type.
1001 """
1003 sections, warnings = parse_google(
1004 docstring,
1005 parent=Function(
1006 "func",
1007 type_parameters=TypeParameters(
1008 TypeParameter("X", kind=TypeParameterKind.type_var, constraints=["complex"]),
1009 TypeParameter("Y", kind=TypeParameterKind.type_var, bound="int"),
1010 ),
1011 ),
1012 )
1013 assert len(sections) == 1
1014 assert not warnings
1016 assert sections[0].kind is DocstringSectionKind.type_parameters
1018 (x, y) = sections[0].value
1020 assert x.name == "X"
1021 assert str(x.bound) == "str"
1022 assert x.constraints is None
1024 assert y.name == "Y"
1025 assert y.bound is None
1026 assert [str(constraint) for constraint in y.constraints] == ["str", "int"]
1029def test_type_parameter_line_without_colon(parse_google: ParserType) -> None:
1030 """Warn when missing colon.
1032 Parameters:
1033 parse_google: Fixture parser.
1034 """
1035 docstring = """
1036 Type Parameters:
1037 X is an integer type.
1038 """
1040 sections, warnings = parse_google(docstring)
1041 assert len(sections) == 0 # empty sections are discarded
1042 assert len(warnings) == 1
1043 assert "pair" in warnings[0]
1046def test_warn_about_unknown_type_parameters(parse_google: ParserType) -> None:
1047 """Warn about unknown type parameters in "Type Parameters" sections.
1049 Parameters:
1050 parse_google: Fixture parser.
1051 """
1052 docstring = """
1053 Type Parameters:
1054 X (int): Integer.
1055 Y (int): Integer.
1056 """
1058 _, warnings = parse_google(
1059 docstring,
1060 parent=Function(
1061 "func",
1062 type_parameters=TypeParameters(
1063 TypeParameter("A", kind=TypeParameterKind.type_var),
1064 TypeParameter("Y", kind=TypeParameterKind.type_var),
1065 ),
1066 ),
1067 )
1068 assert len(warnings) == 1
1069 assert "'X' does not appear in the function signature" in warnings[0]
1072def test_unknown_type_params_scan_doesnt_crash_without_type_parameters(parse_google: ParserType) -> None:
1073 """Assert we don't crash when parsing type parameters sections and parent object does not have type parameters.
1075 Parameters:
1076 parse_google: Fixture parser.
1077 """
1078 docstring = """
1079 TypeParameters:
1080 This (str): This.
1081 That: That.
1082 """
1084 _, warnings = parse_google(docstring, parent=Module("mod"))
1085 assert not warnings
1088# =============================================================================================
1089# Attributes sections
1090def test_retrieve_attributes_annotation_from_parent(parse_google: ParserType) -> None:
1091 """Retrieve the annotations of attributes from the parent object.
1093 Parameters:
1094 parse_google: Fixture parser.
1095 """
1096 docstring = """
1097 Summary.
1099 Attributes:
1100 a: Whatever.
1101 b: Whatever.
1102 """
1103 parent = Class("cls")
1104 parent["a"] = Attribute("a", annotation=ExprName("int"))
1105 parent["b"] = Attribute("b", annotation=ExprName("str"))
1106 sections, _ = parse_google(docstring, parent=parent)
1107 attributes = sections[1].value
1108 assert attributes[0].name == "a"
1109 assert attributes[0].annotation.name == "int"
1110 assert attributes[1].name == "b"
1111 assert attributes[1].annotation.name == "str"
1114# =============================================================================================
1115# Yields sections
1116def test_parse_yields_section_with_return_annotation(parse_google: ParserType) -> None:
1117 """Parse Yields section with a return annotation in the parent function.
1119 Parameters:
1120 parse_google: Fixture parser.
1121 """
1122 docstring = """
1123 Yields:
1124 Integers.
1125 """
1127 function = Function("func", returns="Iterator[int]")
1128 sections, warnings = parse_google(docstring, function)
1129 assert len(sections) == 1
1130 annotated = sections[0].value[0]
1131 assert annotated.annotation == "Iterator[int]"
1132 assert annotated.description == "Integers."
1133 assert not warnings
1136@pytest.mark.parametrize(
1137 "return_annotation",
1138 [
1139 "Iterator[tuple[int, float]]",
1140 "Generator[tuple[int, float], ..., ...]",
1141 ],
1142)
1143def test_parse_yields_tuple_in_iterator_or_generator(parse_google: ParserType, return_annotation: str) -> None:
1144 """Parse Yields annotations in Iterator or Generator types.
1146 Parameters:
1147 parse_google: Fixture parser.
1148 return_annotation: Parametrized return annotation as a string.
1149 """
1150 docstring = """
1151 Summary.
1153 Yields:
1154 a: Whatever.
1155 b: Whatever.
1156 """
1157 sections, _ = parse_google(
1158 docstring,
1159 parent=Function(
1160 "func",
1161 returns=parse_docstring_annotation(return_annotation, Docstring("d", parent=Function("f"))),
1162 ),
1163 )
1164 yields = sections[1].value
1165 assert yields[0].name == "a"
1166 assert yields[0].annotation.name == "int"
1167 assert yields[1].name == "b"
1168 assert yields[1].annotation.name == "float"
1171@pytest.mark.parametrize(
1172 "return_annotation",
1173 [
1174 "Iterator[int]",
1175 "Generator[int, None, None]",
1176 ],
1177)
1178def test_extract_yielded_type_with_single_return_item(parse_google: ParserType, return_annotation: str) -> None:
1179 """Extract main type annotation from Iterator or Generator.
1181 Parameters:
1182 parse_google: Fixture parser.
1183 return_annotation: Parametrized return annotation as a string.
1184 """
1185 docstring = """
1186 Summary.
1188 Yields:
1189 A number.
1190 """
1191 sections, _ = parse_google(
1192 docstring,
1193 parent=Function(
1194 "func",
1195 returns=parse_docstring_annotation(return_annotation, Docstring("d", parent=Function("f"))),
1196 ),
1197 )
1198 yields = sections[1].value
1199 assert yields[0].annotation.name == "int"
1202def test_yield_section_in_property(parse_google: ParserType) -> None:
1203 """No warnings when parsing Yields section in a property.
1205 Parameters:
1206 parse_google: Fixture parser.
1207 """
1208 docstring = """
1209 Summary.
1211 Yields:
1212 A number.
1213 """
1214 sections, warnings = parse_google(
1215 docstring,
1216 parent=Attribute(
1217 "prop",
1218 annotation=parse_docstring_annotation("Iterator[int]", Docstring("d", parent=Attribute("a"))),
1219 ),
1220 )
1221 assert not warnings
1222 yields = sections[1].value
1223 assert yields[0].annotation.name == "int"
1226# =============================================================================================
1227# Receives sections
1228def test_parse_receives_tuple_in_generator(parse_google: ParserType) -> None:
1229 """Parse Receives annotations in Generator type.
1231 Parameters:
1232 parse_google: Fixture parser.
1233 """
1234 docstring = """
1235 Summary.
1237 Receives:
1238 a: Whatever.
1239 b: Whatever.
1240 """
1241 sections, _ = parse_google(
1242 docstring,
1243 parent=Function(
1244 "func",
1245 returns=parse_docstring_annotation(
1246 "Generator[..., tuple[int, float], ...]",
1247 Docstring("d", parent=Function("f")),
1248 ),
1249 ),
1250 )
1251 receives = sections[1].value
1252 assert receives[0].name == "a"
1253 assert receives[0].annotation.name == "int"
1254 assert receives[1].name == "b"
1255 assert receives[1].annotation.name == "float"
1258@pytest.mark.parametrize(
1259 "return_annotation",
1260 [
1261 "Generator[int, float, None]",
1262 ],
1263)
1264def test_extract_received_type_with_single_return_item(parse_google: ParserType, return_annotation: str) -> None:
1265 """Extract main type annotation from Iterator or Generator.
1267 Parameters:
1268 parse_google: Fixture parser.
1269 return_annotation: Parametrized return annotation as a string.
1270 """
1271 docstring = """
1272 Summary.
1274 Receives:
1275 A floating point number.
1276 """
1277 sections, _ = parse_google(
1278 docstring,
1279 parent=Function(
1280 "func",
1281 returns=parse_docstring_annotation(return_annotation, Docstring("d", parent=Function("f"))),
1282 ),
1283 )
1284 receives = sections[1].value
1285 assert receives[0].annotation.name == "float"
1288# =============================================================================================
1289# Returns sections
1290def test_parse_returns_tuple_in_generator(parse_google: ParserType) -> None:
1291 """Parse Returns annotations in Generator type.
1293 Parameters:
1294 parse_google: Fixture parser.
1295 """
1296 docstring = """
1297 Summary.
1299 Returns:
1300 a: Whatever.
1301 b: Whatever.
1302 """
1303 sections, _ = parse_google(
1304 docstring,
1305 parent=Function(
1306 "func",
1307 returns=parse_docstring_annotation(
1308 "Generator[..., ..., tuple[int, float]]",
1309 Docstring("d", parent=Function("f")),
1310 ),
1311 ),
1312 )
1313 returns = sections[1].value
1314 assert returns[0].name == "a"
1315 assert returns[0].annotation.name == "int"
1316 assert returns[1].name == "b"
1317 assert returns[1].annotation.name == "float"
1320# =============================================================================================
1321# Parser special features
1322def test_parse_admonitions(parse_google: ParserType) -> None:
1323 """Parse admonitions.
1325 Parameters:
1326 parse_google: Fixture parser.
1327 """
1328 docstring = """
1329 Important note:
1330 Hello.
1332 Note: With title.
1333 Hello again.
1335 Something:
1336 Something.
1337 """
1339 sections, warnings = parse_google(docstring)
1340 assert len(sections) == 3
1341 assert not warnings
1342 assert sections[0].title == "Important note"
1343 assert sections[0].value.kind == "important-note"
1344 assert sections[0].value.contents == "Hello."
1345 assert sections[1].title == "With title."
1346 assert sections[1].value.kind == "note"
1347 assert sections[1].value.contents == "Hello again."
1348 assert sections[2].title == "Something"
1349 assert sections[2].value.kind == "something"
1350 assert sections[2].value.contents == "Something."
1353@pytest.mark.parametrize(
1354 "docstring",
1355 [
1356 """
1357 ******************************
1358 This looks like an admonition:
1359 ******************************
1360 """,
1361 """
1362 Warning: this line also looks
1363 like an admonition.
1364 """,
1365 """
1366 Matching but not an admonition:
1370 - Multiple empty lines above.
1371 """,
1372 """Last line:""",
1373 ],
1374)
1375def test_handle_false_admonitions_correctly(parse_google: ParserType, docstring: str) -> None:
1376 """Correctly handle lines that look like admonitions.
1378 Parameters:
1379 parse_google: Fixture parser.
1380 docstring: The docstring to parse (parametrized).
1381 """
1382 sections, warnings = parse_google(docstring)
1383 assert len(sections) == 1
1384 assert sections[0].kind is DocstringSectionKind.text
1385 assert len(sections[0].value.splitlines()) == len(inspect.cleandoc(docstring).splitlines())
1386 assert not warnings
1389def test_dont_insert_admonition_before_current_section(parse_google: ParserType) -> None:
1390 """Check that admonitions are inserted at the right place.
1392 Parameters:
1393 parse_google: Fixture parser.
1394 """
1395 docstring = """
1396 Summary.
1398 Short description.
1400 Info:
1401 Something useful.
1402 """
1403 sections, _ = parse_google(docstring)
1404 assert len(sections) == 2
1405 assert sections[0].kind is DocstringSectionKind.text
1406 assert sections[1].kind is DocstringSectionKind.admonition
1409@pytest.mark.parametrize(
1410 "docstring",
1411 [
1412 "",
1413 "\n",
1414 "\n\n",
1415 "Summary.",
1416 "Summary.\n\n\n",
1417 "Summary.\n\nParagraph.",
1418 "Summary\non two lines.",
1419 "Summary\non two lines.\n\nParagraph.",
1420 ],
1421)
1422def test_ignore_init_summary(parse_google: ParserType, docstring: str) -> None:
1423 """Correctly ignore summary in `__init__` methods' docstrings.
1425 Parameters:
1426 parse_google: Fixture parser.
1427 docstring: The docstring to parse_google (parametrized).
1428 """
1429 sections, _ = parse_google(docstring, parent=Function("__init__", parent=Class("C")), ignore_init_summary=True)
1430 for section in sections:
1431 assert "Summary" not in section.value
1433 if docstring.strip():
1434 sections, _ = parse_google(docstring, parent=Function("__init__", parent=Module("M")), ignore_init_summary=True)
1435 assert "Summary" in sections[0].value
1436 sections, _ = parse_google(docstring, parent=Function("f", parent=Class("C")), ignore_init_summary=True)
1437 assert "Summary" in sections[0].value
1438 sections, _ = parse_google(docstring, ignore_init_summary=True)
1439 assert "Summary" in sections[0].value
1442@pytest.mark.parametrize(
1443 "docstring",
1444 [
1445 """
1446 Examples:
1447 Base case 1. We want to skip the following test.
1448 >>> 1 + 1 == 3 # doctest: +SKIP
1449 True
1450 """,
1451 r"""
1452 Examples:
1453 Base case 2. We have a blankline test.
1454 >>> print("a\n\nb")
1455 a
1456 <BLANKLINE>
1457 b
1458 """,
1459 ],
1460)
1461def test_trim_doctest_flags_basic_example(parse_google: ParserType, docstring: str) -> None:
1462 """Correctly parse simple example docstrings when `trim_doctest_flags` option is turned on.
1464 Parameters:
1465 parse_google: Fixture parser.
1466 docstring: The docstring to parse (parametrized).
1467 """
1468 sections, warnings = parse_google(docstring, trim_doctest_flags=True)
1469 assert len(sections) == 1
1470 assert len(sections[0].value) == 2
1471 assert not warnings
1473 # Verify that doctest flags have indeed been trimmed.
1474 example_str = sections[0].value[1][1]
1475 assert "# doctest: +SKIP" not in example_str
1476 assert "<BLANKLINE>" not in example_str
1479def test_trim_doctest_flags_multi_example(parse_google: ParserType) -> None:
1480 """Correctly parse multiline example docstrings when `trim_doctest_flags` option is turned on.
1482 Parameters:
1483 parse_google: Fixture parser.
1484 """
1485 docstring = r"""
1486 Examples:
1487 Test multiline example blocks.
1488 We want to skip the following test.
1489 >>> 1 + 1 == 3 # doctest: +SKIP
1490 True
1492 And then a few more examples here:
1493 >>> print("a\n\nb")
1494 a
1495 <BLANKLINE>
1496 b
1497 >>> 1 + 1 == 2 # doctest: +SKIP
1498 >>> print(list(range(1, 100))) # doctest: +ELLIPSIS
1499 [1, 2, ..., 98, 99]
1500 """
1501 sections, warnings = parse_google(docstring, trim_doctest_flags=True)
1502 assert len(sections) == 1
1503 assert len(sections[0].value) == 4
1504 assert not warnings
1506 # Verify that doctest flags have indeed been trimmed.
1507 example_str = sections[0].value[1][1]
1508 assert "# doctest: +SKIP" not in example_str
1509 example_str = sections[0].value[3][1]
1510 assert "<BLANKLINE>" not in example_str
1511 assert "\n>>> print(list(range(1, 100)))\n" in example_str
1514def test_single_line_with_trailing_whitespace(parse_google: ParserType) -> None:
1515 """Don't crash on single line docstrings with trailing whitespace.
1517 Parameters:
1518 parse_google: Fixture parser.
1519 """
1520 docstring = "a: b\n "
1521 sections, warnings = parse_google(docstring, trim_doctest_flags=True)
1522 assert len(sections) == 1
1523 assert sections[0].kind is DocstringSectionKind.text
1524 assert not warnings
1527@pytest.mark.parametrize(
1528 ("returns_multiple_items", "return_annotation", "expected"),
1529 [
1530 (
1531 False,
1532 None,
1533 [DocstringReturn("", description="XXXXXXX\n YYYYYYY\nZZZZZZZ", annotation=None)],
1534 ),
1535 (
1536 False,
1537 "tuple[int, int]",
1538 [DocstringReturn("", description="XXXXXXX\n YYYYYYY\nZZZZZZZ", annotation="tuple[int, int]")],
1539 ),
1540 (
1541 True,
1542 None,
1543 [
1544 DocstringReturn("", description="XXXXXXX\nYYYYYYY", annotation=None),
1545 DocstringReturn("", description="ZZZZZZZ", annotation=None),
1546 ],
1547 ),
1548 (
1549 True,
1550 "tuple[int,int]",
1551 [
1552 DocstringReturn("", description="XXXXXXX\nYYYYYYY", annotation="int"),
1553 DocstringReturn("", description="ZZZZZZZ", annotation="int"),
1554 ],
1555 ),
1556 ],
1557)
1558def test_parse_returns_multiple_items(
1559 parse_google: ParserType,
1560 returns_multiple_items: bool,
1561 return_annotation: str,
1562 expected: list[DocstringReturn],
1563) -> None:
1564 """Parse Returns section with and without multiple items.
1566 Parameters:
1567 parse_google: Fixture parser.
1568 returns_multiple_items: Whether the `Returns` section has multiple items.
1569 return_annotation: The return annotation of the function to parse.
1570 expected: The expected value of the parsed Returns section.
1571 """
1572 parent = (
1573 Function("func", returns=parse_docstring_annotation(return_annotation, Docstring("d", parent=Function("f"))))
1574 if return_annotation is not None
1575 else None
1576 )
1577 docstring = """
1578 Returns:
1579 XXXXXXX
1580 YYYYYYY
1581 ZZZZZZZ
1582 """
1583 sections, _ = parse_google(
1584 docstring,
1585 returns_multiple_items=returns_multiple_items,
1586 parent=parent,
1587 )
1589 assert len(sections) == 1
1590 assert len(sections[0].value) == len(expected)
1592 for annotated, expected_ in zip(sections[0].value, expected, strict=False):
1593 assert annotated.name == expected_.name
1594 assert str(annotated.annotation) == str(expected_.annotation)
1595 assert annotated.description == expected_.description
1598@pytest.mark.parametrize(
1599 ("returns_multiple_items", "return_annotation", "expected"),
1600 [
1601 (
1602 False,
1603 None,
1604 [DocstringYield("", description="XXXXXXX\n YYYYYYY\nZZZZZZZ", annotation=None)],
1605 ),
1606 (
1607 False,
1608 "Iterator[tuple[int, int]]",
1609 [DocstringYield("", description="XXXXXXX\n YYYYYYY\nZZZZZZZ", annotation="tuple[int, int]")],
1610 ),
1611 (
1612 True,
1613 None,
1614 [
1615 DocstringYield("", description="XXXXXXX\nYYYYYYY", annotation=None),
1616 DocstringYield("", description="ZZZZZZZ", annotation=None),
1617 ],
1618 ),
1619 (
1620 True,
1621 "Iterator[tuple[int,int]]",
1622 [
1623 DocstringYield("", description="XXXXXXX\nYYYYYYY", annotation="int"),
1624 DocstringYield("", description="ZZZZZZZ", annotation="int"),
1625 ],
1626 ),
1627 ],
1628)
1629def test_parse_yields_multiple_items(
1630 parse_google: ParserType,
1631 returns_multiple_items: bool,
1632 return_annotation: str,
1633 expected: list[DocstringYield],
1634) -> None:
1635 """Parse Returns section with and without multiple items.
1637 Parameters:
1638 parse_google: Fixture parser.
1639 returns_multiple_items: Whether the `Returns` and `Yields` sections have multiple items.
1640 return_annotation: The return annotation of the function to parse. Usually an `Iterator`.
1641 expected: The expected value of the parsed Yields section.
1642 """
1643 parent = (
1644 Function("func", returns=parse_docstring_annotation(return_annotation, Docstring("d", parent=Function("f"))))
1645 if return_annotation is not None
1646 else None
1647 )
1648 docstring = """
1649 Yields:
1650 XXXXXXX
1651 YYYYYYY
1652 ZZZZZZZ
1653 """
1654 sections, _ = parse_google(
1655 docstring,
1656 returns_multiple_items=returns_multiple_items,
1657 parent=parent,
1658 )
1660 assert len(sections) == 1
1661 assert len(sections[0].value) == len(expected)
1663 for annotated, expected_ in zip(sections[0].value, expected, strict=False):
1664 assert annotated.name == expected_.name
1665 assert str(annotated.annotation) == str(expected_.annotation)
1666 assert annotated.description == expected_.description
1669@pytest.mark.parametrize(
1670 ("receives_multiple_items", "return_annotation", "expected"),
1671 [
1672 (
1673 False,
1674 None,
1675 [DocstringReceive("", description="XXXXXXX\n YYYYYYY\nZZZZZZZ", annotation=None)],
1676 ),
1677 (
1678 False,
1679 "Generator[..., tuple[int, int], ...]",
1680 [DocstringReceive("", description="XXXXXXX\n YYYYYYY\nZZZZZZZ", annotation="tuple[int, int]")],
1681 ),
1682 (
1683 True,
1684 None,
1685 [
1686 DocstringReceive("", description="XXXXXXX\nYYYYYYY", annotation=None),
1687 DocstringReceive("", description="ZZZZZZZ", annotation=None),
1688 ],
1689 ),
1690 (
1691 True,
1692 "Generator[..., tuple[int, int], ...]",
1693 [
1694 DocstringReceive("", description="XXXXXXX\nYYYYYYY", annotation="int"),
1695 DocstringReceive("", description="ZZZZZZZ", annotation="int"),
1696 ],
1697 ),
1698 ],
1699)
1700def test_parse_receives_multiple_items(
1701 parse_google: ParserType,
1702 receives_multiple_items: bool,
1703 return_annotation: str,
1704 expected: list[DocstringReceive],
1705) -> None:
1706 """Parse Returns section with and without multiple items.
1708 Parameters:
1709 parse_google: Fixture parser.
1710 receives_multiple_items: Whether the `Receives` section has multiple items.
1711 return_annotation: The return annotation of the function to parse. Usually a `Generator`.
1712 expected: The expected value of the parsed Receives section.
1713 """
1714 parent = (
1715 Function("func", returns=parse_docstring_annotation(return_annotation, Docstring("d", parent=Function("f"))))
1716 if return_annotation is not None
1717 else None
1718 )
1719 docstring = """
1720 Receives:
1721 XXXXXXX
1722 YYYYYYY
1723 ZZZZZZZ
1724 """
1725 sections, _ = parse_google(
1726 docstring,
1727 receives_multiple_items=receives_multiple_items,
1728 parent=parent,
1729 )
1731 assert len(sections) == 1
1732 assert len(sections[0].value) == len(expected)
1734 for annotated, expected_ in zip(sections[0].value, expected, strict=False):
1735 assert annotated.name == expected_.name
1736 assert str(annotated.annotation) == str(expected_.annotation)
1737 assert annotated.description == expected_.description
1740def test_avoid_false_positive_sections(parse_google: ParserType) -> None:
1741 """Avoid false positive when parsing sections.
1743 Parameters:
1744 parse_google: Fixture parser.
1745 """
1746 docstring = """
1747 Summary.
1748 Modules:
1749 Not a modules section.
1750 No blank line before title:
1751 Not an admonition.
1753 Blank line after title:
1755 Not an admonition.
1757 Modules:
1759 Not a modules section.
1760 Modules:
1762 Not a modules section.
1763 No blank line before and blank line after:
1765 Not an admonition.
1767 Classes:
1769 - Text.
1770 """
1771 sections, warnings = parse_google(docstring)
1772 assert len(sections) == 1
1773 assert "Classes" in sections[0].value
1774 assert "Text" in sections[0].value
1775 assert len(warnings) == 6
1776 assert warnings == [
1777 "Possible section skipped, reasons: Missing blank line above section",
1778 "Possible admonition skipped, reasons: Missing blank line above admonition",
1779 "Possible admonition skipped, reasons: Extraneous blank line below admonition title",
1780 "Possible section skipped, reasons: Extraneous blank line below section title",
1781 "Possible section skipped, reasons: Missing blank line above section; Extraneous blank line below section title",
1782 "Possible admonition skipped, reasons: Missing blank line above admonition; Extraneous blank line below admonition title",
1783 ]
1786def test_type_in_returns_without_parentheses(parse_google: ParserType) -> None:
1787 """Assert we can parse the return type without parentheses.
1789 Parameters:
1790 parse_google: Fixture parser.
1791 """
1792 docstring = """
1793 Summary.
1795 Returns:
1796 int: Description
1797 on several lines.
1798 """
1799 sections, warnings = parse_google(docstring, returns_named_value=False)
1800 assert len(sections) == 2
1801 assert not warnings
1802 retval = sections[1].value[0]
1803 assert retval.name == ""
1804 assert retval.annotation == "int"
1805 assert retval.description == "Description\non several lines."
1807 docstring = """
1808 Summary.
1810 Returns:
1811 Description
1812 on several lines.
1813 """
1814 sections, warnings = parse_google(docstring, returns_named_value=False)
1815 assert len(sections) == 2
1816 assert len(warnings) == 1
1817 retval = sections[1].value[0]
1818 assert retval.name == ""
1819 assert retval.annotation is None
1820 assert retval.description == "Description\non several lines."
1823def test_type_in_yields_without_parentheses(parse_google: ParserType) -> None:
1824 """Assert we can parse the return type without parentheses.
1826 Parameters:
1827 parse_google: Fixture parser.
1828 """
1829 docstring = """
1830 Summary.
1832 Yields:
1833 int: Description
1834 on several lines.
1835 """
1836 sections, warnings = parse_google(docstring, returns_named_value=False)
1837 assert len(sections) == 2
1838 assert not warnings
1839 retval = sections[1].value[0]
1840 assert retval.name == ""
1841 assert retval.annotation == "int"
1842 assert retval.description == "Description\non several lines."
1844 docstring = """
1845 Summary.
1847 Yields:
1848 Description
1849 on several lines.
1850 """
1851 sections, warnings = parse_google(docstring, returns_named_value=False)
1852 assert len(sections) == 2
1853 assert len(warnings) == 1
1854 retval = sections[1].value[0]
1855 assert retval.name == ""
1856 assert retval.annotation is None
1857 assert retval.description == "Description\non several lines."
1860def test_type_in_receives_without_parentheses(parse_google: ParserType) -> None:
1861 """Assert we can parse the return type without parentheses.
1863 Parameters:
1864 parse_google: Fixture parser.
1865 """
1866 docstring = """
1867 Summary.
1869 Receives:
1870 int: Description
1871 on several lines.
1872 """
1873 sections, warnings = parse_google(docstring, receives_named_value=False)
1874 assert len(sections) == 2
1875 assert not warnings
1876 retval = sections[1].value[0]
1877 assert retval.name == ""
1878 assert retval.annotation == "int"
1879 assert retval.description == "Description\non several lines."
1881 docstring = """
1882 Summary.
1884 Receives:
1885 Description
1886 on several lines.
1887 """
1888 sections, warnings = parse_google(docstring, receives_named_value=False)
1889 assert len(sections) == 2
1890 assert len(warnings) == 1
1891 retval = sections[1].value[0]
1892 assert retval.name == ""
1893 assert retval.annotation is None
1894 assert retval.description == "Description\non several lines."
1897def test_reading_property_type_in_summary(parse_google: ParserType) -> None:
1898 """Assert we can parse the return type of properties in their summary.
1900 Parameters:
1901 parse_google: Fixture parser.
1902 """
1903 docstring = "str: Description of the property."
1904 parent = Attribute("prop")
1905 parent.labels.add("property")
1906 sections, _ = parse_google(docstring, returns_type_in_property_summary=True, parent=parent)
1907 assert len(sections) == 2
1908 assert sections[0].kind is DocstringSectionKind.text
1909 assert sections[1].kind is DocstringSectionKind.returns
1910 retval = sections[1].value[0]
1911 assert retval.name == ""
1912 assert retval.annotation.name == "str"
1913 assert retval.description == ""
1916# =============================================================================================
1917# Warnings
1918def test_disabled_warnings(parse_google: ParserType) -> None:
1919 """Assert warnings are disabled.
1921 Parameters:
1922 parse_google: Fixture parser.
1923 """
1924 docstring = """
1925 Parameters:
1926 x: X value.
1927 """
1928 _, warnings = parse_google(docstring, warnings=True)
1929 assert warnings
1930 _, warnings = parse_google(docstring, warnings=False)
1931 assert not warnings