Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
singlestore-labs
GitHub Repository: singlestore-labs/singlestoredb-python
Path: blob/main/singlestoredb/docstring/tests/test_parser.py
469 views
1
"""Tests for generic docstring routines."""
2
import typing as T
3
4
import pytest
5
6
from singlestoredb.docstring.common import DocstringStyle
7
from singlestoredb.docstring.common import ParseError
8
from singlestoredb.docstring.parser 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.description == expected
29
assert docstring.long_description is None
30
assert not docstring.meta
31
32
33
def test_rest() -> None:
34
"""Test ReST-style parser autodetection."""
35
docstring = parse(
36
"""
37
Short description
38
39
Long description
40
41
Causing people to indent:
42
43
A lot sometimes
44
45
:param spam: spam desc
46
:param int bla: bla desc
47
:param str yay:
48
:raises ValueError: exc desc
49
:returns tuple: ret desc
50
""",
51
)
52
53
assert docstring.style == DocstringStyle.REST
54
assert docstring.short_description == 'Short description'
55
assert docstring.long_description == (
56
'Long description\n\n'
57
'Causing people to indent:\n\n'
58
' A lot sometimes'
59
)
60
assert docstring.description == (
61
'Short description\n\n'
62
'Long description\n\n'
63
'Causing people to indent:\n\n'
64
' A lot sometimes'
65
)
66
assert len(docstring.params) == 3
67
assert docstring.params[0].arg_name == 'spam'
68
assert docstring.params[0].type_name is None
69
assert docstring.params[0].description == 'spam desc'
70
assert docstring.params[1].arg_name == 'bla'
71
assert docstring.params[1].type_name == 'int'
72
assert docstring.params[1].description == 'bla desc'
73
assert docstring.params[2].arg_name == 'yay'
74
assert docstring.params[2].type_name == 'str'
75
assert docstring.params[2].description == ''
76
assert len(docstring.raises) == 1
77
assert docstring.raises[0].type_name == 'ValueError'
78
assert docstring.raises[0].description == 'exc desc'
79
assert docstring.returns is not None
80
assert docstring.returns.type_name == 'tuple'
81
assert docstring.returns.description == 'ret desc'
82
assert docstring.many_returns is not None
83
assert len(docstring.many_returns) == 1
84
assert docstring.many_returns[0] == docstring.returns
85
86
87
def test_google() -> None:
88
"""Test Google-style parser autodetection."""
89
docstring = parse(
90
"""Short description
91
92
Long description
93
94
Causing people to indent:
95
96
A lot sometimes
97
98
Args:
99
spam: spam desc
100
bla (int): bla desc
101
yay (str):
102
103
Raises:
104
ValueError: exc desc
105
106
Returns:
107
tuple: ret desc
108
""",
109
)
110
111
assert docstring.style == DocstringStyle.GOOGLE
112
assert docstring.short_description == 'Short description'
113
assert docstring.long_description == (
114
'Long description\n\n'
115
'Causing people to indent:\n\n'
116
' A lot sometimes'
117
)
118
assert docstring.description == (
119
'Short description\n\n'
120
'Long description\n\n'
121
'Causing people to indent:\n\n'
122
' A lot sometimes'
123
)
124
assert len(docstring.params) == 3
125
assert docstring.params[0].arg_name == 'spam'
126
assert docstring.params[0].type_name is None
127
assert docstring.params[0].description == 'spam desc'
128
assert docstring.params[1].arg_name == 'bla'
129
assert docstring.params[1].type_name == 'int'
130
assert docstring.params[1].description == 'bla desc'
131
assert docstring.params[2].arg_name == 'yay'
132
assert docstring.params[2].type_name == 'str'
133
assert docstring.params[2].description == ''
134
assert len(docstring.raises) == 1
135
assert docstring.raises[0].type_name == 'ValueError'
136
assert docstring.raises[0].description == 'exc desc'
137
assert docstring.returns is not None
138
assert docstring.returns.type_name == 'tuple'
139
assert docstring.returns.description == 'ret desc'
140
assert docstring.many_returns is not None
141
assert len(docstring.many_returns) == 1
142
assert docstring.many_returns[0] == docstring.returns
143
144
145
def test_numpydoc() -> None:
146
"""Test numpydoc-style parser autodetection."""
147
docstring = parse(
148
"""Short description
149
150
Long description
151
152
Causing people to indent:
153
154
A lot sometimes
155
156
Parameters
157
----------
158
spam
159
spam desc
160
bla : int
161
bla desc
162
yay : str
163
164
Raises
165
------
166
ValueError
167
exc desc
168
169
Other Parameters
170
----------------
171
this_guy : int, optional
172
you know him
173
174
Returns
175
-------
176
tuple
177
ret desc
178
179
See Also
180
--------
181
multiple lines...
182
something else?
183
184
Warnings
185
--------
186
multiple lines...
187
none of this is real!
188
""",
189
)
190
191
assert docstring.style == DocstringStyle.NUMPYDOC
192
assert docstring.short_description == 'Short description'
193
assert docstring.long_description == (
194
'Long description\n\n'
195
'Causing people to indent:\n\n'
196
' A lot sometimes'
197
)
198
assert docstring.description == (
199
'Short description\n\n'
200
'Long description\n\n'
201
'Causing people to indent:\n\n'
202
' A lot sometimes'
203
)
204
assert len(docstring.params) == 4
205
assert docstring.params[0].arg_name == 'spam'
206
assert docstring.params[0].type_name is None
207
assert docstring.params[0].description == 'spam desc'
208
assert docstring.params[1].arg_name == 'bla'
209
assert docstring.params[1].type_name == 'int'
210
assert docstring.params[1].description == 'bla desc'
211
assert docstring.params[2].arg_name == 'yay'
212
assert docstring.params[2].type_name == 'str'
213
assert docstring.params[2].description is None
214
assert docstring.params[3].arg_name == 'this_guy'
215
assert docstring.params[3].type_name == 'int'
216
assert docstring.params[3].is_optional
217
assert docstring.params[3].description == 'you know him'
218
219
assert len(docstring.raises) == 1
220
assert docstring.raises[0].type_name == 'ValueError'
221
assert docstring.raises[0].description == 'exc desc'
222
assert docstring.returns is not None
223
assert docstring.returns.type_name == 'tuple'
224
assert docstring.returns.description == 'ret desc'
225
assert docstring.many_returns is not None
226
assert len(docstring.many_returns) == 1
227
assert docstring.many_returns[0] == docstring.returns
228
229
230
def test_autodetection_error_detection() -> None:
231
"""Test autodection for the case where one of the parsers throws an error
232
and another one succeeds.
233
"""
234
source = """
235
Does something useless
236
237
:param 3 + 3 a: a param
238
"""
239
240
with pytest.raises(ParseError):
241
# assert that one of the parsers does raise
242
parse(source, DocstringStyle.REST)
243
244
# assert that autodetection still works
245
docstring = parse(source)
246
247
assert docstring
248
assert docstring.style == DocstringStyle.GOOGLE
249
250