singlestoredb 1.16.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- singlestoredb/__init__.py +75 -0
- singlestoredb/ai/__init__.py +2 -0
- singlestoredb/ai/chat.py +139 -0
- singlestoredb/ai/embeddings.py +128 -0
- singlestoredb/alchemy/__init__.py +90 -0
- singlestoredb/apps/__init__.py +3 -0
- singlestoredb/apps/_cloud_functions.py +90 -0
- singlestoredb/apps/_config.py +72 -0
- singlestoredb/apps/_connection_info.py +18 -0
- singlestoredb/apps/_dashboards.py +47 -0
- singlestoredb/apps/_process.py +32 -0
- singlestoredb/apps/_python_udfs.py +100 -0
- singlestoredb/apps/_stdout_supress.py +30 -0
- singlestoredb/apps/_uvicorn_util.py +36 -0
- singlestoredb/auth.py +245 -0
- singlestoredb/config.py +484 -0
- singlestoredb/connection.py +1487 -0
- singlestoredb/converters.py +950 -0
- singlestoredb/docstring/__init__.py +33 -0
- singlestoredb/docstring/attrdoc.py +126 -0
- singlestoredb/docstring/common.py +230 -0
- singlestoredb/docstring/epydoc.py +267 -0
- singlestoredb/docstring/google.py +412 -0
- singlestoredb/docstring/numpydoc.py +562 -0
- singlestoredb/docstring/parser.py +100 -0
- singlestoredb/docstring/py.typed +1 -0
- singlestoredb/docstring/rest.py +256 -0
- singlestoredb/docstring/tests/__init__.py +1 -0
- singlestoredb/docstring/tests/_pydoctor.py +21 -0
- singlestoredb/docstring/tests/test_epydoc.py +729 -0
- singlestoredb/docstring/tests/test_google.py +1007 -0
- singlestoredb/docstring/tests/test_numpydoc.py +1100 -0
- singlestoredb/docstring/tests/test_parse_from_object.py +109 -0
- singlestoredb/docstring/tests/test_parser.py +248 -0
- singlestoredb/docstring/tests/test_rest.py +547 -0
- singlestoredb/docstring/tests/test_util.py +70 -0
- singlestoredb/docstring/util.py +141 -0
- singlestoredb/exceptions.py +120 -0
- singlestoredb/functions/__init__.py +16 -0
- singlestoredb/functions/decorator.py +201 -0
- singlestoredb/functions/dtypes.py +1793 -0
- singlestoredb/functions/ext/__init__.py +1 -0
- singlestoredb/functions/ext/arrow.py +375 -0
- singlestoredb/functions/ext/asgi.py +2133 -0
- singlestoredb/functions/ext/json.py +420 -0
- singlestoredb/functions/ext/mmap.py +413 -0
- singlestoredb/functions/ext/rowdat_1.py +724 -0
- singlestoredb/functions/ext/timer.py +89 -0
- singlestoredb/functions/ext/utils.py +218 -0
- singlestoredb/functions/signature.py +1578 -0
- singlestoredb/functions/typing/__init__.py +41 -0
- singlestoredb/functions/typing/numpy.py +20 -0
- singlestoredb/functions/typing/pandas.py +2 -0
- singlestoredb/functions/typing/polars.py +2 -0
- singlestoredb/functions/typing/pyarrow.py +2 -0
- singlestoredb/functions/utils.py +421 -0
- singlestoredb/fusion/__init__.py +11 -0
- singlestoredb/fusion/graphql.py +213 -0
- singlestoredb/fusion/handler.py +916 -0
- singlestoredb/fusion/handlers/__init__.py +0 -0
- singlestoredb/fusion/handlers/export.py +525 -0
- singlestoredb/fusion/handlers/files.py +690 -0
- singlestoredb/fusion/handlers/job.py +660 -0
- singlestoredb/fusion/handlers/models.py +250 -0
- singlestoredb/fusion/handlers/stage.py +502 -0
- singlestoredb/fusion/handlers/utils.py +324 -0
- singlestoredb/fusion/handlers/workspace.py +956 -0
- singlestoredb/fusion/registry.py +249 -0
- singlestoredb/fusion/result.py +399 -0
- singlestoredb/http/__init__.py +27 -0
- singlestoredb/http/connection.py +1267 -0
- singlestoredb/magics/__init__.py +34 -0
- singlestoredb/magics/run_personal.py +137 -0
- singlestoredb/magics/run_shared.py +134 -0
- singlestoredb/management/__init__.py +9 -0
- singlestoredb/management/billing_usage.py +148 -0
- singlestoredb/management/cluster.py +462 -0
- singlestoredb/management/export.py +295 -0
- singlestoredb/management/files.py +1102 -0
- singlestoredb/management/inference_api.py +105 -0
- singlestoredb/management/job.py +887 -0
- singlestoredb/management/manager.py +373 -0
- singlestoredb/management/organization.py +226 -0
- singlestoredb/management/region.py +169 -0
- singlestoredb/management/utils.py +423 -0
- singlestoredb/management/workspace.py +1927 -0
- singlestoredb/mysql/__init__.py +177 -0
- singlestoredb/mysql/_auth.py +298 -0
- singlestoredb/mysql/charset.py +214 -0
- singlestoredb/mysql/connection.py +2032 -0
- singlestoredb/mysql/constants/CLIENT.py +38 -0
- singlestoredb/mysql/constants/COMMAND.py +32 -0
- singlestoredb/mysql/constants/CR.py +78 -0
- singlestoredb/mysql/constants/ER.py +474 -0
- singlestoredb/mysql/constants/EXTENDED_TYPE.py +3 -0
- singlestoredb/mysql/constants/FIELD_TYPE.py +48 -0
- singlestoredb/mysql/constants/FLAG.py +15 -0
- singlestoredb/mysql/constants/SERVER_STATUS.py +10 -0
- singlestoredb/mysql/constants/VECTOR_TYPE.py +6 -0
- singlestoredb/mysql/constants/__init__.py +0 -0
- singlestoredb/mysql/converters.py +271 -0
- singlestoredb/mysql/cursors.py +896 -0
- singlestoredb/mysql/err.py +92 -0
- singlestoredb/mysql/optionfile.py +20 -0
- singlestoredb/mysql/protocol.py +450 -0
- singlestoredb/mysql/tests/__init__.py +19 -0
- singlestoredb/mysql/tests/base.py +126 -0
- singlestoredb/mysql/tests/conftest.py +37 -0
- singlestoredb/mysql/tests/test_DictCursor.py +132 -0
- singlestoredb/mysql/tests/test_SSCursor.py +141 -0
- singlestoredb/mysql/tests/test_basic.py +452 -0
- singlestoredb/mysql/tests/test_connection.py +851 -0
- singlestoredb/mysql/tests/test_converters.py +58 -0
- singlestoredb/mysql/tests/test_cursor.py +141 -0
- singlestoredb/mysql/tests/test_err.py +16 -0
- singlestoredb/mysql/tests/test_issues.py +514 -0
- singlestoredb/mysql/tests/test_load_local.py +75 -0
- singlestoredb/mysql/tests/test_nextset.py +88 -0
- singlestoredb/mysql/tests/test_optionfile.py +27 -0
- singlestoredb/mysql/tests/thirdparty/__init__.py +6 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/__init__.py +9 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/capabilities.py +323 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/dbapi20.py +865 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_capabilities.py +110 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_dbapi20.py +224 -0
- singlestoredb/mysql/tests/thirdparty/test_MySQLdb/test_MySQLdb_nonstandard.py +101 -0
- singlestoredb/mysql/times.py +23 -0
- singlestoredb/notebook/__init__.py +16 -0
- singlestoredb/notebook/_objects.py +213 -0
- singlestoredb/notebook/_portal.py +352 -0
- singlestoredb/py.typed +0 -0
- singlestoredb/pytest.py +352 -0
- singlestoredb/server/__init__.py +0 -0
- singlestoredb/server/docker.py +452 -0
- singlestoredb/server/free_tier.py +267 -0
- singlestoredb/tests/__init__.py +0 -0
- singlestoredb/tests/alltypes.sql +307 -0
- singlestoredb/tests/alltypes_no_nulls.sql +208 -0
- singlestoredb/tests/empty.sql +0 -0
- singlestoredb/tests/ext_funcs/__init__.py +702 -0
- singlestoredb/tests/local_infile.csv +3 -0
- singlestoredb/tests/test.ipynb +18 -0
- singlestoredb/tests/test.sql +680 -0
- singlestoredb/tests/test2.ipynb +18 -0
- singlestoredb/tests/test2.sql +1 -0
- singlestoredb/tests/test_basics.py +1332 -0
- singlestoredb/tests/test_config.py +318 -0
- singlestoredb/tests/test_connection.py +3103 -0
- singlestoredb/tests/test_dbapi.py +27 -0
- singlestoredb/tests/test_exceptions.py +45 -0
- singlestoredb/tests/test_ext_func.py +1472 -0
- singlestoredb/tests/test_ext_func_data.py +1101 -0
- singlestoredb/tests/test_fusion.py +1527 -0
- singlestoredb/tests/test_http.py +288 -0
- singlestoredb/tests/test_management.py +1599 -0
- singlestoredb/tests/test_plugin.py +33 -0
- singlestoredb/tests/test_results.py +171 -0
- singlestoredb/tests/test_types.py +132 -0
- singlestoredb/tests/test_udf.py +737 -0
- singlestoredb/tests/test_udf_returns.py +459 -0
- singlestoredb/tests/test_vectorstore.py +51 -0
- singlestoredb/tests/test_xdict.py +333 -0
- singlestoredb/tests/utils.py +141 -0
- singlestoredb/types.py +373 -0
- singlestoredb/utils/__init__.py +0 -0
- singlestoredb/utils/config.py +950 -0
- singlestoredb/utils/convert_rows.py +69 -0
- singlestoredb/utils/debug.py +13 -0
- singlestoredb/utils/dtypes.py +205 -0
- singlestoredb/utils/events.py +65 -0
- singlestoredb/utils/mogrify.py +151 -0
- singlestoredb/utils/results.py +585 -0
- singlestoredb/utils/xdict.py +425 -0
- singlestoredb/vectorstore.py +192 -0
- singlestoredb/warnings.py +5 -0
- singlestoredb-1.16.1.dist-info/METADATA +165 -0
- singlestoredb-1.16.1.dist-info/RECORD +183 -0
- singlestoredb-1.16.1.dist-info/WHEEL +5 -0
- singlestoredb-1.16.1.dist-info/entry_points.txt +2 -0
- singlestoredb-1.16.1.dist-info/licenses/LICENSE +201 -0
- singlestoredb-1.16.1.dist-info/top_level.txt +3 -0
- sqlx/__init__.py +4 -0
- sqlx/magic.py +113 -0
|
@@ -0,0 +1,1100 @@
|
|
|
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
|