Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
singlestore-labs
GitHub Repository: singlestore-labs/singlestoredb-python
Path: blob/main/singlestoredb/docstring/tests/test_numpydoc.py
469 views
1
"""Tests for numpydoc-style docstring routines."""
2
import typing as T
3
4
import pytest
5
6
import singlestoredb.docstring.numpydoc as numpydoc
7
from singlestoredb.docstring.numpydoc import compose
8
from singlestoredb.docstring.numpydoc import parse
9
10
11
@pytest.mark.parametrize(
12
'source, expected',
13
[
14
pytest.param(None, None, id='No __doc__'),
15
('', None),
16
('\n', None),
17
('Short description', 'Short description'),
18
('\nShort description\n', 'Short description'),
19
('\n Short description\n', 'Short description'),
20
],
21
)
22
def test_short_description(
23
source: T.Optional[str], expected: T.Optional[str],
24
) -> None:
25
"""Test parsing short description."""
26
docstring = parse(source)
27
assert docstring.short_description == expected
28
assert docstring.long_description is None
29
assert not docstring.meta
30
31
32
@pytest.mark.parametrize(
33
'source, expected_short_desc, expected_long_desc, expected_blank',
34
[
35
(
36
'Short description\n\nLong description',
37
'Short description',
38
'Long description',
39
True,
40
),
41
(
42
"""
43
Short description
44
45
Long description
46
""",
47
'Short description',
48
'Long description',
49
True,
50
),
51
(
52
"""
53
Short description
54
55
Long description
56
Second line
57
""",
58
'Short description',
59
'Long description\nSecond line',
60
True,
61
),
62
(
63
'Short description\nLong description',
64
'Short description',
65
'Long description',
66
False,
67
),
68
(
69
"""
70
Short description
71
Long description
72
""",
73
'Short description',
74
'Long description',
75
False,
76
),
77
(
78
'\nShort description\nLong description\n',
79
'Short description',
80
'Long description',
81
False,
82
),
83
(
84
"""
85
Short description
86
Long description
87
Second line
88
""",
89
'Short description',
90
'Long description\nSecond line',
91
False,
92
),
93
],
94
)
95
def test_long_description(
96
source: str,
97
expected_short_desc: str,
98
expected_long_desc: str,
99
expected_blank: bool,
100
) -> None:
101
"""Test parsing long description."""
102
docstring = parse(source)
103
assert docstring.short_description == expected_short_desc
104
assert docstring.long_description == expected_long_desc
105
assert docstring.blank_after_short_description == expected_blank
106
assert not docstring.meta
107
108
109
@pytest.mark.parametrize(
110
'source, expected_short_desc, expected_long_desc, '
111
'expected_blank_short_desc, expected_blank_long_desc',
112
[
113
(
114
"""
115
Short description
116
Parameters
117
----------
118
asd
119
""",
120
'Short description',
121
None,
122
False,
123
False,
124
),
125
(
126
"""
127
Short description
128
Long description
129
Parameters
130
----------
131
asd
132
""",
133
'Short description',
134
'Long description',
135
False,
136
False,
137
),
138
(
139
"""
140
Short description
141
First line
142
Second line
143
Parameters
144
----------
145
asd
146
""",
147
'Short description',
148
'First line\n Second line',
149
False,
150
False,
151
),
152
(
153
"""
154
Short description
155
156
First line
157
Second line
158
Parameters
159
----------
160
asd
161
""",
162
'Short description',
163
'First line\n Second line',
164
True,
165
False,
166
),
167
(
168
"""
169
Short description
170
171
First line
172
Second line
173
174
Parameters
175
----------
176
asd
177
""",
178
'Short description',
179
'First line\n Second line',
180
True,
181
True,
182
),
183
(
184
"""
185
Parameters
186
----------
187
asd
188
""",
189
None,
190
None,
191
False,
192
False,
193
),
194
],
195
)
196
def test_meta_newlines(
197
source: str,
198
expected_short_desc: T.Optional[str],
199
expected_long_desc: T.Optional[str],
200
expected_blank_short_desc: bool,
201
expected_blank_long_desc: bool,
202
) -> None:
203
"""Test parsing newlines around description sections."""
204
docstring = parse(source)
205
assert docstring.short_description == expected_short_desc
206
assert docstring.long_description == expected_long_desc
207
assert docstring.blank_after_short_description == expected_blank_short_desc
208
assert docstring.blank_after_long_description == expected_blank_long_desc
209
assert len(docstring.meta) == 1
210
211
212
def test_meta_with_multiline_description() -> None:
213
"""Test parsing multiline meta documentation."""
214
docstring = parse(
215
"""
216
Short description
217
218
Parameters
219
----------
220
spam
221
asd
222
1
223
2
224
3
225
""",
226
)
227
assert docstring.short_description == 'Short description'
228
assert len(docstring.meta) == 1
229
assert docstring.meta[0].args == ['param', 'spam']
230
assert isinstance(docstring.meta[0], numpydoc.DocstringParam)
231
assert docstring.meta[0].arg_name == 'spam'
232
assert docstring.meta[0].description == 'asd\n1\n 2\n3'
233
234
235
@pytest.mark.parametrize(
236
'source, expected_is_optional, expected_type_name, expected_default',
237
[
238
(
239
"""
240
Parameters
241
----------
242
arg1 : int
243
The first arg
244
""",
245
False,
246
'int',
247
None,
248
),
249
(
250
"""
251
Parameters
252
----------
253
arg2 : str
254
The second arg
255
""",
256
False,
257
'str',
258
None,
259
),
260
(
261
"""
262
Parameters
263
----------
264
arg3 : float, optional
265
The third arg. Default is 1.0.
266
""",
267
True,
268
'float',
269
'1.0',
270
),
271
(
272
"""
273
Parameters
274
----------
275
arg4 : Optional[Dict[str, Any]], optional
276
The fourth arg. Defaults to None
277
""",
278
True,
279
'Optional[Dict[str, Any]]',
280
'None',
281
),
282
(
283
"""
284
Parameters
285
----------
286
arg5 : str, optional
287
The fifth arg. Default: DEFAULT_ARGS
288
""",
289
True,
290
'str',
291
'DEFAULT_ARGS',
292
),
293
(
294
"""
295
Parameters
296
----------
297
parameter_without_default : int
298
The parameter_without_default is required.
299
""",
300
False,
301
'int',
302
None,
303
),
304
],
305
)
306
def test_default_args(
307
source: str,
308
expected_is_optional: bool,
309
expected_type_name: T.Optional[str],
310
expected_default: T.Optional[str],
311
) -> None:
312
"""Test parsing default arguments."""
313
docstring = parse(source)
314
assert docstring is not None
315
assert len(docstring.params) == 1
316
317
arg1 = docstring.params[0]
318
assert arg1.is_optional == expected_is_optional
319
assert arg1.type_name == expected_type_name
320
assert arg1.default == expected_default
321
322
323
def test_multiple_meta() -> None:
324
"""Test parsing multiple meta."""
325
docstring = parse(
326
"""
327
Short description
328
329
Parameters
330
----------
331
spam
332
asd
333
1
334
2
335
3
336
337
Raises
338
------
339
bla
340
herp
341
yay
342
derp
343
""",
344
)
345
assert docstring.short_description == 'Short description'
346
assert len(docstring.meta) == 3
347
assert docstring.meta[0].args == ['param', 'spam']
348
assert isinstance(docstring.meta[0], numpydoc.DocstringParam)
349
assert docstring.meta[0].arg_name == 'spam'
350
assert docstring.meta[0].description == 'asd\n1\n 2\n3'
351
assert docstring.meta[1].args == ['raises', 'bla']
352
assert isinstance(docstring.meta[1], numpydoc.DocstringRaises)
353
assert docstring.meta[1].type_name == 'bla'
354
assert docstring.meta[1].description == 'herp'
355
assert docstring.meta[2].args == ['raises', 'yay']
356
assert isinstance(docstring.meta[2], numpydoc.DocstringRaises)
357
assert docstring.meta[2].type_name == 'yay'
358
assert docstring.meta[2].description == 'derp'
359
360
361
def test_params() -> None:
362
"""Test parsing params."""
363
docstring = parse('Short description')
364
assert len(docstring.params) == 0
365
366
docstring = parse(
367
"""
368
Short description
369
370
Parameters
371
----------
372
name
373
description 1
374
priority : int
375
description 2
376
sender : str, optional
377
description 3
378
ratio : Optional[float], optional
379
description 4
380
""",
381
)
382
assert len(docstring.params) == 4
383
assert docstring.params[0].arg_name == 'name'
384
assert docstring.params[0].type_name is None
385
assert docstring.params[0].description == 'description 1'
386
assert not docstring.params[0].is_optional
387
assert docstring.params[1].arg_name == 'priority'
388
assert docstring.params[1].type_name == 'int'
389
assert docstring.params[1].description == 'description 2'
390
assert not docstring.params[1].is_optional
391
assert docstring.params[2].arg_name == 'sender'
392
assert docstring.params[2].type_name == 'str'
393
assert docstring.params[2].description == 'description 3'
394
assert docstring.params[2].is_optional
395
assert docstring.params[3].arg_name == 'ratio'
396
assert docstring.params[3].type_name == 'Optional[float]'
397
assert docstring.params[3].description == 'description 4'
398
assert docstring.params[3].is_optional
399
400
docstring = parse(
401
"""
402
Short description
403
404
Parameters
405
----------
406
name
407
description 1
408
with multi-line text
409
priority : int
410
description 2
411
""",
412
)
413
assert len(docstring.params) == 2
414
assert docstring.params[0].arg_name == 'name'
415
assert docstring.params[0].type_name is None
416
assert docstring.params[0].description == (
417
'description 1\nwith multi-line text'
418
)
419
assert docstring.params[1].arg_name == 'priority'
420
assert docstring.params[1].type_name == 'int'
421
assert docstring.params[1].description == 'description 2'
422
423
424
def test_attributes() -> None:
425
"""Test parsing attributes."""
426
docstring = parse('Short description')
427
assert len(docstring.params) == 0
428
429
docstring = parse(
430
"""
431
Short description
432
433
Attributes
434
----------
435
name
436
description 1
437
priority : int
438
description 2
439
sender : str, optional
440
description 3
441
ratio : Optional[float], optional
442
description 4
443
""",
444
)
445
assert len(docstring.params) == 4
446
assert docstring.params[0].arg_name == 'name'
447
assert docstring.params[0].type_name is None
448
assert docstring.params[0].description == 'description 1'
449
assert not docstring.params[0].is_optional
450
assert docstring.params[1].arg_name == 'priority'
451
assert docstring.params[1].type_name == 'int'
452
assert docstring.params[1].description == 'description 2'
453
assert not docstring.params[1].is_optional
454
assert docstring.params[2].arg_name == 'sender'
455
assert docstring.params[2].type_name == 'str'
456
assert docstring.params[2].description == 'description 3'
457
assert docstring.params[2].is_optional
458
assert docstring.params[3].arg_name == 'ratio'
459
assert docstring.params[3].type_name == 'Optional[float]'
460
assert docstring.params[3].description == 'description 4'
461
assert docstring.params[3].is_optional
462
463
docstring = parse(
464
"""
465
Short description
466
467
Attributes
468
----------
469
name
470
description 1
471
with multi-line text
472
priority : int
473
description 2
474
""",
475
)
476
assert len(docstring.params) == 2
477
assert docstring.params[0].arg_name == 'name'
478
assert docstring.params[0].type_name is None
479
assert docstring.params[0].description == (
480
'description 1\nwith multi-line text'
481
)
482
assert docstring.params[1].arg_name == 'priority'
483
assert docstring.params[1].type_name == 'int'
484
assert docstring.params[1].description == 'description 2'
485
486
487
def test_other_params() -> None:
488
"""Test parsing other parameters."""
489
docstring = parse(
490
"""
491
Short description
492
Other Parameters
493
----------------
494
only_seldom_used_keywords : type, optional
495
Explanation
496
common_parameters_listed_above : type, optional
497
Explanation
498
""",
499
)
500
assert len(docstring.meta) == 2
501
assert docstring.meta[0].args == [
502
'other_param',
503
'only_seldom_used_keywords',
504
]
505
assert isinstance(docstring.meta[0], numpydoc.DocstringParam)
506
assert docstring.meta[0].arg_name == 'only_seldom_used_keywords'
507
assert docstring.meta[0].type_name == 'type'
508
assert docstring.meta[0].is_optional
509
assert docstring.meta[0].description == 'Explanation'
510
511
assert docstring.meta[1].args == [
512
'other_param',
513
'common_parameters_listed_above',
514
]
515
516
517
def test_yields() -> None:
518
"""Test parsing yields."""
519
docstring = parse(
520
"""
521
Short description
522
Yields
523
------
524
int
525
description
526
""",
527
)
528
assert len(docstring.meta) == 1
529
assert isinstance(docstring.meta[0], numpydoc.DocstringReturns)
530
assert docstring.meta[0].args == ['yields']
531
assert docstring.meta[0].type_name == 'int'
532
assert docstring.meta[0].description == 'description'
533
assert docstring.meta[0].return_name is None
534
assert docstring.meta[0].is_generator
535
536
537
def test_returns() -> None:
538
"""Test parsing returns."""
539
docstring = parse(
540
"""
541
Short description
542
""",
543
)
544
assert docstring.returns is None
545
assert docstring.many_returns is not None
546
assert len(docstring.many_returns) == 0
547
548
docstring = parse(
549
"""
550
Short description
551
Returns
552
-------
553
type
554
""",
555
)
556
assert docstring.returns is not None
557
assert docstring.returns.type_name == 'type'
558
assert docstring.returns.description is None
559
assert docstring.many_returns is not None
560
assert len(docstring.many_returns) == 1
561
assert docstring.many_returns[0] == docstring.returns
562
563
docstring = parse(
564
"""
565
Short description
566
Returns
567
-------
568
int
569
description
570
""",
571
)
572
assert docstring.returns is not None
573
assert docstring.returns.type_name == 'int'
574
assert docstring.returns.description == 'description'
575
assert docstring.many_returns is not None
576
assert len(docstring.many_returns) == 1
577
assert docstring.many_returns[0] == docstring.returns
578
579
docstring = parse(
580
"""
581
Returns
582
-------
583
Optional[Mapping[str, List[int]]]
584
A description: with a colon
585
""",
586
)
587
assert docstring.returns is not None
588
assert docstring.returns.type_name == 'Optional[Mapping[str, List[int]]]'
589
assert docstring.returns.description == 'A description: with a colon'
590
assert docstring.many_returns is not None
591
assert len(docstring.many_returns) == 1
592
assert docstring.many_returns[0] == docstring.returns
593
594
docstring = parse(
595
"""
596
Short description
597
Returns
598
-------
599
int
600
description
601
with much text
602
603
even some spacing
604
""",
605
)
606
assert docstring.returns is not None
607
assert docstring.returns.type_name == 'int'
608
assert docstring.returns.description == (
609
'description\nwith much text\n\neven some spacing'
610
)
611
assert docstring.many_returns is not None
612
assert len(docstring.many_returns) == 1
613
assert docstring.many_returns[0] == docstring.returns
614
615
docstring = parse(
616
"""
617
Short description
618
Returns
619
-------
620
a : int
621
description for a
622
b : str
623
description for b
624
""",
625
)
626
assert docstring.returns is not None
627
assert docstring.returns.type_name == 'int'
628
assert docstring.returns.description == ('description for a')
629
assert docstring.many_returns is not None
630
assert len(docstring.many_returns) == 2
631
assert docstring.many_returns[0].type_name == 'int'
632
assert docstring.many_returns[0].description == 'description for a'
633
assert docstring.many_returns[0].return_name == 'a'
634
assert docstring.many_returns[1].type_name == 'str'
635
assert docstring.many_returns[1].description == 'description for b'
636
assert docstring.many_returns[1].return_name == 'b'
637
638
639
def test_raises() -> None:
640
"""Test parsing raises."""
641
docstring = parse(
642
"""
643
Short description
644
""",
645
)
646
assert len(docstring.raises) == 0
647
648
docstring = parse(
649
"""
650
Short description
651
Raises
652
------
653
ValueError
654
description
655
""",
656
)
657
assert len(docstring.raises) == 1
658
assert docstring.raises[0].type_name == 'ValueError'
659
assert docstring.raises[0].description == 'description'
660
661
662
def test_warns() -> None:
663
"""Test parsing warns."""
664
docstring = parse(
665
"""
666
Short description
667
Warns
668
-----
669
UserWarning
670
description
671
""",
672
)
673
assert len(docstring.meta) == 1
674
assert isinstance(docstring.meta[0], numpydoc.DocstringRaises)
675
assert docstring.meta[0].type_name == 'UserWarning'
676
assert docstring.meta[0].description == 'description'
677
678
679
def test_simple_sections() -> None:
680
"""Test parsing simple sections."""
681
docstring = parse(
682
"""
683
Short description
684
685
See Also
686
--------
687
something : some thing you can also see
688
actually, anything can go in this section
689
690
Warnings
691
--------
692
Here be dragons
693
694
Notes
695
-----
696
None of this is real
697
698
References
699
----------
700
Cite the relevant literature, e.g. [1]_. You may also cite these
701
references in the notes section above.
702
703
.. [1] O. McNoleg, "The integration of GIS, remote sensing,
704
expert systems and adaptive co-kriging for environmental habitat
705
modelling of the Highland Haggis using object-oriented, fuzzy-logic
706
and neural-network techniques," Computers & Geosciences, vol. 22,
707
pp. 585-588, 1996.
708
""",
709
)
710
assert len(docstring.meta) == 4
711
assert docstring.meta[0].args == ['see_also']
712
assert docstring.meta[0].description == (
713
'something : some thing you can also see\n'
714
'actually, anything can go in this section'
715
)
716
717
assert docstring.meta[1].args == ['warnings']
718
assert docstring.meta[1].description == 'Here be dragons'
719
720
assert docstring.meta[2].args == ['notes']
721
assert docstring.meta[2].description == 'None of this is real'
722
723
assert docstring.meta[3].args == ['references']
724
725
726
@pytest.mark.parametrize(
727
'source, expected_results',
728
[
729
(
730
'Description\nExamples\n--------\nlong example\n\nmore here',
731
[
732
(None, 'long example\n\nmore here'),
733
],
734
),
735
(
736
'Description\nExamples\n--------\n>>> test',
737
[
738
('>>> test', ''),
739
],
740
),
741
(
742
'Description\nExamples\n--------\n>>> testa\n>>> testb',
743
[
744
('>>> testa\n>>> testb', ''),
745
],
746
),
747
(
748
'Description\nExamples\n--------\n>>> test1\ndesc1',
749
[
750
('>>> test1\ndesc1', ''),
751
],
752
),
753
(
754
'Description\nExamples\n--------\n'
755
'>>> test1a\n>>> test1b\ndesc1a\ndesc1b',
756
[
757
('>>> test1a\n>>> test1b\ndesc1a\ndesc1b', ''),
758
],
759
),
760
(
761
'Description\nExamples\n--------\n'
762
'>>> test1\ndesc1\n>>> test2\ndesc2',
763
[
764
('>>> test1\ndesc1', ''),
765
('>>> test2\ndesc2', ''),
766
],
767
),
768
(
769
'Description\nExamples\n--------\n'
770
'>>> test1a\n>>> test1b\ndesc1a\ndesc1b\n'
771
'>>> test2a\n>>> test2b\ndesc2a\ndesc2b\n',
772
[
773
('>>> test1a\n>>> test1b\ndesc1a\ndesc1b', ''),
774
('>>> test2a\n>>> test2b\ndesc2a\ndesc2b', ''),
775
],
776
),
777
(
778
'Description\nExamples\n--------\n'
779
' >>> test1a\n >>> test1b\n desc1a\n desc1b\n'
780
' >>> test2a\n >>> test2b\n desc2a\n desc2b\n',
781
[
782
('>>> test1a\n>>> test1b\ndesc1a\ndesc1b', ''),
783
('>>> test2a\n>>> test2b\ndesc2a\ndesc2b', ''),
784
],
785
),
786
],
787
)
788
def test_examples(
789
source: str, expected_results: T.List[T.Tuple[T.Optional[str], str]],
790
) -> None:
791
"""Test parsing examples."""
792
docstring = parse(source)
793
assert len(docstring.meta) == len(expected_results)
794
for meta, expected_result in zip(docstring.meta, expected_results):
795
assert meta.description == expected_result[1]
796
assert len(docstring.examples) == len(expected_results)
797
for example, expected_result in zip(docstring.examples, expected_results):
798
assert example.snippet == expected_result[0]
799
assert example.description == expected_result[1]
800
801
802
@pytest.mark.parametrize(
803
'source, expected_depr_version, expected_depr_desc',
804
[
805
(
806
'Short description\n\n.. deprecated:: 1.6.0\n This is busted!',
807
'1.6.0',
808
'This is busted!',
809
),
810
(
811
(
812
'Short description\n\n'
813
'.. deprecated:: 1.6.0\n'
814
' This description has\n'
815
' multiple lines!'
816
),
817
'1.6.0',
818
'This description has\nmultiple lines!',
819
),
820
('Short description\n\n.. deprecated:: 1.6.0', '1.6.0', None),
821
(
822
'Short description\n\n.. deprecated::\n No version!',
823
None,
824
'No version!',
825
),
826
],
827
)
828
def test_deprecation(
829
source: str,
830
expected_depr_version: T.Optional[str],
831
expected_depr_desc: T.Optional[str],
832
) -> None:
833
"""Test parsing deprecation notes."""
834
docstring = parse(source)
835
836
assert docstring.deprecation is not None
837
assert docstring.deprecation.version == expected_depr_version
838
assert docstring.deprecation.description == expected_depr_desc
839
840
841
@pytest.mark.parametrize(
842
'source, expected',
843
[
844
('', ''),
845
('\n', ''),
846
('Short description', 'Short description'),
847
('\nShort description\n', 'Short description'),
848
('\n Short description\n', 'Short description'),
849
(
850
'Short description\n\nLong description',
851
'Short description\n\nLong description',
852
),
853
(
854
"""
855
Short description
856
857
Long description
858
""",
859
'Short description\n\nLong description',
860
),
861
(
862
"""
863
Short description
864
865
Long description
866
Second line
867
""",
868
'Short description\n\nLong description\nSecond line',
869
),
870
(
871
'Short description\nLong description',
872
'Short description\nLong description',
873
),
874
(
875
"""
876
Short description
877
Long description
878
""",
879
'Short description\nLong description',
880
),
881
(
882
'\nShort description\nLong description\n',
883
'Short description\nLong description',
884
),
885
(
886
"""
887
Short description
888
Long description
889
Second line
890
""",
891
'Short description\nLong description\nSecond line',
892
),
893
(
894
"""
895
Short description
896
Meta:
897
-----
898
asd
899
""",
900
'Short description\nMeta:\n-----\n asd',
901
),
902
(
903
"""
904
Short description
905
Long description
906
Meta:
907
-----
908
asd
909
""",
910
'Short description\n'
911
'Long description\n'
912
'Meta:\n'
913
'-----\n'
914
' asd',
915
),
916
(
917
"""
918
Short description
919
First line
920
Second line
921
Meta:
922
-----
923
asd
924
""",
925
'Short description\n'
926
'First line\n'
927
' Second line\n'
928
'Meta:\n'
929
'-----\n'
930
' asd',
931
),
932
(
933
"""
934
Short description
935
936
First line
937
Second line
938
Meta:
939
-----
940
asd
941
""",
942
'Short description\n'
943
'\n'
944
'First line\n'
945
' Second line\n'
946
'Meta:\n'
947
'-----\n'
948
' asd',
949
),
950
(
951
"""
952
Short description
953
954
First line
955
Second line
956
957
Meta:
958
-----
959
asd
960
""",
961
'Short description\n'
962
'\n'
963
'First line\n'
964
' Second line\n'
965
'\n'
966
'Meta:\n'
967
'-----\n'
968
' asd',
969
),
970
(
971
"""
972
Short description
973
974
Meta:
975
-----
976
asd
977
1
978
2
979
3
980
""",
981
'Short description\n'
982
'\n'
983
'Meta:\n'
984
'-----\n'
985
' asd\n'
986
' 1\n'
987
' 2\n'
988
' 3',
989
),
990
(
991
"""
992
Short description
993
994
Meta1:
995
------
996
asd
997
1
998
2
999
3
1000
Meta2:
1001
------
1002
herp
1003
Meta3:
1004
------
1005
derp
1006
""",
1007
'Short description\n'
1008
'\n'
1009
'Meta1:\n'
1010
'------\n'
1011
' asd\n'
1012
' 1\n'
1013
' 2\n'
1014
' 3\n'
1015
'Meta2:\n'
1016
'------\n'
1017
' herp\n'
1018
'Meta3:\n'
1019
'------\n'
1020
' derp',
1021
),
1022
(
1023
"""
1024
Short description
1025
1026
Parameters:
1027
-----------
1028
name
1029
description 1
1030
priority: int
1031
description 2
1032
sender: str, optional
1033
description 3
1034
message: str, optional
1035
description 4, defaults to 'hello'
1036
multiline: str, optional
1037
long description 5,
1038
defaults to 'bye'
1039
""",
1040
'Short description\n'
1041
'\n'
1042
'Parameters:\n'
1043
'-----------\n'
1044
' name\n'
1045
' description 1\n'
1046
' priority: int\n'
1047
' description 2\n'
1048
' sender: str, optional\n'
1049
' description 3\n'
1050
' message: str, optional\n'
1051
" description 4, defaults to 'hello'\n"
1052
' multiline: str, optional\n'
1053
' long description 5,\n'
1054
" defaults to 'bye'",
1055
),
1056
(
1057
"""
1058
Short description
1059
Raises:
1060
-------
1061
ValueError
1062
description
1063
""",
1064
'Short description\n'
1065
'Raises:\n'
1066
'-------\n'
1067
' ValueError\n'
1068
' description',
1069
),
1070
(
1071
"""
1072
Description
1073
Examples:
1074
--------
1075
>>> test1a
1076
>>> test1b
1077
desc1a
1078
desc1b
1079
>>> test2a
1080
>>> test2b
1081
desc2a
1082
desc2b
1083
""",
1084
'Description\n'
1085
'Examples:\n'
1086
'--------\n'
1087
'>>> test1a\n'
1088
'>>> test1b\n'
1089
'desc1a\n'
1090
'desc1b\n'
1091
'>>> test2a\n'
1092
'>>> test2b\n'
1093
'desc2a\n'
1094
'desc2b',
1095
),
1096
],
1097
)
1098
def test_compose(source: str, expected: str) -> None:
1099
"""Test compose in default mode."""
1100
assert compose(parse(source)) == expected
1101
1102