rapydscript-ns 0.9.1 → 0.9.3
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.
- package/CHANGELOG.md +22 -1
- package/PYTHON_GAPS.md +420 -0
- package/README.md +154 -30
- package/TODO.md +22 -7
- package/language-service/index.js +241 -12
- package/language-service/language-service.d.ts +1 -1
- package/memory/project_string_impl.md +43 -0
- package/package.json +6 -2
- package/release/baselib-plain-pretty.js +248 -38
- package/release/baselib-plain-ugly.js +8 -8
- package/release/compiler.js +821 -305
- package/release/signatures.json +15 -15
- package/src/ast.pyj +4 -1
- package/src/baselib-builtins.pyj +56 -2
- package/src/baselib-containers.pyj +2 -0
- package/src/baselib-errors.pyj +7 -3
- package/src/baselib-internal.pyj +51 -6
- package/src/baselib-str.pyj +5 -3
- package/src/lib/asyncio.pyj +534 -0
- package/src/lib/base64.pyj +399 -0
- package/src/lib/bisect.pyj +73 -0
- package/src/lib/collections.pyj +1 -1
- package/src/lib/csv.pyj +494 -0
- package/src/lib/heapq.pyj +98 -0
- package/src/lib/html.pyj +382 -0
- package/src/lib/http/__init__.pyj +98 -0
- package/src/lib/http/client.pyj +304 -0
- package/src/lib/http/cookies.pyj +236 -0
- package/src/lib/logging.pyj +672 -0
- package/src/lib/pythonize.pyj +1 -1
- package/src/lib/string.pyj +357 -0
- package/src/lib/textwrap.pyj +329 -0
- package/src/lib/urllib/__init__.pyj +14 -0
- package/src/lib/urllib/error.pyj +66 -0
- package/src/lib/urllib/parse.pyj +475 -0
- package/src/lib/urllib/request.pyj +86 -0
- package/src/monaco-language-service/analyzer.js +5 -2
- package/src/monaco-language-service/completions.js +26 -0
- package/src/monaco-language-service/diagnostics.js +204 -5
- package/src/monaco-language-service/index.js +2 -2
- package/src/monaco-language-service/scope.js +1 -0
- package/src/output/functions.pyj +152 -6
- package/src/output/loops.pyj +26 -2
- package/src/output/modules.pyj +1 -1
- package/src/output/operators.pyj +15 -0
- package/src/output/stream.pyj +0 -1
- package/src/parse.pyj +80 -17
- package/src/tokenizer.pyj +1 -1
- package/test/async_generators.pyj +144 -0
- package/test/asyncio.pyj +307 -0
- package/test/base64.pyj +202 -0
- package/test/bisect.pyj +178 -0
- package/test/csv.pyj +405 -0
- package/test/float_special.pyj +64 -0
- package/test/heapq.pyj +174 -0
- package/test/html.pyj +212 -0
- package/test/http.pyj +259 -0
- package/test/imports.pyj +7 -0
- package/test/logging.pyj +356 -0
- package/test/long.pyj +130 -0
- package/test/parenthesized_with.pyj +141 -0
- package/test/python_compat.pyj +3 -5
- package/test/python_modulo.pyj +76 -0
- package/test/python_modulo_off.pyj +21 -0
- package/test/str.pyj +14 -0
- package/test/string.pyj +245 -0
- package/test/textwrap.pyj +172 -0
- package/test/type_display.pyj +48 -0
- package/test/type_enforcement.pyj +164 -0
- package/test/unit/index.js +80 -6
- package/test/unit/language-service-completions.js +119 -0
- package/test/unit/language-service-scope.js +32 -0
- package/test/unit/language-service.js +128 -4
- package/test/unit/run-language-service.js +17 -3
- package/test/unit/web-repl.js +2094 -29
- package/test/urllib.pyj +193 -0
- package/tools/compile.js +1 -1
- package/tools/compiler.d.ts +367 -0
- package/tools/embedded_compiler.js +7 -7
- package/web-repl/main.js +1 -1
- package/web-repl/rapydscript.js +3 -3
- package/test/omit_function_metadata.pyj +0 -20
package/src/lib/csv.pyj
ADDED
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
###########################################################
|
|
2
|
+
# RapydScript Standard Library
|
|
3
|
+
# License: Apache License 2.0
|
|
4
|
+
# This library is covered under Apache license, so that
|
|
5
|
+
# you can distribute it with your RapydScript applications.
|
|
6
|
+
###########################################################
|
|
7
|
+
|
|
8
|
+
# Python-compatible csv module.
|
|
9
|
+
#
|
|
10
|
+
# Provides: reader, writer, DictReader, DictWriter,
|
|
11
|
+
# Dialect, excel, excel_tab, unix_dialect,
|
|
12
|
+
# register_dialect, unregister_dialect,
|
|
13
|
+
# get_dialect, list_dialects, field_size_limit,
|
|
14
|
+
# QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE,
|
|
15
|
+
# Error.
|
|
16
|
+
#
|
|
17
|
+
# Usage:
|
|
18
|
+
# import csv
|
|
19
|
+
# from io import StringIO
|
|
20
|
+
#
|
|
21
|
+
# rows = []
|
|
22
|
+
# for row in csv.reader(['a,b,c', '1,2,3']):
|
|
23
|
+
# rows.push(row)
|
|
24
|
+
#
|
|
25
|
+
# sio = StringIO()
|
|
26
|
+
# w = csv.writer(sio)
|
|
27
|
+
# w.writerow(['name', 'age'])
|
|
28
|
+
# w.writerow(['Alice', 30])
|
|
29
|
+
# print(sio.getvalue())
|
|
30
|
+
#
|
|
31
|
+
# Notes:
|
|
32
|
+
# - DictReader rows are returned as plain JS objects (access with row.field
|
|
33
|
+
# or row['field']); they are NOT ρσ_dict instances.
|
|
34
|
+
# - `default` is a JS reserved word; csv.writer's dflt param is irrelevant
|
|
35
|
+
# here, but `dialect` parameters named `default` become `dialect=` positional.
|
|
36
|
+
# - csv.Error shadows the native JS Error constructor if imported with
|
|
37
|
+
# `from csv import Error` in web-repl mode; catch via Exception instead.
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
QUOTE_MINIMAL = 0
|
|
41
|
+
QUOTE_ALL = 1
|
|
42
|
+
QUOTE_NONNUMERIC = 2
|
|
43
|
+
QUOTE_NONE = 3
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class Error(Exception):
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# ---------------------------------------------------------------------------
|
|
51
|
+
# Internal JS helpers
|
|
52
|
+
# ---------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
v"""
|
|
55
|
+
// Convert csvfile input (string, file-like, array, or iterable) to a flat
|
|
56
|
+
// text string suitable for _csv_parse_text. Array inputs strip trailing
|
|
57
|
+
// \r/\n from each element before joining so that lines like 'a,b\n' and
|
|
58
|
+
// 'a,b' both produce the same row. Returns null for an empty array (signals
|
|
59
|
+
// zero rows, not one empty-field row).
|
|
60
|
+
function _csv_to_text(src) {
|
|
61
|
+
if (typeof src === 'string') return src;
|
|
62
|
+
if (src && typeof src.read === 'function') {
|
|
63
|
+
return String(src.read() || '');
|
|
64
|
+
}
|
|
65
|
+
var arr = null;
|
|
66
|
+
if (Array.isArray(src)) {
|
|
67
|
+
arr = src;
|
|
68
|
+
} else if (src && typeof src[Symbol.iterator] === 'function') {
|
|
69
|
+
arr = [];
|
|
70
|
+
var it = src[Symbol.iterator]();
|
|
71
|
+
var r = it.next();
|
|
72
|
+
while (!r.done) { arr.push(r.value); r = it.next(); }
|
|
73
|
+
}
|
|
74
|
+
if (arr !== null) {
|
|
75
|
+
if (arr.length === 0) return null;
|
|
76
|
+
var stripped = arr.map(function(s) {
|
|
77
|
+
s = String(s);
|
|
78
|
+
var end = s.length;
|
|
79
|
+
while (end > 0 && (s[end-1] === '\r' || s[end-1] === '\n')) end--;
|
|
80
|
+
return s.slice(0, end);
|
|
81
|
+
});
|
|
82
|
+
return stripped.join('\n') + '\n';
|
|
83
|
+
}
|
|
84
|
+
return String(src || '');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Parse a CSV text string into an array of row arrays.
|
|
88
|
+
// Handles quoted fields (including multi-line), escape chars, and all
|
|
89
|
+
// QUOTE_* modes. Returns [] for null input (empty array source).
|
|
90
|
+
function _csv_parse_text(text, delimiter, quotechar, escapechar,
|
|
91
|
+
doublequote, skipinitialspace, quoting) {
|
|
92
|
+
if (text === null) return [];
|
|
93
|
+
var rows = [];
|
|
94
|
+
var field = '';
|
|
95
|
+
var fields = [];
|
|
96
|
+
var in_q = false;
|
|
97
|
+
var i = 0, n = text.length;
|
|
98
|
+
|
|
99
|
+
function push_field() {
|
|
100
|
+
if (quoting === 2) {
|
|
101
|
+
var f = field;
|
|
102
|
+
field = '';
|
|
103
|
+
var num = parseFloat(f);
|
|
104
|
+
fields.push((f.trim() !== '' && !isNaN(num) && isFinite(num)) ? num : f);
|
|
105
|
+
} else {
|
|
106
|
+
fields.push(field);
|
|
107
|
+
field = '';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
while (i < n) {
|
|
112
|
+
var c = text[i];
|
|
113
|
+
if (in_q) {
|
|
114
|
+
if (quotechar && c === quotechar) {
|
|
115
|
+
if (doublequote && i + 1 < n && text[i+1] === quotechar) {
|
|
116
|
+
field += quotechar; i += 2;
|
|
117
|
+
} else {
|
|
118
|
+
in_q = false; i++;
|
|
119
|
+
}
|
|
120
|
+
} else if (escapechar && c === escapechar && i + 1 < n) {
|
|
121
|
+
field += text[i+1]; i += 2;
|
|
122
|
+
} else {
|
|
123
|
+
field += c; i++;
|
|
124
|
+
}
|
|
125
|
+
} else {
|
|
126
|
+
if (c === '\r' || c === '\n') {
|
|
127
|
+
push_field();
|
|
128
|
+
rows.push(fields);
|
|
129
|
+
fields = [];
|
|
130
|
+
i++;
|
|
131
|
+
if (c === '\r' && i < n && text[i] === '\n') i++;
|
|
132
|
+
} else if (c === delimiter) {
|
|
133
|
+
push_field();
|
|
134
|
+
i++;
|
|
135
|
+
if (skipinitialspace && i < n && text[i] === ' ') i++;
|
|
136
|
+
} else if (quotechar && c === quotechar && quoting !== 3) {
|
|
137
|
+
in_q = true; i++;
|
|
138
|
+
} else if (escapechar && c === escapechar && i + 1 < n) {
|
|
139
|
+
field += text[i+1]; i += 2;
|
|
140
|
+
} else {
|
|
141
|
+
field += c; i++;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// final row when text does not end with a newline
|
|
146
|
+
if (fields.length > 0 || field !== '') {
|
|
147
|
+
push_field();
|
|
148
|
+
rows.push(fields);
|
|
149
|
+
}
|
|
150
|
+
return rows;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Format a single CSV field value.
|
|
154
|
+
function _csv_fmt_field(field, delimiter, quotechar, escapechar,
|
|
155
|
+
doublequote, quoting) {
|
|
156
|
+
var s;
|
|
157
|
+
if (field === null || field === undefined) s = '';
|
|
158
|
+
else s = String(field);
|
|
159
|
+
|
|
160
|
+
var needs_q = false;
|
|
161
|
+
if (quoting === 1) {
|
|
162
|
+
needs_q = true;
|
|
163
|
+
} else if (quoting === 2) {
|
|
164
|
+
if (typeof field !== 'number') needs_q = true;
|
|
165
|
+
} else if (quoting === 0) {
|
|
166
|
+
for (var i = 0; i < s.length; i++) {
|
|
167
|
+
var c = s[i];
|
|
168
|
+
if (c === delimiter || c === '\r' || c === '\n' ||
|
|
169
|
+
(quotechar && c === quotechar)) { needs_q = true; break; }
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (quoting === 3) { // QUOTE_NONE
|
|
174
|
+
if (!escapechar) return s;
|
|
175
|
+
var out = '';
|
|
176
|
+
for (var j = 0; j < s.length; j++) {
|
|
177
|
+
var ch = s[j];
|
|
178
|
+
if (ch === delimiter || ch === escapechar) out += escapechar;
|
|
179
|
+
out += ch;
|
|
180
|
+
}
|
|
181
|
+
return out;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (!needs_q) return s;
|
|
185
|
+
var q = quotechar || '"';
|
|
186
|
+
var r = q;
|
|
187
|
+
for (var k = 0; k < s.length; k++) {
|
|
188
|
+
var fc = s[k];
|
|
189
|
+
if (fc === q) {
|
|
190
|
+
if (doublequote) r += q + q;
|
|
191
|
+
else if (escapechar) r += escapechar + q;
|
|
192
|
+
else r += q;
|
|
193
|
+
} else if (escapechar && fc === escapechar) {
|
|
194
|
+
r += escapechar + escapechar;
|
|
195
|
+
} else {
|
|
196
|
+
r += fc;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return r + q;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Dict helpers — handle both plain JS objects and ρσ_dict (web-repl mode).
|
|
203
|
+
function _csv_dict_keys(d) {
|
|
204
|
+
if (d && d.jsmap && typeof d.jsmap.forEach === 'function') {
|
|
205
|
+
var ks = [];
|
|
206
|
+
d.jsmap.forEach(function(v, k) { ks.push(k); });
|
|
207
|
+
return ks;
|
|
208
|
+
}
|
|
209
|
+
return Object.keys(d || {});
|
|
210
|
+
}
|
|
211
|
+
function _csv_dict_get(d, key, dflt) {
|
|
212
|
+
if (d && d.jsmap && typeof d.jsmap.get === 'function') {
|
|
213
|
+
return d.jsmap.has(key) ? d.jsmap.get(key) : dflt;
|
|
214
|
+
}
|
|
215
|
+
if (Object.prototype.hasOwnProperty.call(d || {}, key)) return d[key];
|
|
216
|
+
return dflt;
|
|
217
|
+
}
|
|
218
|
+
"""
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
# ---------------------------------------------------------------------------
|
|
222
|
+
# Dialect classes
|
|
223
|
+
# ---------------------------------------------------------------------------
|
|
224
|
+
|
|
225
|
+
class Dialect:
|
|
226
|
+
delimiter = ','
|
|
227
|
+
quotechar = '"'
|
|
228
|
+
escapechar = None
|
|
229
|
+
doublequote = True
|
|
230
|
+
skipinitialspace = False
|
|
231
|
+
lineterminator = '\r\n'
|
|
232
|
+
quoting = QUOTE_MINIMAL
|
|
233
|
+
strict = False
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
class excel(Dialect):
|
|
237
|
+
pass
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
class excel_tab(Dialect):
|
|
241
|
+
delimiter = '\t'
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class unix_dialect(Dialect):
|
|
245
|
+
lineterminator = '\n'
|
|
246
|
+
quoting = QUOTE_ALL
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
# ---------------------------------------------------------------------------
|
|
250
|
+
# Dialect registry
|
|
251
|
+
# ---------------------------------------------------------------------------
|
|
252
|
+
|
|
253
|
+
_dialects = {}
|
|
254
|
+
_dialects['excel'] = excel()
|
|
255
|
+
_dialects['excel-tab'] = excel_tab()
|
|
256
|
+
_dialects['unix'] = unix_dialect()
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def _build_dialect(dialect, delimiter, quotechar, escapechar, doublequote,
|
|
260
|
+
skipinitialspace, lineterminator, quoting, strict):
|
|
261
|
+
if jstype(dialect) is 'string':
|
|
262
|
+
if dialect not in _dialects:
|
|
263
|
+
raise Error('unknown dialect: ' + dialect)
|
|
264
|
+
tmpl = _dialects[dialect]
|
|
265
|
+
elif dialect is None:
|
|
266
|
+
tmpl = _dialects['excel']
|
|
267
|
+
elif jstype(dialect) is 'function':
|
|
268
|
+
tmpl = dialect()
|
|
269
|
+
else:
|
|
270
|
+
tmpl = dialect
|
|
271
|
+
d = Dialect()
|
|
272
|
+
d.delimiter = tmpl.delimiter
|
|
273
|
+
d.quotechar = tmpl.quotechar
|
|
274
|
+
d.escapechar = tmpl.escapechar
|
|
275
|
+
d.doublequote = tmpl.doublequote
|
|
276
|
+
d.skipinitialspace = tmpl.skipinitialspace
|
|
277
|
+
d.lineterminator = tmpl.lineterminator
|
|
278
|
+
d.quoting = tmpl.quoting
|
|
279
|
+
d.strict = tmpl.strict
|
|
280
|
+
if delimiter is not None: d.delimiter = delimiter
|
|
281
|
+
if quotechar is not None: d.quotechar = quotechar
|
|
282
|
+
if escapechar is not None: d.escapechar = escapechar
|
|
283
|
+
if doublequote is not None: d.doublequote = doublequote
|
|
284
|
+
if skipinitialspace is not None: d.skipinitialspace = skipinitialspace
|
|
285
|
+
if lineterminator is not None: d.lineterminator = lineterminator
|
|
286
|
+
if quoting is not None: d.quoting = quoting
|
|
287
|
+
if strict is not None: d.strict = strict
|
|
288
|
+
return d
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
# ---------------------------------------------------------------------------
|
|
292
|
+
# Reader
|
|
293
|
+
# ---------------------------------------------------------------------------
|
|
294
|
+
|
|
295
|
+
class _Reader:
|
|
296
|
+
def __init__(self, csvfile, d):
|
|
297
|
+
self.dialect = d
|
|
298
|
+
self.line_num = 0
|
|
299
|
+
self._index = 0
|
|
300
|
+
self._rows = _csv_parse_text(
|
|
301
|
+
_csv_to_text(csvfile),
|
|
302
|
+
d.delimiter, d.quotechar, d.escapechar,
|
|
303
|
+
d.doublequote, d.skipinitialspace, d.quoting
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
def __iter__(self):
|
|
307
|
+
return self
|
|
308
|
+
|
|
309
|
+
def next(self):
|
|
310
|
+
if self._index >= self._rows.length:
|
|
311
|
+
return {'value': undefined, 'done': True}
|
|
312
|
+
row = self._rows[self._index]
|
|
313
|
+
self._index += 1
|
|
314
|
+
self.line_num = self._index
|
|
315
|
+
return {'value': row, 'done': False}
|
|
316
|
+
|
|
317
|
+
def __next__(self):
|
|
318
|
+
r = self.next()
|
|
319
|
+
if r.done:
|
|
320
|
+
raise StopIteration()
|
|
321
|
+
return r.value
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def reader(csvfile, dialect='excel', delimiter=None, quotechar=None,
|
|
325
|
+
escapechar=None, doublequote=None, skipinitialspace=None,
|
|
326
|
+
lineterminator=None, quoting=None, strict=None):
|
|
327
|
+
d = _build_dialect(dialect, delimiter, quotechar, escapechar, doublequote,
|
|
328
|
+
skipinitialspace, lineterminator, quoting, strict)
|
|
329
|
+
return _Reader(csvfile, d)
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
# ---------------------------------------------------------------------------
|
|
333
|
+
# Writer
|
|
334
|
+
# ---------------------------------------------------------------------------
|
|
335
|
+
|
|
336
|
+
class _Writer:
|
|
337
|
+
def __init__(self, csvfile, d):
|
|
338
|
+
self.dialect = d
|
|
339
|
+
self._file = csvfile
|
|
340
|
+
|
|
341
|
+
def writerow(self, row):
|
|
342
|
+
d = self.dialect
|
|
343
|
+
parts = []
|
|
344
|
+
for field in row:
|
|
345
|
+
parts.push(_csv_fmt_field(field, d.delimiter, d.quotechar,
|
|
346
|
+
d.escapechar, d.doublequote, d.quoting))
|
|
347
|
+
self._file.write(parts.join(d.delimiter) + d.lineterminator)
|
|
348
|
+
|
|
349
|
+
def writerows(self, rows):
|
|
350
|
+
for row in rows:
|
|
351
|
+
self.writerow(row)
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def writer(csvfile, dialect='excel', delimiter=None, quotechar=None,
|
|
355
|
+
escapechar=None, doublequote=None, skipinitialspace=None,
|
|
356
|
+
lineterminator=None, quoting=None, strict=None):
|
|
357
|
+
d = _build_dialect(dialect, delimiter, quotechar, escapechar, doublequote,
|
|
358
|
+
skipinitialspace, lineterminator, quoting, strict)
|
|
359
|
+
return _Writer(csvfile, d)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
# ---------------------------------------------------------------------------
|
|
363
|
+
# DictReader
|
|
364
|
+
# ---------------------------------------------------------------------------
|
|
365
|
+
|
|
366
|
+
class DictReader:
|
|
367
|
+
def __init__(self, f, fieldnames=None, restkey=None, restval=None,
|
|
368
|
+
dialect='excel', delimiter=None, quotechar=None,
|
|
369
|
+
escapechar=None, doublequote=None, skipinitialspace=None,
|
|
370
|
+
lineterminator=None, quoting=None, strict=None):
|
|
371
|
+
self._reader = reader(f, dialect, delimiter, quotechar, escapechar,
|
|
372
|
+
doublequote, skipinitialspace, lineterminator,
|
|
373
|
+
quoting, strict)
|
|
374
|
+
self.fieldnames = fieldnames
|
|
375
|
+
self.restkey = restkey if restkey is not None else 'EXTRA'
|
|
376
|
+
self.restval = restval
|
|
377
|
+
self.dialect = self._reader.dialect
|
|
378
|
+
self.line_num = 0
|
|
379
|
+
|
|
380
|
+
def _ensure_fieldnames(self):
|
|
381
|
+
if self.fieldnames is None:
|
|
382
|
+
try:
|
|
383
|
+
self.fieldnames = self._reader.__next__()
|
|
384
|
+
except StopIteration:
|
|
385
|
+
self.fieldnames = []
|
|
386
|
+
|
|
387
|
+
def __iter__(self):
|
|
388
|
+
return self
|
|
389
|
+
|
|
390
|
+
def next(self):
|
|
391
|
+
self._ensure_fieldnames()
|
|
392
|
+
try:
|
|
393
|
+
row = self._reader.__next__()
|
|
394
|
+
except StopIteration:
|
|
395
|
+
return {'value': undefined, 'done': True}
|
|
396
|
+
self.line_num = self._reader.line_num
|
|
397
|
+
fields = self.fieldnames
|
|
398
|
+
d = {}
|
|
399
|
+
for i in range(fields.length):
|
|
400
|
+
d[fields[i]] = row[i] if i < row.length else self.restval
|
|
401
|
+
if row.length > fields.length:
|
|
402
|
+
d[self.restkey] = row.slice(fields.length)
|
|
403
|
+
return {'value': d, 'done': False}
|
|
404
|
+
|
|
405
|
+
def __next__(self):
|
|
406
|
+
r = self.next()
|
|
407
|
+
if r.done:
|
|
408
|
+
raise StopIteration()
|
|
409
|
+
return r.value
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
# ---------------------------------------------------------------------------
|
|
413
|
+
# DictWriter
|
|
414
|
+
# ---------------------------------------------------------------------------
|
|
415
|
+
|
|
416
|
+
class DictWriter:
|
|
417
|
+
def __init__(self, f, fieldnames, restval='', extrasaction='raise',
|
|
418
|
+
dialect='excel', delimiter=None, quotechar=None,
|
|
419
|
+
escapechar=None, doublequote=None, skipinitialspace=None,
|
|
420
|
+
lineterminator=None, quoting=None, strict=None):
|
|
421
|
+
self.fieldnames = fieldnames
|
|
422
|
+
self.restval = restval
|
|
423
|
+
self.extrasaction = extrasaction
|
|
424
|
+
self._writer = writer(f, dialect, delimiter, quotechar, escapechar,
|
|
425
|
+
doublequote, skipinitialspace, lineterminator,
|
|
426
|
+
quoting, strict)
|
|
427
|
+
self.dialect = self._writer.dialect
|
|
428
|
+
|
|
429
|
+
def writeheader(self):
|
|
430
|
+
self._writer.writerow(self.fieldnames)
|
|
431
|
+
|
|
432
|
+
def writerow(self, rowdict):
|
|
433
|
+
row = []
|
|
434
|
+
fields = self.fieldnames
|
|
435
|
+
restval = self.restval
|
|
436
|
+
v"""
|
|
437
|
+
if (this.extrasaction === 'raise') {
|
|
438
|
+
var _dkeys = _csv_dict_keys(rowdict);
|
|
439
|
+
for (var _i = 0; _i < _dkeys.length; _i++) {
|
|
440
|
+
if (fields.indexOf(_dkeys[_i]) < 0) {
|
|
441
|
+
throw new ValueError(
|
|
442
|
+
"dict contains fields not in fieldnames: '" + _dkeys[_i] + "'");
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
for (var _j = 0; _j < fields.length; _j++) {
|
|
447
|
+
row.push(_csv_dict_get(rowdict, fields[_j], restval));
|
|
448
|
+
}
|
|
449
|
+
"""
|
|
450
|
+
self._writer.writerow(row)
|
|
451
|
+
|
|
452
|
+
def writerows(self, rowdicts):
|
|
453
|
+
for rowdict in rowdicts:
|
|
454
|
+
self.writerow(rowdict)
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
# ---------------------------------------------------------------------------
|
|
458
|
+
# Dialect management
|
|
459
|
+
# ---------------------------------------------------------------------------
|
|
460
|
+
|
|
461
|
+
def register_dialect(name, dialect=None, delimiter=None, quotechar=None,
|
|
462
|
+
escapechar=None, doublequote=None, skipinitialspace=None,
|
|
463
|
+
lineterminator=None, quoting=None, strict=None):
|
|
464
|
+
base = excel if dialect is None else dialect
|
|
465
|
+
d = _build_dialect(base, delimiter, quotechar, escapechar, doublequote,
|
|
466
|
+
skipinitialspace, lineterminator, quoting, strict)
|
|
467
|
+
_dialects[name] = d
|
|
468
|
+
|
|
469
|
+
|
|
470
|
+
def unregister_dialect(name):
|
|
471
|
+
if name not in _dialects:
|
|
472
|
+
raise Error('unknown dialect: ' + name)
|
|
473
|
+
v'delete _dialects[name]'
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
def get_dialect(name):
|
|
477
|
+
if name not in _dialects:
|
|
478
|
+
raise Error('unknown dialect: ' + name)
|
|
479
|
+
return _dialects[name]
|
|
480
|
+
|
|
481
|
+
|
|
482
|
+
def list_dialects():
|
|
483
|
+
return Object.keys(_dialects)
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
_field_size_limit_val = 131072
|
|
487
|
+
|
|
488
|
+
|
|
489
|
+
def field_size_limit(new_limit=None):
|
|
490
|
+
global _field_size_limit_val
|
|
491
|
+
old = _field_size_limit_val
|
|
492
|
+
if new_limit is not None:
|
|
493
|
+
_field_size_limit_val = new_limit
|
|
494
|
+
return old
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
###########################################################
|
|
2
|
+
# RapydScript Standard Library
|
|
3
|
+
# License: Apache License 2.0
|
|
4
|
+
# This library is covered under Apache license, so that
|
|
5
|
+
# you can distribute it with your RapydScript applications.
|
|
6
|
+
###########################################################
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Implementation of Python's 'heapq' module.
|
|
10
|
+
# Min-heap (priority queue) operations on lists.
|
|
11
|
+
#
|
|
12
|
+
# The heap invariant: heap[k] <= heap[2*k+1] and heap[k] <= heap[2*k+2].
|
|
13
|
+
# Algorithms ported from CPython's heapq.py.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _siftdown(heap, startpos, pos):
|
|
17
|
+
newitem = heap[pos]
|
|
18
|
+
while pos > startpos:
|
|
19
|
+
parentpos = (pos - 1) >> 1
|
|
20
|
+
parent = heap[parentpos]
|
|
21
|
+
if newitem < parent:
|
|
22
|
+
heap[pos] = parent
|
|
23
|
+
pos = parentpos
|
|
24
|
+
else:
|
|
25
|
+
break
|
|
26
|
+
heap[pos] = newitem
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _siftup(heap, pos):
|
|
30
|
+
endpos = heap.length
|
|
31
|
+
startpos = pos
|
|
32
|
+
newitem = heap[pos]
|
|
33
|
+
childpos = 2 * pos + 1
|
|
34
|
+
while childpos < endpos:
|
|
35
|
+
rightpos = childpos + 1
|
|
36
|
+
if rightpos < endpos and heap[childpos] >= heap[rightpos]:
|
|
37
|
+
childpos = rightpos
|
|
38
|
+
heap[pos] = heap[childpos]
|
|
39
|
+
pos = childpos
|
|
40
|
+
childpos = 2 * pos + 1
|
|
41
|
+
heap[pos] = newitem
|
|
42
|
+
_siftdown(heap, startpos, pos)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def heappush(heap, item):
|
|
46
|
+
heap.push(item)
|
|
47
|
+
_siftdown(heap, 0, heap.length - 1)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def heappop(heap):
|
|
51
|
+
if heap.length == 0:
|
|
52
|
+
raise IndexError('index out of range')
|
|
53
|
+
lastelt = heap.pop()
|
|
54
|
+
if heap.length > 0:
|
|
55
|
+
returnitem = heap[0]
|
|
56
|
+
heap[0] = lastelt
|
|
57
|
+
_siftup(heap, 0)
|
|
58
|
+
return returnitem
|
|
59
|
+
return lastelt
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def heapreplace(heap, item):
|
|
63
|
+
if heap.length == 0:
|
|
64
|
+
raise IndexError('index out of range')
|
|
65
|
+
returnitem = heap[0]
|
|
66
|
+
heap[0] = item
|
|
67
|
+
_siftup(heap, 0)
|
|
68
|
+
return returnitem
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def heappushpop(heap, item):
|
|
72
|
+
if heap.length > 0 and heap[0] < item:
|
|
73
|
+
tmp = heap[0]
|
|
74
|
+
heap[0] = item
|
|
75
|
+
item = tmp
|
|
76
|
+
_siftup(heap, 0)
|
|
77
|
+
return item
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def heapify(x):
|
|
81
|
+
i = Math.floor(x.length / 2) - 1
|
|
82
|
+
while i >= 0:
|
|
83
|
+
_siftup(x, i)
|
|
84
|
+
i -= 1
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def nsmallest(n, iterable, key=None):
|
|
88
|
+
if n <= 0:
|
|
89
|
+
return []
|
|
90
|
+
result = sorted(iterable, key=key)
|
|
91
|
+
return result[:n]
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def nlargest(n, iterable, key=None):
|
|
95
|
+
if n <= 0:
|
|
96
|
+
return []
|
|
97
|
+
result = sorted(iterable, key=key, reverse=True)
|
|
98
|
+
return result[:n]
|