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,547 @@
|
|
|
1
|
+
"""Tests for ReST-style docstring routines."""
|
|
2
|
+
import typing as T
|
|
3
|
+
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from singlestoredb.docstring.common import ParseError
|
|
7
|
+
from singlestoredb.docstring.common import RenderingStyle
|
|
8
|
+
from singlestoredb.docstring.rest import compose
|
|
9
|
+
from singlestoredb.docstring.rest import parse
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@pytest.mark.parametrize(
|
|
13
|
+
'source, expected',
|
|
14
|
+
[
|
|
15
|
+
pytest.param(None, None, id='No __doc__'),
|
|
16
|
+
('', None),
|
|
17
|
+
('\n', None),
|
|
18
|
+
('Short description', 'Short description'),
|
|
19
|
+
('\nShort description\n', 'Short description'),
|
|
20
|
+
('\n Short description\n', 'Short description'),
|
|
21
|
+
],
|
|
22
|
+
)
|
|
23
|
+
def test_short_description(
|
|
24
|
+
source: T.Optional[str], expected: T.Optional[str],
|
|
25
|
+
) -> None:
|
|
26
|
+
"""Test parsing short description."""
|
|
27
|
+
docstring = parse(source)
|
|
28
|
+
assert docstring.short_description == expected
|
|
29
|
+
assert docstring.description == expected
|
|
30
|
+
assert docstring.long_description is None
|
|
31
|
+
assert not docstring.meta
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@pytest.mark.parametrize(
|
|
35
|
+
'source, expected_short_desc, expected_long_desc, expected_blank',
|
|
36
|
+
[
|
|
37
|
+
(
|
|
38
|
+
'Short description\n\nLong description',
|
|
39
|
+
'Short description',
|
|
40
|
+
'Long description',
|
|
41
|
+
True,
|
|
42
|
+
),
|
|
43
|
+
(
|
|
44
|
+
"""
|
|
45
|
+
Short description
|
|
46
|
+
|
|
47
|
+
Long description
|
|
48
|
+
""",
|
|
49
|
+
'Short description',
|
|
50
|
+
'Long description',
|
|
51
|
+
True,
|
|
52
|
+
),
|
|
53
|
+
(
|
|
54
|
+
"""
|
|
55
|
+
Short description
|
|
56
|
+
|
|
57
|
+
Long description
|
|
58
|
+
Second line
|
|
59
|
+
""",
|
|
60
|
+
'Short description',
|
|
61
|
+
'Long description\nSecond line',
|
|
62
|
+
True,
|
|
63
|
+
),
|
|
64
|
+
(
|
|
65
|
+
'Short description\nLong description',
|
|
66
|
+
'Short description',
|
|
67
|
+
'Long description',
|
|
68
|
+
False,
|
|
69
|
+
),
|
|
70
|
+
(
|
|
71
|
+
"""
|
|
72
|
+
Short description
|
|
73
|
+
Long description
|
|
74
|
+
""",
|
|
75
|
+
'Short description',
|
|
76
|
+
'Long description',
|
|
77
|
+
False,
|
|
78
|
+
),
|
|
79
|
+
(
|
|
80
|
+
'\nShort description\nLong description\n',
|
|
81
|
+
'Short description',
|
|
82
|
+
'Long description',
|
|
83
|
+
False,
|
|
84
|
+
),
|
|
85
|
+
(
|
|
86
|
+
"""
|
|
87
|
+
Short description
|
|
88
|
+
Long description
|
|
89
|
+
Second line
|
|
90
|
+
""",
|
|
91
|
+
'Short description',
|
|
92
|
+
'Long description\nSecond line',
|
|
93
|
+
False,
|
|
94
|
+
),
|
|
95
|
+
],
|
|
96
|
+
)
|
|
97
|
+
def test_long_description(
|
|
98
|
+
source: str,
|
|
99
|
+
expected_short_desc: str,
|
|
100
|
+
expected_long_desc: str,
|
|
101
|
+
expected_blank: bool,
|
|
102
|
+
) -> None:
|
|
103
|
+
"""Test parsing long description."""
|
|
104
|
+
docstring = parse(source)
|
|
105
|
+
assert docstring.short_description == expected_short_desc
|
|
106
|
+
assert docstring.long_description == expected_long_desc
|
|
107
|
+
assert docstring.blank_after_short_description == expected_blank
|
|
108
|
+
assert not docstring.meta
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@pytest.mark.parametrize(
|
|
112
|
+
'source, expected_short_desc, expected_long_desc, '
|
|
113
|
+
'expected_blank_short_desc, expected_blank_long_desc, '
|
|
114
|
+
'expected_full_desc',
|
|
115
|
+
[
|
|
116
|
+
(
|
|
117
|
+
"""
|
|
118
|
+
Short description
|
|
119
|
+
:meta: asd
|
|
120
|
+
""",
|
|
121
|
+
'Short description',
|
|
122
|
+
None,
|
|
123
|
+
False,
|
|
124
|
+
False,
|
|
125
|
+
'Short description',
|
|
126
|
+
),
|
|
127
|
+
(
|
|
128
|
+
"""
|
|
129
|
+
Short description
|
|
130
|
+
Long description
|
|
131
|
+
:meta: asd
|
|
132
|
+
""",
|
|
133
|
+
'Short description',
|
|
134
|
+
'Long description',
|
|
135
|
+
False,
|
|
136
|
+
False,
|
|
137
|
+
'Short description\nLong description',
|
|
138
|
+
),
|
|
139
|
+
(
|
|
140
|
+
"""
|
|
141
|
+
Short description
|
|
142
|
+
First line
|
|
143
|
+
Second line
|
|
144
|
+
:meta: asd
|
|
145
|
+
""",
|
|
146
|
+
'Short description',
|
|
147
|
+
'First line\n Second line',
|
|
148
|
+
False,
|
|
149
|
+
False,
|
|
150
|
+
'Short description\nFirst line\n Second line',
|
|
151
|
+
),
|
|
152
|
+
(
|
|
153
|
+
"""
|
|
154
|
+
Short description
|
|
155
|
+
|
|
156
|
+
First line
|
|
157
|
+
Second line
|
|
158
|
+
:meta: asd
|
|
159
|
+
""",
|
|
160
|
+
'Short description',
|
|
161
|
+
'First line\n Second line',
|
|
162
|
+
True,
|
|
163
|
+
False,
|
|
164
|
+
'Short description\n\nFirst line\n Second line',
|
|
165
|
+
),
|
|
166
|
+
(
|
|
167
|
+
"""
|
|
168
|
+
Short description
|
|
169
|
+
|
|
170
|
+
First line
|
|
171
|
+
Second line
|
|
172
|
+
|
|
173
|
+
:meta: asd
|
|
174
|
+
""",
|
|
175
|
+
'Short description',
|
|
176
|
+
'First line\n Second line',
|
|
177
|
+
True,
|
|
178
|
+
True,
|
|
179
|
+
'Short description\n\nFirst line\n Second line',
|
|
180
|
+
),
|
|
181
|
+
(
|
|
182
|
+
"""
|
|
183
|
+
:meta: asd
|
|
184
|
+
""",
|
|
185
|
+
None,
|
|
186
|
+
None,
|
|
187
|
+
False,
|
|
188
|
+
False,
|
|
189
|
+
None,
|
|
190
|
+
),
|
|
191
|
+
],
|
|
192
|
+
)
|
|
193
|
+
def test_meta_newlines(
|
|
194
|
+
source: str,
|
|
195
|
+
expected_short_desc: T.Optional[str],
|
|
196
|
+
expected_long_desc: T.Optional[str],
|
|
197
|
+
expected_blank_short_desc: bool,
|
|
198
|
+
expected_blank_long_desc: bool,
|
|
199
|
+
expected_full_desc: T.Optional[str],
|
|
200
|
+
) -> None:
|
|
201
|
+
"""Test parsing newlines around description sections."""
|
|
202
|
+
docstring = parse(source)
|
|
203
|
+
assert docstring.short_description == expected_short_desc
|
|
204
|
+
assert docstring.long_description == expected_long_desc
|
|
205
|
+
assert docstring.blank_after_short_description == expected_blank_short_desc
|
|
206
|
+
assert docstring.blank_after_long_description == expected_blank_long_desc
|
|
207
|
+
assert docstring.description == expected_full_desc
|
|
208
|
+
assert len(docstring.meta) == 1
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def test_meta_with_multiline_description() -> None:
|
|
212
|
+
"""Test parsing multiline meta documentation."""
|
|
213
|
+
docstring = parse(
|
|
214
|
+
"""
|
|
215
|
+
Short description
|
|
216
|
+
|
|
217
|
+
:meta: asd
|
|
218
|
+
1
|
|
219
|
+
2
|
|
220
|
+
3
|
|
221
|
+
""",
|
|
222
|
+
)
|
|
223
|
+
assert docstring.short_description == 'Short description'
|
|
224
|
+
assert len(docstring.meta) == 1
|
|
225
|
+
assert docstring.meta[0].args == ['meta']
|
|
226
|
+
assert docstring.meta[0].description == 'asd\n1\n 2\n3'
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def test_multiple_meta() -> None:
|
|
230
|
+
"""Test parsing multiple meta."""
|
|
231
|
+
docstring = parse(
|
|
232
|
+
"""
|
|
233
|
+
Short description
|
|
234
|
+
|
|
235
|
+
:meta1: asd
|
|
236
|
+
1
|
|
237
|
+
2
|
|
238
|
+
3
|
|
239
|
+
:meta2: herp
|
|
240
|
+
:meta3: derp
|
|
241
|
+
""",
|
|
242
|
+
)
|
|
243
|
+
assert docstring.short_description == 'Short description'
|
|
244
|
+
assert len(docstring.meta) == 3
|
|
245
|
+
assert docstring.meta[0].args == ['meta1']
|
|
246
|
+
assert docstring.meta[0].description == 'asd\n1\n 2\n3'
|
|
247
|
+
assert docstring.meta[1].args == ['meta2']
|
|
248
|
+
assert docstring.meta[1].description == 'herp'
|
|
249
|
+
assert docstring.meta[2].args == ['meta3']
|
|
250
|
+
assert docstring.meta[2].description == 'derp'
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
def test_meta_with_args() -> None:
|
|
254
|
+
"""Test parsing meta with additional arguments."""
|
|
255
|
+
docstring = parse(
|
|
256
|
+
"""
|
|
257
|
+
Short description
|
|
258
|
+
|
|
259
|
+
:meta ene due rabe: asd
|
|
260
|
+
""",
|
|
261
|
+
)
|
|
262
|
+
assert docstring.short_description == 'Short description'
|
|
263
|
+
assert len(docstring.meta) == 1
|
|
264
|
+
assert docstring.meta[0].args == ['meta', 'ene', 'due', 'rabe']
|
|
265
|
+
assert docstring.meta[0].description == 'asd'
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def test_params() -> None:
|
|
269
|
+
"""Test parsing params."""
|
|
270
|
+
docstring = parse('Short description')
|
|
271
|
+
assert len(docstring.params) == 0
|
|
272
|
+
|
|
273
|
+
docstring = parse(
|
|
274
|
+
"""
|
|
275
|
+
Short description
|
|
276
|
+
|
|
277
|
+
:param name: description 1
|
|
278
|
+
:param int priority: description 2
|
|
279
|
+
:param str? sender: description 3
|
|
280
|
+
:param str? message: description 4, defaults to 'hello'
|
|
281
|
+
:param str? multiline: long description 5,
|
|
282
|
+
defaults to 'bye'
|
|
283
|
+
""",
|
|
284
|
+
)
|
|
285
|
+
assert len(docstring.params) == 5
|
|
286
|
+
assert docstring.params[0].arg_name == 'name'
|
|
287
|
+
assert docstring.params[0].type_name is None
|
|
288
|
+
assert docstring.params[0].description == 'description 1'
|
|
289
|
+
assert docstring.params[0].default is None
|
|
290
|
+
assert not docstring.params[0].is_optional
|
|
291
|
+
assert docstring.params[1].arg_name == 'priority'
|
|
292
|
+
assert docstring.params[1].type_name == 'int'
|
|
293
|
+
assert docstring.params[1].description == 'description 2'
|
|
294
|
+
assert not docstring.params[1].is_optional
|
|
295
|
+
assert docstring.params[1].default is None
|
|
296
|
+
assert docstring.params[2].arg_name == 'sender'
|
|
297
|
+
assert docstring.params[2].type_name == 'str'
|
|
298
|
+
assert docstring.params[2].description == 'description 3'
|
|
299
|
+
assert docstring.params[2].is_optional
|
|
300
|
+
assert docstring.params[2].default is None
|
|
301
|
+
assert docstring.params[3].arg_name == 'message'
|
|
302
|
+
assert docstring.params[3].type_name == 'str'
|
|
303
|
+
assert (
|
|
304
|
+
docstring.params[3].description == "description 4, defaults to 'hello'"
|
|
305
|
+
)
|
|
306
|
+
assert docstring.params[3].is_optional
|
|
307
|
+
assert docstring.params[3].default == "'hello'"
|
|
308
|
+
assert docstring.params[4].arg_name == 'multiline'
|
|
309
|
+
assert docstring.params[4].type_name == 'str'
|
|
310
|
+
assert (
|
|
311
|
+
docstring.params[4].description
|
|
312
|
+
== "long description 5,\ndefaults to 'bye'"
|
|
313
|
+
)
|
|
314
|
+
assert docstring.params[4].is_optional
|
|
315
|
+
assert docstring.params[4].default == "'bye'"
|
|
316
|
+
|
|
317
|
+
docstring = parse(
|
|
318
|
+
"""
|
|
319
|
+
Short description
|
|
320
|
+
|
|
321
|
+
:param a: description a
|
|
322
|
+
:type a: int
|
|
323
|
+
:param int b: description b
|
|
324
|
+
""",
|
|
325
|
+
)
|
|
326
|
+
assert len(docstring.params) == 2
|
|
327
|
+
assert docstring.params[0].arg_name == 'a'
|
|
328
|
+
assert docstring.params[0].type_name == 'int'
|
|
329
|
+
assert docstring.params[0].description == 'description a'
|
|
330
|
+
assert docstring.params[0].default is None
|
|
331
|
+
assert not docstring.params[0].is_optional
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def test_returns() -> None:
|
|
335
|
+
"""Test parsing returns."""
|
|
336
|
+
docstring = parse(
|
|
337
|
+
"""
|
|
338
|
+
Short description
|
|
339
|
+
""",
|
|
340
|
+
)
|
|
341
|
+
assert docstring.returns is None
|
|
342
|
+
assert docstring.many_returns is not None
|
|
343
|
+
assert len(docstring.many_returns) == 0
|
|
344
|
+
|
|
345
|
+
docstring = parse(
|
|
346
|
+
"""
|
|
347
|
+
Short description
|
|
348
|
+
:returns: description
|
|
349
|
+
""",
|
|
350
|
+
)
|
|
351
|
+
assert docstring.returns is not None
|
|
352
|
+
assert docstring.returns.type_name is None
|
|
353
|
+
assert docstring.returns.description == 'description'
|
|
354
|
+
assert not docstring.returns.is_generator
|
|
355
|
+
assert docstring.many_returns == [docstring.returns]
|
|
356
|
+
|
|
357
|
+
docstring = parse(
|
|
358
|
+
"""
|
|
359
|
+
Short description
|
|
360
|
+
:returns int: description
|
|
361
|
+
""",
|
|
362
|
+
)
|
|
363
|
+
assert docstring.returns is not None
|
|
364
|
+
assert docstring.returns.type_name == 'int'
|
|
365
|
+
assert docstring.returns.description == 'description'
|
|
366
|
+
assert not docstring.returns.is_generator
|
|
367
|
+
assert docstring.many_returns == [docstring.returns]
|
|
368
|
+
|
|
369
|
+
docstring = parse(
|
|
370
|
+
"""
|
|
371
|
+
Short description
|
|
372
|
+
:returns: description
|
|
373
|
+
:rtype: int
|
|
374
|
+
""",
|
|
375
|
+
)
|
|
376
|
+
assert docstring.returns is not None
|
|
377
|
+
assert docstring.returns.type_name == 'int'
|
|
378
|
+
assert docstring.returns.description == 'description'
|
|
379
|
+
assert not docstring.returns.is_generator
|
|
380
|
+
assert docstring.many_returns == [docstring.returns]
|
|
381
|
+
|
|
382
|
+
|
|
383
|
+
def test_yields() -> None:
|
|
384
|
+
"""Test parsing yields."""
|
|
385
|
+
docstring = parse(
|
|
386
|
+
"""
|
|
387
|
+
Short description
|
|
388
|
+
""",
|
|
389
|
+
)
|
|
390
|
+
assert docstring.returns is None
|
|
391
|
+
assert docstring.many_returns is not None
|
|
392
|
+
assert len(docstring.many_returns) == 0
|
|
393
|
+
|
|
394
|
+
docstring = parse(
|
|
395
|
+
"""
|
|
396
|
+
Short description
|
|
397
|
+
:yields: description
|
|
398
|
+
""",
|
|
399
|
+
)
|
|
400
|
+
assert docstring.returns is not None
|
|
401
|
+
assert docstring.returns.type_name is None
|
|
402
|
+
assert docstring.returns.description == 'description'
|
|
403
|
+
assert docstring.returns.is_generator
|
|
404
|
+
assert docstring.many_returns is not None
|
|
405
|
+
assert len(docstring.many_returns) == 1
|
|
406
|
+
assert docstring.many_returns[0] == docstring.returns
|
|
407
|
+
|
|
408
|
+
docstring = parse(
|
|
409
|
+
"""
|
|
410
|
+
Short description
|
|
411
|
+
:yields int: description
|
|
412
|
+
""",
|
|
413
|
+
)
|
|
414
|
+
assert docstring.returns is not None
|
|
415
|
+
assert docstring.returns.type_name == 'int'
|
|
416
|
+
assert docstring.returns.description == 'description'
|
|
417
|
+
assert docstring.returns.is_generator
|
|
418
|
+
assert docstring.many_returns is not None
|
|
419
|
+
assert len(docstring.many_returns) == 1
|
|
420
|
+
assert docstring.many_returns[0] == docstring.returns
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
def test_raises() -> None:
|
|
424
|
+
"""Test parsing raises."""
|
|
425
|
+
docstring = parse(
|
|
426
|
+
"""
|
|
427
|
+
Short description
|
|
428
|
+
""",
|
|
429
|
+
)
|
|
430
|
+
assert len(docstring.raises) == 0
|
|
431
|
+
|
|
432
|
+
docstring = parse(
|
|
433
|
+
"""
|
|
434
|
+
Short description
|
|
435
|
+
:raises: description
|
|
436
|
+
""",
|
|
437
|
+
)
|
|
438
|
+
assert len(docstring.raises) == 1
|
|
439
|
+
assert docstring.raises[0].type_name is None
|
|
440
|
+
assert docstring.raises[0].description == 'description'
|
|
441
|
+
|
|
442
|
+
docstring = parse(
|
|
443
|
+
"""
|
|
444
|
+
Short description
|
|
445
|
+
:raises ValueError: description
|
|
446
|
+
""",
|
|
447
|
+
)
|
|
448
|
+
assert len(docstring.raises) == 1
|
|
449
|
+
assert docstring.raises[0].type_name == 'ValueError'
|
|
450
|
+
assert docstring.raises[0].description == 'description'
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
def test_broken_meta() -> None:
|
|
454
|
+
"""Test parsing broken meta."""
|
|
455
|
+
with pytest.raises(ParseError):
|
|
456
|
+
parse(':')
|
|
457
|
+
|
|
458
|
+
with pytest.raises(ParseError):
|
|
459
|
+
parse(':param herp derp')
|
|
460
|
+
|
|
461
|
+
with pytest.raises(ParseError):
|
|
462
|
+
parse(':param: invalid')
|
|
463
|
+
|
|
464
|
+
with pytest.raises(ParseError):
|
|
465
|
+
parse(':param with too many args: desc')
|
|
466
|
+
|
|
467
|
+
# these should not raise any errors
|
|
468
|
+
parse(':sthstrange: desc')
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
def test_deprecation() -> None:
|
|
472
|
+
"""Test parsing deprecation notes."""
|
|
473
|
+
docstring = parse(':deprecation: 1.1.0 this function will be removed')
|
|
474
|
+
assert docstring.deprecation is not None
|
|
475
|
+
assert docstring.deprecation.version == '1.1.0'
|
|
476
|
+
assert docstring.deprecation.description == 'this function will be removed'
|
|
477
|
+
|
|
478
|
+
docstring = parse(':deprecation: this function will be removed')
|
|
479
|
+
assert docstring.deprecation is not None
|
|
480
|
+
assert docstring.deprecation.version is None
|
|
481
|
+
assert docstring.deprecation.description == 'this function will be removed'
|
|
482
|
+
|
|
483
|
+
|
|
484
|
+
@pytest.mark.parametrize(
|
|
485
|
+
'rendering_style, expected',
|
|
486
|
+
[
|
|
487
|
+
(
|
|
488
|
+
RenderingStyle.COMPACT,
|
|
489
|
+
'Short description.\n'
|
|
490
|
+
'\n'
|
|
491
|
+
'Long description.\n'
|
|
492
|
+
'\n'
|
|
493
|
+
':param int foo: a description\n'
|
|
494
|
+
':param int bar: another description\n'
|
|
495
|
+
':returns float: a return',
|
|
496
|
+
),
|
|
497
|
+
(
|
|
498
|
+
RenderingStyle.CLEAN,
|
|
499
|
+
'Short description.\n'
|
|
500
|
+
'\n'
|
|
501
|
+
'Long description.\n'
|
|
502
|
+
'\n'
|
|
503
|
+
':param int foo: a description\n'
|
|
504
|
+
':param int bar: another description\n'
|
|
505
|
+
':returns float: a return',
|
|
506
|
+
),
|
|
507
|
+
(
|
|
508
|
+
RenderingStyle.EXPANDED,
|
|
509
|
+
'Short description.\n'
|
|
510
|
+
'\n'
|
|
511
|
+
'Long description.\n'
|
|
512
|
+
'\n'
|
|
513
|
+
':param foo:\n'
|
|
514
|
+
' a description\n'
|
|
515
|
+
':type foo: int\n'
|
|
516
|
+
':param bar:\n'
|
|
517
|
+
' another description\n'
|
|
518
|
+
':type bar: int\n'
|
|
519
|
+
':returns:\n'
|
|
520
|
+
' a return\n'
|
|
521
|
+
':rtype: float',
|
|
522
|
+
),
|
|
523
|
+
],
|
|
524
|
+
)
|
|
525
|
+
def test_compose(rendering_style: RenderingStyle, expected: str) -> None:
|
|
526
|
+
"""Test compose"""
|
|
527
|
+
|
|
528
|
+
docstring = parse(
|
|
529
|
+
"""
|
|
530
|
+
Short description.
|
|
531
|
+
|
|
532
|
+
Long description.
|
|
533
|
+
|
|
534
|
+
:param int foo: a description
|
|
535
|
+
:param int bar: another description
|
|
536
|
+
:return float: a return
|
|
537
|
+
""",
|
|
538
|
+
)
|
|
539
|
+
assert compose(docstring, rendering_style=rendering_style) == expected
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
def test_short_rtype() -> None:
|
|
543
|
+
"""Test abbreviated docstring with only return type information."""
|
|
544
|
+
string = 'Short description.\n\n:rtype: float'
|
|
545
|
+
docstring = parse(string)
|
|
546
|
+
rendering_style = RenderingStyle.EXPANDED
|
|
547
|
+
assert compose(docstring, rendering_style=rendering_style) == string
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"""Test for utility functions."""
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from singlestoredb.docstring.common import DocstringReturns
|
|
5
|
+
from singlestoredb.docstring.util import combine_docstrings
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_combine_docstrings() -> None:
|
|
9
|
+
"""Test combine_docstrings wrapper."""
|
|
10
|
+
|
|
11
|
+
def fun1(arg_a: Any, arg_b: Any, arg_c: Any, arg_d: Any) -> None:
|
|
12
|
+
"""short_description: fun1
|
|
13
|
+
|
|
14
|
+
:param arg_a: fun1
|
|
15
|
+
:param arg_b: fun1
|
|
16
|
+
:return: fun1
|
|
17
|
+
"""
|
|
18
|
+
assert arg_a and arg_b and arg_c and arg_d
|
|
19
|
+
|
|
20
|
+
def fun2(arg_b: Any, arg_c: Any, arg_d: Any, arg_e: Any) -> None:
|
|
21
|
+
"""short_description: fun2
|
|
22
|
+
|
|
23
|
+
long_description: fun2
|
|
24
|
+
|
|
25
|
+
:param arg_b: fun2
|
|
26
|
+
:param arg_c: fun2
|
|
27
|
+
:param arg_e: fun2
|
|
28
|
+
"""
|
|
29
|
+
assert arg_b and arg_c and arg_d and arg_e
|
|
30
|
+
|
|
31
|
+
@combine_docstrings(fun1, fun2)
|
|
32
|
+
def decorated1(
|
|
33
|
+
arg_a: Any, arg_b: Any, arg_c: Any,
|
|
34
|
+
arg_d: Any, arg_e: Any, arg_f: Any,
|
|
35
|
+
) -> None:
|
|
36
|
+
"""
|
|
37
|
+
:param arg_e: decorated
|
|
38
|
+
:param arg_f: decorated
|
|
39
|
+
"""
|
|
40
|
+
assert arg_a and arg_b and arg_c and arg_d and arg_e and arg_f
|
|
41
|
+
|
|
42
|
+
assert decorated1.__doc__ == (
|
|
43
|
+
'short_description: fun2\n'
|
|
44
|
+
'\n'
|
|
45
|
+
'long_description: fun2\n'
|
|
46
|
+
'\n'
|
|
47
|
+
':param arg_a: fun1\n'
|
|
48
|
+
':param arg_b: fun1\n'
|
|
49
|
+
':param arg_c: fun2\n'
|
|
50
|
+
':param arg_e: fun2\n'
|
|
51
|
+
':param arg_f: decorated\n'
|
|
52
|
+
':returns: fun1'
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
@combine_docstrings(fun1, fun2, exclude=[DocstringReturns])
|
|
56
|
+
def decorated2(
|
|
57
|
+
arg_a: Any, arg_b: Any, arg_c: Any, arg_d: Any, arg_e: Any, arg_f: Any,
|
|
58
|
+
) -> None:
|
|
59
|
+
assert arg_a and arg_b and arg_c and arg_d and arg_e and arg_f
|
|
60
|
+
|
|
61
|
+
assert decorated2.__doc__ == (
|
|
62
|
+
'short_description: fun2\n'
|
|
63
|
+
'\n'
|
|
64
|
+
'long_description: fun2\n'
|
|
65
|
+
'\n'
|
|
66
|
+
':param arg_a: fun1\n'
|
|
67
|
+
':param arg_b: fun1\n'
|
|
68
|
+
':param arg_c: fun2\n'
|
|
69
|
+
':param arg_e: fun2'
|
|
70
|
+
)
|