Coverage for tests/test_docstrings/test_google.py: 100.00%
571 statements
« prev ^ index » next coverage.py v7.10.2, created at 2025-08-11 13:44 +0200
« prev ^ index » next coverage.py v7.10.2, created at 2025-08-11 13:44 +0200
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
579# =============================================================================================
580# Parameters sections
581def test_parse_args_and_kwargs(parse_google: ParserType) -> None:
582 """Parse args and kwargs.
584 Parameters:
585 parse_google: Fixture parser.
586 """
587 docstring = """
588 Parameters:
589 a (str): a parameter.
590 *args (str): args parameters.
591 **kwargs (str): kwargs parameters.
592 """
594 sections, warnings = parse_google(docstring)
595 assert len(sections) == 1
596 expected_parameters = {"a": "a parameter.", "*args": "args parameters.", "**kwargs": "kwargs parameters."}
597 for parameter in sections[0].value:
598 assert parameter.name in expected_parameters
599 assert expected_parameters[parameter.name] == parameter.description
600 assert not warnings
603def test_parse_args_kwargs_keyword_only(parse_google: ParserType) -> None:
604 """Parse args and kwargs.
606 Parameters:
607 parse_google: Fixture parser.
608 """
609 docstring = """
610 Parameters:
611 a (str): a parameter.
612 *args (str): args parameters.
614 Keyword Args:
615 **kwargs (str): kwargs parameters.
616 """
618 sections, warnings = parse_google(docstring)
619 assert len(sections) == 2
620 expected_parameters = {"a": "a parameter.", "*args": "args parameters."}
621 for parameter in sections[0].value:
622 assert parameter.name in expected_parameters
623 assert expected_parameters[parameter.name] == parameter.description
625 expected_parameters = {"**kwargs": "kwargs parameters."}
626 for kwarg in sections[1].value:
627 assert kwarg.name in expected_parameters
628 assert expected_parameters[kwarg.name] == kwarg.description
630 assert not warnings
633def test_parse_types_in_docstring(parse_google: ParserType) -> None:
634 """Parse types in docstring.
636 Parameters:
637 parse_google: Fixture parser.
638 """
639 docstring = """
640 Parameters:
641 x (int): X value.
643 Keyword Args:
644 y (int): Y value.
646 Returns:
647 s (int): Sum X + Y + Z.
648 """
650 sections, warnings = parse_google(
651 docstring,
652 parent=Function(
653 "func",
654 parameters=Parameters(
655 Parameter("x"),
656 Parameter("y"),
657 ),
658 ),
659 )
660 assert len(sections) == 3
661 assert not warnings
663 assert sections[0].kind is DocstringSectionKind.parameters
664 assert sections[1].kind is DocstringSectionKind.other_parameters
665 assert sections[2].kind is DocstringSectionKind.returns
667 (argx,) = sections[0].value
668 (argy,) = sections[1].value
669 (returns,) = sections[2].value
671 assert argx.name == "x"
672 assert argx.annotation.name == "int"
673 assert argx.annotation.canonical_path == "int"
674 assert argx.description == "X value."
675 assert argx.value is None
677 assert argy.name == "y"
678 assert argy.annotation.name == "int"
679 assert argy.annotation.canonical_path == "int"
680 assert argy.description == "Y value."
681 assert argy.value is None
683 assert returns.annotation.name == "int"
684 assert returns.annotation.canonical_path == "int"
685 assert returns.description == "Sum X + Y + Z."
688def test_parse_optional_type_in_docstring(parse_google: ParserType) -> None:
689 """Parse optional types in docstring.
691 Parameters:
692 parse_google: Fixture parser.
693 """
694 docstring = """
695 Parameters:
696 x (int): X value.
697 y (int, optional): Y value.
699 Keyword Args:
700 z (int, optional): Z value.
701 """
703 sections, warnings = parse_google(
704 docstring,
705 parent=Function(
706 "func",
707 parameters=Parameters(
708 Parameter("x", default="1"),
709 Parameter("y", default="None"),
710 Parameter("z", default="None"),
711 ),
712 ),
713 )
714 assert len(sections) == 2
715 assert not warnings
717 assert sections[0].kind is DocstringSectionKind.parameters
718 assert sections[1].kind is DocstringSectionKind.other_parameters
720 argx, argy = sections[0].value
721 (argz,) = sections[1].value
723 assert argx.name == "x"
724 assert argx.annotation.name == "int"
725 assert argx.annotation.canonical_path == "int"
726 assert argx.description == "X value."
727 assert argx.value == "1"
729 assert argy.name == "y"
730 assert argy.annotation.name == "int"
731 assert argy.annotation.canonical_path == "int"
732 assert argy.description == "Y value."
733 assert argy.value == "None"
735 assert argz.name == "z"
736 assert argz.annotation.name == "int"
737 assert argz.annotation.canonical_path == "int"
738 assert argz.description == "Z value."
739 assert argz.value == "None"
742def test_prefer_docstring_types_over_annotations(parse_google: ParserType) -> None:
743 """Prefer the docstring type over the annotation.
745 Parameters:
746 parse_google: Fixture parser.
747 """
748 docstring = """
749 Parameters:
750 x (str): X value.
752 Keyword Args:
753 y (str): Y value.
755 Returns:
756 (str): Sum X + Y + Z.
757 """
759 sections, warnings = parse_google(
760 docstring,
761 parent=Function(
762 "func",
763 parameters=Parameters(
764 Parameter("x", annotation="int"),
765 Parameter("y", annotation="int"),
766 ),
767 returns="int",
768 ),
769 )
770 assert len(sections) == 3
771 assert not warnings
773 assert sections[0].kind is DocstringSectionKind.parameters
774 assert sections[1].kind is DocstringSectionKind.other_parameters
775 assert sections[2].kind is DocstringSectionKind.returns
777 (argx,) = sections[0].value
778 (argy,) = sections[1].value
779 (returns,) = sections[2].value
781 assert argx.name == "x"
782 assert argx.annotation.name == "str"
783 assert argx.annotation.canonical_path == "str"
784 assert argx.description == "X value."
786 assert argy.name == "y"
787 assert argy.annotation.name == "str"
788 assert argy.annotation.canonical_path == "str"
789 assert argy.description == "Y value."
791 assert returns.annotation.name == "str"
792 assert returns.annotation.canonical_path == "str"
793 assert returns.description == "Sum X + Y + Z."
796def test_parameter_line_without_colon(parse_google: ParserType) -> None:
797 """Warn when missing colon.
799 Parameters:
800 parse_google: Fixture parser.
801 """
802 docstring = """
803 Parameters:
804 x is an integer.
805 """
807 sections, warnings = parse_google(docstring)
808 assert len(sections) == 0 # Empty sections are discarded.
809 assert len(warnings) == 1
810 assert "pair" in warnings[0]
813def test_parameter_line_without_colon_keyword_only(parse_google: ParserType) -> None:
814 """Warn when missing colon.
816 Parameters:
817 parse_google: Fixture parser.
818 """
819 docstring = """
820 Keyword Args:
821 x is an integer.
822 """
824 sections, warnings = parse_google(docstring)
825 assert len(sections) == 0 # Empty sections are discarded.
826 assert len(warnings) == 1
827 assert "pair" in warnings[0]
830def test_warn_about_unknown_parameters(parse_google: ParserType) -> None:
831 """Warn about unknown parameters in "Parameters" sections.
833 Parameters:
834 parse_google: Fixture parser.
835 """
836 docstring = """
837 Parameters:
838 x (int): Integer.
839 y (int): Integer.
840 """
842 _, warnings = parse_google(
843 docstring,
844 parent=Function(
845 "func",
846 parameters=Parameters(
847 Parameter("a"),
848 Parameter("y"),
849 ),
850 ),
851 )
852 assert len(warnings) == 1
853 assert "'x' does not appear in the function signature" in warnings[0]
856def test_never_warn_about_unknown_other_parameters(parse_google: ParserType) -> None:
857 """Never warn about unknown parameters in "Other parameters" sections.
859 Parameters:
860 parse_google: Fixture parser.
861 """
862 docstring = """
863 Other Parameters:
864 x (int): Integer.
865 z (int): Integer.
866 """
868 _, warnings = parse_google(
869 docstring,
870 parent=Function(
871 "func",
872 parameters=Parameters(
873 Parameter("a"),
874 Parameter("y"),
875 ),
876 ),
877 )
878 assert not warnings
881def test_unknown_params_scan_doesnt_crash_without_parameters(parse_google: ParserType) -> None:
882 """Assert we don't crash when parsing parameters sections and parent object does not have parameters.
884 Parameters:
885 parse_google: Fixture parser.
886 """
887 docstring = """
888 Parameters:
889 this (str): This.
890 that (str): That.
891 """
893 _, warnings = parse_google(docstring, parent=Module("mod"))
894 assert not warnings
897def test_class_uses_init_parameters(parse_google: ParserType) -> None:
898 """Assert we use the `__init__` parameters when parsing classes' parameters sections.
900 Parameters:
901 parse_google: Fixture parser.
902 """
903 docstring = """
904 Parameters:
905 x: X value.
906 """
907 parent = Class("c")
908 parent["__init__"] = Function("__init__", parameters=Parameters(Parameter("x", annotation="int")))
909 sections, warnings = parse_google(docstring, parent=parent)
910 assert not warnings
911 argx = sections[0].value[0]
912 assert argx.name == "x"
913 assert argx.annotation == "int"
914 assert argx.description == "X value."
917# TODO: possible feature
918# def test_missing_parameter(parse_google: ParserType) -> None:
919# """Warn on missing parameter in docstring.
920#
921# Parameters:
922# parse_google: Fixture parser.
923# """
924# docstring = """
925# Parameters:
926# x: Integer.
927# """
928# assert not warnings
931# =============================================================================================
932# Type parameters sections
933def test_parse_type_var_tuples_and_param_specs(parse_google: ParserType) -> None:
934 """Parse type variable tuples and parameter specifications.
936 Parameters:
937 parse_google: Fixture parser.
938 """
939 docstring = """
940 Type Parameters:
941 T: A type parameter.
942 C (str, (int, float)): A constrained type parameter.
943 D complex: A bounded type parameter.
944 """
946 sections, warnings = parse_google(docstring)
947 assert len(sections) == 1
948 expected_type_parameters = {
949 "T": ("A type parameter.", None),
950 "C": ("A constrained type parameter.", "str, (int, float)"),
951 "D": ("A bounded type parameter.", "complex"),
952 }
953 for type_parameter in sections[0].value:
954 assert type_parameter.name in expected_type_parameters
955 assert expected_type_parameters[type_parameter.name][0] == type_parameter.description
956 assert expected_type_parameters[type_parameter.name][1] == type_parameter.annotation
957 assert not warnings
960def test_prefer_docstring_bounds_over_annotations(parse_google: ParserType) -> None:
961 """Prefer the docstring bound over the annotation.
963 Parameters:
964 parse_google: Fixture parser.
965 """
966 docstring = """
967 Type Parameters:
968 X (str): X type.
969 Y str, int: Y type.
970 """
972 sections, warnings = parse_google(
973 docstring,
974 parent=Function(
975 "func",
976 type_parameters=TypeParameters(
977 TypeParameter("X", kind=TypeParameterKind.type_var, constraints=["complex"]),
978 TypeParameter("Y", kind=TypeParameterKind.type_var, bound="int"),
979 ),
980 ),
981 )
982 assert len(sections) == 1
983 assert not warnings
985 assert sections[0].kind is DocstringSectionKind.type_parameters
987 (x, y) = sections[0].value
989 assert x.name == "X"
990 assert str(x.bound) == "str"
991 assert x.constraints is None
993 assert y.name == "Y"
994 assert y.bound is None
995 assert [str(constraint) for constraint in y.constraints] == ["str", "int"]
998def test_type_parameter_line_without_colon(parse_google: ParserType) -> None:
999 """Warn when missing colon.
1001 Parameters:
1002 parse_google: Fixture parser.
1003 """
1004 docstring = """
1005 Type Parameters:
1006 X is an integer type.
1007 """
1009 sections, warnings = parse_google(docstring)
1010 assert len(sections) == 0 # empty sections are discarded
1011 assert len(warnings) == 1
1012 assert "pair" in warnings[0]
1015def test_warn_about_unknown_type_parameters(parse_google: ParserType) -> None:
1016 """Warn about unknown type parameters in "Type Parameters" sections.
1018 Parameters:
1019 parse_google: Fixture parser.
1020 """
1021 docstring = """
1022 Type Parameters:
1023 X (int): Integer.
1024 Y (int): Integer.
1025 """
1027 _, warnings = parse_google(
1028 docstring,
1029 parent=Function(
1030 "func",
1031 type_parameters=TypeParameters(
1032 TypeParameter("A", kind=TypeParameterKind.type_var),
1033 TypeParameter("Y", kind=TypeParameterKind.type_var),
1034 ),
1035 ),
1036 )
1037 assert len(warnings) == 1
1038 assert "'X' does not appear in the function signature" in warnings[0]
1041def test_unknown_type_params_scan_doesnt_crash_without_type_parameters(parse_google: ParserType) -> None:
1042 """Assert we don't crash when parsing type parameters sections and parent object does not have type parameters.
1044 Parameters:
1045 parse_google: Fixture parser.
1046 """
1047 docstring = """
1048 TypeParameters:
1049 This (str): This.
1050 That: That.
1051 """
1053 _, warnings = parse_google(docstring, parent=Module("mod"))
1054 assert not warnings
1057# =============================================================================================
1058# Attributes sections
1059def test_retrieve_attributes_annotation_from_parent(parse_google: ParserType) -> None:
1060 """Retrieve the annotations of attributes from the parent object.
1062 Parameters:
1063 parse_google: Fixture parser.
1064 """
1065 docstring = """
1066 Summary.
1068 Attributes:
1069 a: Whatever.
1070 b: Whatever.
1071 """
1072 parent = Class("cls")
1073 parent["a"] = Attribute("a", annotation=ExprName("int"))
1074 parent["b"] = Attribute("b", annotation=ExprName("str"))
1075 sections, _ = parse_google(docstring, parent=parent)
1076 attributes = sections[1].value
1077 assert attributes[0].name == "a"
1078 assert attributes[0].annotation.name == "int"
1079 assert attributes[1].name == "b"
1080 assert attributes[1].annotation.name == "str"
1083# =============================================================================================
1084# Yields sections
1085def test_parse_yields_section_with_return_annotation(parse_google: ParserType) -> None:
1086 """Parse Yields section with a return annotation in the parent function.
1088 Parameters:
1089 parse_google: Fixture parser.
1090 """
1091 docstring = """
1092 Yields:
1093 Integers.
1094 """
1096 function = Function("func", returns="Iterator[int]")
1097 sections, warnings = parse_google(docstring, function)
1098 assert len(sections) == 1
1099 annotated = sections[0].value[0]
1100 assert annotated.annotation == "Iterator[int]"
1101 assert annotated.description == "Integers."
1102 assert not warnings
1105@pytest.mark.parametrize(
1106 "return_annotation",
1107 [
1108 "Iterator[tuple[int, float]]",
1109 "Generator[tuple[int, float], ..., ...]",
1110 ],
1111)
1112def test_parse_yields_tuple_in_iterator_or_generator(parse_google: ParserType, return_annotation: str) -> None:
1113 """Parse Yields annotations in Iterator or Generator types.
1115 Parameters:
1116 parse_google: Fixture parser.
1117 return_annotation: Parametrized return annotation as a string.
1118 """
1119 docstring = """
1120 Summary.
1122 Yields:
1123 a: Whatever.
1124 b: Whatever.
1125 """
1126 sections, _ = parse_google(
1127 docstring,
1128 parent=Function(
1129 "func",
1130 returns=parse_docstring_annotation(return_annotation, Docstring("d", parent=Function("f"))),
1131 ),
1132 )
1133 yields = sections[1].value
1134 assert yields[0].name == "a"
1135 assert yields[0].annotation.name == "int"
1136 assert yields[1].name == "b"
1137 assert yields[1].annotation.name == "float"
1140@pytest.mark.parametrize(
1141 "return_annotation",
1142 [
1143 "Iterator[int]",
1144 "Generator[int, None, None]",
1145 ],
1146)
1147def test_extract_yielded_type_with_single_return_item(parse_google: ParserType, return_annotation: str) -> None:
1148 """Extract main type annotation from Iterator or Generator.
1150 Parameters:
1151 parse_google: Fixture parser.
1152 return_annotation: Parametrized return annotation as a string.
1153 """
1154 docstring = """
1155 Summary.
1157 Yields:
1158 A number.
1159 """
1160 sections, _ = parse_google(
1161 docstring,
1162 parent=Function(
1163 "func",
1164 returns=parse_docstring_annotation(return_annotation, Docstring("d", parent=Function("f"))),
1165 ),
1166 )
1167 yields = sections[1].value
1168 assert yields[0].annotation.name == "int"
1171def test_yield_section_in_property(parse_google: ParserType) -> None:
1172 """No warnings when parsing Yields section in a property.
1174 Parameters:
1175 parse_google: Fixture parser.
1176 """
1177 docstring = """
1178 Summary.
1180 Yields:
1181 A number.
1182 """
1183 sections, warnings = parse_google(
1184 docstring,
1185 parent=Attribute(
1186 "prop",
1187 annotation=parse_docstring_annotation("Iterator[int]", Docstring("d", parent=Attribute("a"))),
1188 ),
1189 )
1190 assert not warnings
1191 yields = sections[1].value
1192 assert yields[0].annotation.name == "int"
1195# =============================================================================================
1196# Receives sections
1197def test_parse_receives_tuple_in_generator(parse_google: ParserType) -> None:
1198 """Parse Receives annotations in Generator type.
1200 Parameters:
1201 parse_google: Fixture parser.
1202 """
1203 docstring = """
1204 Summary.
1206 Receives:
1207 a: Whatever.
1208 b: Whatever.
1209 """
1210 sections, _ = parse_google(
1211 docstring,
1212 parent=Function(
1213 "func",
1214 returns=parse_docstring_annotation(
1215 "Generator[..., tuple[int, float], ...]",
1216 Docstring("d", parent=Function("f")),
1217 ),
1218 ),
1219 )
1220 receives = sections[1].value
1221 assert receives[0].name == "a"
1222 assert receives[0].annotation.name == "int"
1223 assert receives[1].name == "b"
1224 assert receives[1].annotation.name == "float"
1227@pytest.mark.parametrize(
1228 "return_annotation",
1229 [
1230 "Generator[int, float, None]",
1231 ],
1232)
1233def test_extract_received_type_with_single_return_item(parse_google: ParserType, return_annotation: str) -> None:
1234 """Extract main type annotation from Iterator or Generator.
1236 Parameters:
1237 parse_google: Fixture parser.
1238 return_annotation: Parametrized return annotation as a string.
1239 """
1240 docstring = """
1241 Summary.
1243 Receives:
1244 A floating point number.
1245 """
1246 sections, _ = parse_google(
1247 docstring,
1248 parent=Function(
1249 "func",
1250 returns=parse_docstring_annotation(return_annotation, Docstring("d", parent=Function("f"))),
1251 ),
1252 )
1253 receives = sections[1].value
1254 assert receives[0].annotation.name == "float"
1257# =============================================================================================
1258# Returns sections
1259def test_parse_returns_tuple_in_generator(parse_google: ParserType) -> None:
1260 """Parse Returns annotations in Generator type.
1262 Parameters:
1263 parse_google: Fixture parser.
1264 """
1265 docstring = """
1266 Summary.
1268 Returns:
1269 a: Whatever.
1270 b: Whatever.
1271 """
1272 sections, _ = parse_google(
1273 docstring,
1274 parent=Function(
1275 "func",
1276 returns=parse_docstring_annotation(
1277 "Generator[..., ..., tuple[int, float]]",
1278 Docstring("d", parent=Function("f")),
1279 ),
1280 ),
1281 )
1282 returns = sections[1].value
1283 assert returns[0].name == "a"
1284 assert returns[0].annotation.name == "int"
1285 assert returns[1].name == "b"
1286 assert returns[1].annotation.name == "float"
1289# =============================================================================================
1290# Parser special features
1291def test_parse_admonitions(parse_google: ParserType) -> None:
1292 """Parse admonitions.
1294 Parameters:
1295 parse_google: Fixture parser.
1296 """
1297 docstring = """
1298 Important note:
1299 Hello.
1301 Note: With title.
1302 Hello again.
1304 Something:
1305 Something.
1306 """
1308 sections, warnings = parse_google(docstring)
1309 assert len(sections) == 3
1310 assert not warnings
1311 assert sections[0].title == "Important note"
1312 assert sections[0].value.kind == "important-note"
1313 assert sections[0].value.contents == "Hello."
1314 assert sections[1].title == "With title."
1315 assert sections[1].value.kind == "note"
1316 assert sections[1].value.contents == "Hello again."
1317 assert sections[2].title == "Something"
1318 assert sections[2].value.kind == "something"
1319 assert sections[2].value.contents == "Something."
1322@pytest.mark.parametrize(
1323 "docstring",
1324 [
1325 """
1326 ******************************
1327 This looks like an admonition:
1328 ******************************
1329 """,
1330 """
1331 Warning: this line also looks
1332 like an admonition.
1333 """,
1334 """
1335 Matching but not an admonition:
1339 - Multiple empty lines above.
1340 """,
1341 """Last line:""",
1342 ],
1343)
1344def test_handle_false_admonitions_correctly(parse_google: ParserType, docstring: str) -> None:
1345 """Correctly handle lines that look like admonitions.
1347 Parameters:
1348 parse_google: Fixture parser.
1349 docstring: The docstring to parse (parametrized).
1350 """
1351 sections, warnings = parse_google(docstring)
1352 assert len(sections) == 1
1353 assert sections[0].kind is DocstringSectionKind.text
1354 assert len(sections[0].value.splitlines()) == len(inspect.cleandoc(docstring).splitlines())
1355 assert not warnings
1358def test_dont_insert_admonition_before_current_section(parse_google: ParserType) -> None:
1359 """Check that admonitions are inserted at the right place.
1361 Parameters:
1362 parse_google: Fixture parser.
1363 """
1364 docstring = """
1365 Summary.
1367 Short description.
1369 Info:
1370 Something useful.
1371 """
1372 sections, _ = parse_google(docstring)
1373 assert len(sections) == 2
1374 assert sections[0].kind is DocstringSectionKind.text
1375 assert sections[1].kind is DocstringSectionKind.admonition
1378@pytest.mark.parametrize(
1379 "docstring",
1380 [
1381 "",
1382 "\n",
1383 "\n\n",
1384 "Summary.",
1385 "Summary.\n\n\n",
1386 "Summary.\n\nParagraph.",
1387 "Summary\non two lines.",
1388 "Summary\non two lines.\n\nParagraph.",
1389 ],
1390)
1391def test_ignore_init_summary(parse_google: ParserType, docstring: str) -> None:
1392 """Correctly ignore summary in `__init__` methods' docstrings.
1394 Parameters:
1395 parse_google: Fixture parser.
1396 docstring: The docstring to parse_google (parametrized).
1397 """
1398 sections, _ = parse_google(docstring, parent=Function("__init__", parent=Class("C")), ignore_init_summary=True)
1399 for section in sections:
1400 assert "Summary" not in section.value
1402 if docstring.strip():
1403 sections, _ = parse_google(docstring, parent=Function("__init__", parent=Module("M")), ignore_init_summary=True)
1404 assert "Summary" in sections[0].value
1405 sections, _ = parse_google(docstring, parent=Function("f", parent=Class("C")), ignore_init_summary=True)
1406 assert "Summary" in sections[0].value
1407 sections, _ = parse_google(docstring, ignore_init_summary=True)
1408 assert "Summary" in sections[0].value
1411@pytest.mark.parametrize(
1412 "docstring",
1413 [
1414 """
1415 Examples:
1416 Base case 1. We want to skip the following test.
1417 >>> 1 + 1 == 3 # doctest: +SKIP
1418 True
1419 """,
1420 r"""
1421 Examples:
1422 Base case 2. We have a blankline test.
1423 >>> print("a\n\nb")
1424 a
1425 <BLANKLINE>
1426 b
1427 """,
1428 ],
1429)
1430def test_trim_doctest_flags_basic_example(parse_google: ParserType, docstring: str) -> None:
1431 """Correctly parse simple example docstrings when `trim_doctest_flags` option is turned on.
1433 Parameters:
1434 parse_google: Fixture parser.
1435 docstring: The docstring to parse (parametrized).
1436 """
1437 sections, warnings = parse_google(docstring, trim_doctest_flags=True)
1438 assert len(sections) == 1
1439 assert len(sections[0].value) == 2
1440 assert not warnings
1442 # Verify that doctest flags have indeed been trimmed.
1443 example_str = sections[0].value[1][1]
1444 assert "# doctest: +SKIP" not in example_str
1445 assert "<BLANKLINE>" not in example_str
1448def test_trim_doctest_flags_multi_example(parse_google: ParserType) -> None:
1449 """Correctly parse multiline example docstrings when `trim_doctest_flags` option is turned on.
1451 Parameters:
1452 parse_google: Fixture parser.
1453 """
1454 docstring = r"""
1455 Examples:
1456 Test multiline example blocks.
1457 We want to skip the following test.
1458 >>> 1 + 1 == 3 # doctest: +SKIP
1459 True
1461 And then a few more examples here:
1462 >>> print("a\n\nb")
1463 a
1464 <BLANKLINE>
1465 b
1466 >>> 1 + 1 == 2 # doctest: +SKIP
1467 >>> print(list(range(1, 100))) # doctest: +ELLIPSIS
1468 [1, 2, ..., 98, 99]
1469 """
1470 sections, warnings = parse_google(docstring, trim_doctest_flags=True)
1471 assert len(sections) == 1
1472 assert len(sections[0].value) == 4
1473 assert not warnings
1475 # Verify that doctest flags have indeed been trimmed.
1476 example_str = sections[0].value[1][1]
1477 assert "# doctest: +SKIP" not in example_str
1478 example_str = sections[0].value[3][1]
1479 assert "<BLANKLINE>" not in example_str
1480 assert "\n>>> print(list(range(1, 100)))\n" in example_str
1483def test_single_line_with_trailing_whitespace(parse_google: ParserType) -> None:
1484 """Don't crash on single line docstrings with trailing whitespace.
1486 Parameters:
1487 parse_google: Fixture parser.
1488 """
1489 docstring = "a: b\n "
1490 sections, warnings = parse_google(docstring, trim_doctest_flags=True)
1491 assert len(sections) == 1
1492 assert sections[0].kind is DocstringSectionKind.text
1493 assert not warnings
1496@pytest.mark.parametrize(
1497 ("returns_multiple_items", "return_annotation", "expected"),
1498 [
1499 (
1500 False,
1501 None,
1502 [DocstringReturn("", description="XXXXXXX\n YYYYYYY\nZZZZZZZ", annotation=None)],
1503 ),
1504 (
1505 False,
1506 "tuple[int, int]",
1507 [DocstringReturn("", description="XXXXXXX\n YYYYYYY\nZZZZZZZ", annotation="tuple[int, int]")],
1508 ),
1509 (
1510 True,
1511 None,
1512 [
1513 DocstringReturn("", description="XXXXXXX\nYYYYYYY", annotation=None),
1514 DocstringReturn("", description="ZZZZZZZ", annotation=None),
1515 ],
1516 ),
1517 (
1518 True,
1519 "tuple[int,int]",
1520 [
1521 DocstringReturn("", description="XXXXXXX\nYYYYYYY", annotation="int"),
1522 DocstringReturn("", description="ZZZZZZZ", annotation="int"),
1523 ],
1524 ),
1525 ],
1526)
1527def test_parse_returns_multiple_items(
1528 parse_google: ParserType,
1529 returns_multiple_items: bool,
1530 return_annotation: str,
1531 expected: list[DocstringReturn],
1532) -> None:
1533 """Parse Returns section with and without multiple items.
1535 Parameters:
1536 parse_google: Fixture parser.
1537 returns_multiple_items: Whether the `Returns` section has multiple items.
1538 return_annotation: The return annotation of the function to parse.
1539 expected: The expected value of the parsed Returns section.
1540 """
1541 parent = (
1542 Function("func", returns=parse_docstring_annotation(return_annotation, Docstring("d", parent=Function("f"))))
1543 if return_annotation is not None
1544 else None
1545 )
1546 docstring = """
1547 Returns:
1548 XXXXXXX
1549 YYYYYYY
1550 ZZZZZZZ
1551 """
1552 sections, _ = parse_google(
1553 docstring,
1554 returns_multiple_items=returns_multiple_items,
1555 parent=parent,
1556 )
1558 assert len(sections) == 1
1559 assert len(sections[0].value) == len(expected)
1561 for annotated, expected_ in zip(sections[0].value, expected):
1562 assert annotated.name == expected_.name
1563 assert str(annotated.annotation) == str(expected_.annotation)
1564 assert annotated.description == expected_.description
1567@pytest.mark.parametrize(
1568 ("returns_multiple_items", "return_annotation", "expected"),
1569 [
1570 (
1571 False,
1572 None,
1573 [DocstringYield("", description="XXXXXXX\n YYYYYYY\nZZZZZZZ", annotation=None)],
1574 ),
1575 (
1576 False,
1577 "Iterator[tuple[int, int]]",
1578 [DocstringYield("", description="XXXXXXX\n YYYYYYY\nZZZZZZZ", annotation="tuple[int, int]")],
1579 ),
1580 (
1581 True,
1582 None,
1583 [
1584 DocstringYield("", description="XXXXXXX\nYYYYYYY", annotation=None),
1585 DocstringYield("", description="ZZZZZZZ", annotation=None),
1586 ],
1587 ),
1588 (
1589 True,
1590 "Iterator[tuple[int,int]]",
1591 [
1592 DocstringYield("", description="XXXXXXX\nYYYYYYY", annotation="int"),
1593 DocstringYield("", description="ZZZZZZZ", annotation="int"),
1594 ],
1595 ),
1596 ],
1597)
1598def test_parse_yields_multiple_items(
1599 parse_google: ParserType,
1600 returns_multiple_items: bool,
1601 return_annotation: str,
1602 expected: list[DocstringYield],
1603) -> None:
1604 """Parse Returns section with and without multiple items.
1606 Parameters:
1607 parse_google: Fixture parser.
1608 returns_multiple_items: Whether the `Returns` and `Yields` sections have multiple items.
1609 return_annotation: The return annotation of the function to parse. Usually an `Iterator`.
1610 expected: The expected value of the parsed Yields section.
1611 """
1612 parent = (
1613 Function("func", returns=parse_docstring_annotation(return_annotation, Docstring("d", parent=Function("f"))))
1614 if return_annotation is not None
1615 else None
1616 )
1617 docstring = """
1618 Yields:
1619 XXXXXXX
1620 YYYYYYY
1621 ZZZZZZZ
1622 """
1623 sections, _ = parse_google(
1624 docstring,
1625 returns_multiple_items=returns_multiple_items,
1626 parent=parent,
1627 )
1629 assert len(sections) == 1
1630 assert len(sections[0].value) == len(expected)
1632 for annotated, expected_ in zip(sections[0].value, expected):
1633 assert annotated.name == expected_.name
1634 assert str(annotated.annotation) == str(expected_.annotation)
1635 assert annotated.description == expected_.description
1638@pytest.mark.parametrize(
1639 ("receives_multiple_items", "return_annotation", "expected"),
1640 [
1641 (
1642 False,
1643 None,
1644 [DocstringReceive("", description="XXXXXXX\n YYYYYYY\nZZZZZZZ", annotation=None)],
1645 ),
1646 (
1647 False,
1648 "Generator[..., tuple[int, int], ...]",
1649 [DocstringReceive("", description="XXXXXXX\n YYYYYYY\nZZZZZZZ", annotation="tuple[int, int]")],
1650 ),
1651 (
1652 True,
1653 None,
1654 [
1655 DocstringReceive("", description="XXXXXXX\nYYYYYYY", annotation=None),
1656 DocstringReceive("", description="ZZZZZZZ", annotation=None),
1657 ],
1658 ),
1659 (
1660 True,
1661 "Generator[..., tuple[int, int], ...]",
1662 [
1663 DocstringReceive("", description="XXXXXXX\nYYYYYYY", annotation="int"),
1664 DocstringReceive("", description="ZZZZZZZ", annotation="int"),
1665 ],
1666 ),
1667 ],
1668)
1669def test_parse_receives_multiple_items(
1670 parse_google: ParserType,
1671 receives_multiple_items: bool,
1672 return_annotation: str,
1673 expected: list[DocstringReceive],
1674) -> None:
1675 """Parse Returns section with and without multiple items.
1677 Parameters:
1678 parse_google: Fixture parser.
1679 receives_multiple_items: Whether the `Receives` section has multiple items.
1680 return_annotation: The return annotation of the function to parse. Usually a `Generator`.
1681 expected: The expected value of the parsed Receives section.
1682 """
1683 parent = (
1684 Function("func", returns=parse_docstring_annotation(return_annotation, Docstring("d", parent=Function("f"))))
1685 if return_annotation is not None
1686 else None
1687 )
1688 docstring = """
1689 Receives:
1690 XXXXXXX
1691 YYYYYYY
1692 ZZZZZZZ
1693 """
1694 sections, _ = parse_google(
1695 docstring,
1696 receives_multiple_items=receives_multiple_items,
1697 parent=parent,
1698 )
1700 assert len(sections) == 1
1701 assert len(sections[0].value) == len(expected)
1703 for annotated, expected_ in zip(sections[0].value, expected):
1704 assert annotated.name == expected_.name
1705 assert str(annotated.annotation) == str(expected_.annotation)
1706 assert annotated.description == expected_.description
1709def test_avoid_false_positive_sections(parse_google: ParserType) -> None:
1710 """Avoid false positive when parsing sections.
1712 Parameters:
1713 parse_google: Fixture parser.
1714 """
1715 docstring = """
1716 Summary.
1717 Modules:
1718 Not a modules section.
1719 No blank line before title:
1720 Not an admonition.
1722 Blank line after title:
1724 Not an admonition.
1726 Modules:
1728 Not a modules section.
1729 Modules:
1731 Not a modules section.
1732 No blank line before and blank line after:
1734 Not an admonition.
1736 Classes:
1738 - Text.
1739 """
1740 sections, warnings = parse_google(docstring)
1741 assert len(sections) == 1
1742 assert "Classes" in sections[0].value
1743 assert "Text" in sections[0].value
1744 assert len(warnings) == 6
1745 assert warnings == [
1746 "Possible section skipped, reasons: Missing blank line above section",
1747 "Possible admonition skipped, reasons: Missing blank line above admonition",
1748 "Possible admonition skipped, reasons: Extraneous blank line below admonition title",
1749 "Possible section skipped, reasons: Extraneous blank line below section title",
1750 "Possible section skipped, reasons: Missing blank line above section; Extraneous blank line below section title",
1751 "Possible admonition skipped, reasons: Missing blank line above admonition; Extraneous blank line below admonition title",
1752 ]
1755def test_type_in_returns_without_parentheses(parse_google: ParserType) -> None:
1756 """Assert we can parse the return type without parentheses.
1758 Parameters:
1759 parse_google: Fixture parser.
1760 """
1761 docstring = """
1762 Summary.
1764 Returns:
1765 int: Description
1766 on several lines.
1767 """
1768 sections, warnings = parse_google(docstring, returns_named_value=False)
1769 assert len(sections) == 2
1770 assert not warnings
1771 retval = sections[1].value[0]
1772 assert retval.name == ""
1773 assert retval.annotation == "int"
1774 assert retval.description == "Description\non several lines."
1776 docstring = """
1777 Summary.
1779 Returns:
1780 Description
1781 on several lines.
1782 """
1783 sections, warnings = parse_google(docstring, returns_named_value=False)
1784 assert len(sections) == 2
1785 assert len(warnings) == 1
1786 retval = sections[1].value[0]
1787 assert retval.name == ""
1788 assert retval.annotation is None
1789 assert retval.description == "Description\non several lines."
1792def test_type_in_yields_without_parentheses(parse_google: ParserType) -> None:
1793 """Assert we can parse the return type without parentheses.
1795 Parameters:
1796 parse_google: Fixture parser.
1797 """
1798 docstring = """
1799 Summary.
1801 Yields:
1802 int: Description
1803 on several lines.
1804 """
1805 sections, warnings = parse_google(docstring, returns_named_value=False)
1806 assert len(sections) == 2
1807 assert not warnings
1808 retval = sections[1].value[0]
1809 assert retval.name == ""
1810 assert retval.annotation == "int"
1811 assert retval.description == "Description\non several lines."
1813 docstring = """
1814 Summary.
1816 Yields:
1817 Description
1818 on several lines.
1819 """
1820 sections, warnings = parse_google(docstring, returns_named_value=False)
1821 assert len(sections) == 2
1822 assert len(warnings) == 1
1823 retval = sections[1].value[0]
1824 assert retval.name == ""
1825 assert retval.annotation is None
1826 assert retval.description == "Description\non several lines."
1829def test_type_in_receives_without_parentheses(parse_google: ParserType) -> None:
1830 """Assert we can parse the return type without parentheses.
1832 Parameters:
1833 parse_google: Fixture parser.
1834 """
1835 docstring = """
1836 Summary.
1838 Receives:
1839 int: Description
1840 on several lines.
1841 """
1842 sections, warnings = parse_google(docstring, receives_named_value=False)
1843 assert len(sections) == 2
1844 assert not warnings
1845 retval = sections[1].value[0]
1846 assert retval.name == ""
1847 assert retval.annotation == "int"
1848 assert retval.description == "Description\non several lines."
1850 docstring = """
1851 Summary.
1853 Receives:
1854 Description
1855 on several lines.
1856 """
1857 sections, warnings = parse_google(docstring, receives_named_value=False)
1858 assert len(sections) == 2
1859 assert len(warnings) == 1
1860 retval = sections[1].value[0]
1861 assert retval.name == ""
1862 assert retval.annotation is None
1863 assert retval.description == "Description\non several lines."
1866def test_reading_property_type_in_summary(parse_google: ParserType) -> None:
1867 """Assert we can parse the return type of properties in their summary.
1869 Parameters:
1870 parse_google: Fixture parser.
1871 """
1872 docstring = "str: Description of the property."
1873 parent = Attribute("prop")
1874 parent.labels.add("property")
1875 sections, warnings = parse_google(docstring, returns_type_in_property_summary=True, parent=parent)
1876 assert len(sections) == 2
1877 assert sections[0].kind is DocstringSectionKind.text
1878 assert sections[1].kind is DocstringSectionKind.returns
1879 retval = sections[1].value[0]
1880 assert retval.name == ""
1881 assert retval.annotation.name == "str"
1882 assert retval.description == ""
1885# =============================================================================================
1886# Warnings
1887def test_disabled_warnings(parse_google: ParserType) -> None:
1888 """Assert warnings are disabled.
1890 Parameters:
1891 parse_google: Fixture parser.
1892 """
1893 docstring = """
1894 Parameters:
1895 x: X value.
1896 """
1897 _, warnings = parse_google(docstring, warnings=True)
1898 assert warnings
1899 _, warnings = parse_google(docstring, warnings=False)
1900 assert not warnings