rapydscript-ns 0.9.2 → 0.9.4
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 +28 -0
- package/PYTHON_GAPS.md +352 -0
- package/README.md +176 -32
- package/TODO.md +1 -128
- package/bin/rapydscript +70 -70
- package/language-service/index.js +242 -11
- package/memory/project_string_impl.md +43 -0
- package/package.json +1 -1
- package/release/baselib-plain-pretty.js +248 -38
- package/release/baselib-plain-ugly.js +8 -8
- package/release/compiler.js +778 -277
- package/release/signatures.json +30 -30
- package/src/ast.pyj +10 -1
- package/src/baselib-builtins.pyj +56 -2
- package/src/baselib-containers.pyj +25 -1
- package/src/baselib-errors.pyj +7 -3
- package/src/baselib-internal.pyj +51 -6
- package/src/baselib-str.pyj +18 -5
- 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 +228 -4
- 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/pprint.pyj +455 -0
- package/src/lib/pythonize.pyj +20 -20
- package/src/lib/statistics.pyj +0 -0
- 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 +203 -4
- package/src/monaco-language-service/scope.js +1 -0
- package/src/output/codegen.pyj +4 -1
- package/src/output/functions.pyj +152 -6
- package/src/output/loops.pyj +17 -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 +108 -24
- package/src/tokenizer.pyj +19 -3
- package/test/async_generators.pyj +144 -0
- package/test/asyncio.pyj +307 -0
- package/test/base64.pyj +202 -0
- package/test/baselib.pyj +23 -0
- package/test/bisect.pyj +178 -0
- package/test/chainmap.pyj +185 -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 +79 -72
- package/test/logging.pyj +356 -0
- package/test/long.pyj +130 -0
- package/test/parenthesized_with.pyj +141 -0
- package/test/pprint.pyj +232 -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/statistics.pyj +224 -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 +94 -6
- package/test/unit/language-service-completions.js +121 -0
- package/test/unit/language-service-scope.js +32 -0
- package/test/unit/language-service.js +190 -5
- package/test/unit/run-language-service.js +17 -3
- package/test/unit/web-repl.js +2401 -13
- package/test/urllib.pyj +193 -0
- package/tools/compile.js +1 -1
- package/tools/embedded_compiler.js +7 -7
- package/tools/export.js +4 -2
- package/web-repl/main.js +1 -1
- package/web-repl/rapydscript.js +7 -5
- package/test/omit_function_metadata.pyj +0 -20
package/test/urllib.pyj
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# globals: assrt
|
|
2
|
+
# vim:fileencoding=utf-8
|
|
3
|
+
#
|
|
4
|
+
# urllib.pyj
|
|
5
|
+
# Tests for the urllib standard library module.
|
|
6
|
+
#
|
|
7
|
+
# Covers urllib.parse (pure-JS, no network) and urllib.error exception classes.
|
|
8
|
+
# urllib.request requires a live network (Fetch API) so it is exercised only
|
|
9
|
+
# in the web-repl bundle tests via a mocked Promise chain.
|
|
10
|
+
|
|
11
|
+
from urllib.parse import (
|
|
12
|
+
quote, unquote, quote_plus, unquote_plus,
|
|
13
|
+
urlencode, urlsplit, urlunsplit, urlparse, urlunparse,
|
|
14
|
+
urljoin, parse_qs, parse_qsl,
|
|
15
|
+
SplitResult, ParseResult
|
|
16
|
+
)
|
|
17
|
+
from urllib.error import URLError, HTTPError
|
|
18
|
+
|
|
19
|
+
ae = assrt.equal
|
|
20
|
+
ade = assrt.deepEqual
|
|
21
|
+
ok = assrt.ok
|
|
22
|
+
|
|
23
|
+
# ── 1. quote — basic percent-encoding ────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
ae(quote('hello world'), 'hello%20world')
|
|
26
|
+
ae(quote('a/b/c'), 'a/b/c') # '/' is safe by default
|
|
27
|
+
ae(quote('a/b/c', safe=''), 'a%2Fb%2Fc')
|
|
28
|
+
ae(quote('abc123-_.~'), 'abc123-_.~') # unreserved chars pass through
|
|
29
|
+
ae(quote('a+b'), 'a%2Bb')
|
|
30
|
+
ae(quote('a=1&b=2', safe=''), 'a%3D1%26b%3D2')
|
|
31
|
+
ae(quote('!*\'()'), '%21%2A%27%28%29') # sub-delimiters encoded
|
|
32
|
+
|
|
33
|
+
# ── 2. unquote ────────────────────────────────────────────────────────────────
|
|
34
|
+
|
|
35
|
+
ae(unquote('hello%20world'), 'hello world')
|
|
36
|
+
ae(unquote('a%2Fb'), 'a/b')
|
|
37
|
+
ae(unquote('abc'), 'abc')
|
|
38
|
+
ae(unquote('a%2Bb'), 'a+b') # '+' is not decoded by unquote
|
|
39
|
+
|
|
40
|
+
# ── 3. quote_plus / unquote_plus ─────────────────────────────────────────────
|
|
41
|
+
|
|
42
|
+
ae(quote_plus('hello world'), 'hello+world')
|
|
43
|
+
ae(quote_plus('a+b'), 'a%2Bb')
|
|
44
|
+
ae(quote_plus('a/b', safe=''), 'a%2Fb')
|
|
45
|
+
ae(unquote_plus('hello+world'), 'hello world')
|
|
46
|
+
ae(unquote_plus('a%2Bb'), 'a+b')
|
|
47
|
+
ae(unquote_plus('hello%20world'), 'hello world')
|
|
48
|
+
|
|
49
|
+
# ── 4. urlencode — list of pairs ─────────────────────────────────────────────
|
|
50
|
+
|
|
51
|
+
ae(urlencode([['a', '1'], ['b', '2']]), 'a=1&b=2')
|
|
52
|
+
ae(urlencode([['q', 'hello world']]), 'q=hello%20world')
|
|
53
|
+
ae(urlencode([['k', 'a+b']]), 'k=a%2Bb')
|
|
54
|
+
ae(urlencode([]), '')
|
|
55
|
+
|
|
56
|
+
# ── 5. urlencode — doseq ─────────────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
ae(urlencode([['a', ['x', 'y']]], doseq=True), 'a=x&a=y')
|
|
59
|
+
ae(urlencode([['a', ['x', 'y']], ['b', '1']], doseq=True), 'a=x&a=y&b=1')
|
|
60
|
+
|
|
61
|
+
# ── 6. urlsplit — absolute URL ────────────────────────────────────────────────
|
|
62
|
+
|
|
63
|
+
r = urlsplit('http://example.com/path?q=1#frag')
|
|
64
|
+
ae(r.scheme, 'http')
|
|
65
|
+
ae(r.netloc, 'example.com')
|
|
66
|
+
ae(r.path, '/path')
|
|
67
|
+
ae(r.query, 'q=1')
|
|
68
|
+
ae(r.fragment, 'frag')
|
|
69
|
+
ae(r.hostname, 'example.com')
|
|
70
|
+
ae(r.port, None)
|
|
71
|
+
ae(r.username, None)
|
|
72
|
+
ae(r.password, None)
|
|
73
|
+
|
|
74
|
+
# ── 7. urlsplit — authority with user:pass@host:port ─────────────────────────
|
|
75
|
+
|
|
76
|
+
r2 = urlsplit('https://user:pw@host:8080/p?x=1')
|
|
77
|
+
ae(r2.scheme, 'https')
|
|
78
|
+
ae(r2.netloc, 'user:pw@host:8080')
|
|
79
|
+
ae(r2.path, '/p')
|
|
80
|
+
ae(r2.query, 'x=1')
|
|
81
|
+
ae(r2.hostname, 'host')
|
|
82
|
+
ae(r2.port, 8080)
|
|
83
|
+
ae(r2.username, 'user')
|
|
84
|
+
ae(r2.password, 'pw')
|
|
85
|
+
|
|
86
|
+
# ── 8. urlsplit — no fragment ─────────────────────────────────────────────────
|
|
87
|
+
|
|
88
|
+
r3 = urlsplit('http://example.com/path?q=1', allow_fragments=False)
|
|
89
|
+
ae(r3.fragment, '')
|
|
90
|
+
ae(r3.query, 'q=1')
|
|
91
|
+
|
|
92
|
+
# ── 9. urlsplit — relative URL ────────────────────────────────────────────────
|
|
93
|
+
|
|
94
|
+
r4 = urlsplit('/path?q=1#frag')
|
|
95
|
+
ae(r4.scheme, '')
|
|
96
|
+
ae(r4.netloc, '')
|
|
97
|
+
ae(r4.path, '/path')
|
|
98
|
+
ae(r4.query, 'q=1')
|
|
99
|
+
ae(r4.fragment, 'frag')
|
|
100
|
+
|
|
101
|
+
# ── 10. urlparse — params split from path ─────────────────────────────────────
|
|
102
|
+
|
|
103
|
+
r5 = urlparse('http://example.com/path;params?q=1#frag')
|
|
104
|
+
ae(r5.scheme, 'http')
|
|
105
|
+
ae(r5.path, '/path')
|
|
106
|
+
ae(r5.params, 'params')
|
|
107
|
+
ae(r5.query, 'q=1')
|
|
108
|
+
ae(r5.fragment, 'frag')
|
|
109
|
+
|
|
110
|
+
r6 = urlparse('http://example.com/path?q=1')
|
|
111
|
+
ae(r6.params, '')
|
|
112
|
+
|
|
113
|
+
# ── 11. urlunsplit / urlunparse ───────────────────────────────────────────────
|
|
114
|
+
|
|
115
|
+
ae(urlunsplit(('http', 'example.com', '/path', 'q=1', 'frag')),
|
|
116
|
+
'http://example.com/path?q=1#frag')
|
|
117
|
+
ae(urlunsplit(('http', 'example.com', '/path', '', '')),
|
|
118
|
+
'http://example.com/path')
|
|
119
|
+
ae(urlunsplit(('', '', '/path', 'q=1', '')),
|
|
120
|
+
'/path?q=1')
|
|
121
|
+
ae(urlunparse(('http', 'example.com', '/path', 'par', 'q=1', 'frag')),
|
|
122
|
+
'http://example.com/path;par?q=1#frag')
|
|
123
|
+
ae(urlunparse(('http', 'example.com', '/path', '', 'q=1', '')),
|
|
124
|
+
'http://example.com/path?q=1')
|
|
125
|
+
|
|
126
|
+
# ── 12. geturl round-trip ─────────────────────────────────────────────────────
|
|
127
|
+
|
|
128
|
+
r7 = urlsplit('http://example.com/path?q=1#frag')
|
|
129
|
+
ae(r7.geturl(), 'http://example.com/path?q=1#frag')
|
|
130
|
+
|
|
131
|
+
r8 = urlparse('http://example.com/path?q=1#frag')
|
|
132
|
+
ae(r8.geturl(), 'http://example.com/path?q=1#frag')
|
|
133
|
+
|
|
134
|
+
# ── 13. urljoin ───────────────────────────────────────────────────────────────
|
|
135
|
+
|
|
136
|
+
ae(urljoin('http://example.com/foo', 'bar'), 'http://example.com/bar')
|
|
137
|
+
ae(urljoin('http://example.com/foo/', 'bar'), 'http://example.com/foo/bar')
|
|
138
|
+
ae(urljoin('http://example.com/', '/other'), 'http://example.com/other')
|
|
139
|
+
ae(urljoin('http://example.com/foo', 'http://other.com/'), 'http://other.com/')
|
|
140
|
+
ae(urljoin('http://example.com/foo', '?q=1'), 'http://example.com/foo?q=1')
|
|
141
|
+
|
|
142
|
+
# ── 14. parse_qsl ─────────────────────────────────────────────────────────────
|
|
143
|
+
|
|
144
|
+
pairs = parse_qsl('a=1&b=2&a=3')
|
|
145
|
+
ade(pairs[0], ['a', '1'])
|
|
146
|
+
ade(pairs[1], ['b', '2'])
|
|
147
|
+
ade(pairs[2], ['a', '3'])
|
|
148
|
+
ae(len(pairs), 3)
|
|
149
|
+
|
|
150
|
+
pairs2 = parse_qsl('a=hello+world')
|
|
151
|
+
ae(len(pairs2), 1)
|
|
152
|
+
ae(pairs2[0][1], 'hello world')
|
|
153
|
+
|
|
154
|
+
pairs3 = parse_qsl('q=a%20b')
|
|
155
|
+
ae(pairs3[0][1], 'a b')
|
|
156
|
+
|
|
157
|
+
ae(len(parse_qsl('')), 0)
|
|
158
|
+
|
|
159
|
+
# ── 15. parse_qs ─────────────────────────────────────────────────────────────
|
|
160
|
+
|
|
161
|
+
d = parse_qs('a=1&b=2&a=3')
|
|
162
|
+
ade(d['a'], ['1', '3'])
|
|
163
|
+
ade(d['b'], ['2'])
|
|
164
|
+
|
|
165
|
+
d2 = parse_qs('q=hello+world')
|
|
166
|
+
ae(d2['q'][0], 'hello world')
|
|
167
|
+
|
|
168
|
+
ae(len(parse_qs('')), 0)
|
|
169
|
+
|
|
170
|
+
# ── 16. URLError / HTTPError ──────────────────────────────────────────────────
|
|
171
|
+
|
|
172
|
+
try:
|
|
173
|
+
raise URLError('network error')
|
|
174
|
+
ok(False)
|
|
175
|
+
except URLError as e:
|
|
176
|
+
ok('network error' in str(e.reason))
|
|
177
|
+
|
|
178
|
+
try:
|
|
179
|
+
raise HTTPError('http://example.com', 404, 'Not Found', {}, None)
|
|
180
|
+
ok(False)
|
|
181
|
+
except HTTPError as e:
|
|
182
|
+
ae(e.code, 404)
|
|
183
|
+
ae(e.msg, 'Not Found')
|
|
184
|
+
ae(e.getcode(), 404)
|
|
185
|
+
ae(e.geturl(), 'http://example.com')
|
|
186
|
+
ok(isinstance(e, URLError))
|
|
187
|
+
|
|
188
|
+
try:
|
|
189
|
+
raise HTTPError('http://example.com', 500, 'Internal Server Error', {}, None)
|
|
190
|
+
ok(False)
|
|
191
|
+
except URLError as e:
|
|
192
|
+
# HTTPError is caught by URLError handler (inheritance)
|
|
193
|
+
ae(e.code, 500)
|
package/tools/compile.js
CHANGED
|
@@ -76,7 +76,7 @@ module.exports = function(start_time, argv, base_path, src_path, lib_path) {
|
|
|
76
76
|
|
|
77
77
|
var global_scoped_flags = build_scoped_flags(argv.python_flags);
|
|
78
78
|
if (!argv.legacy_rapydscript) {
|
|
79
|
-
var python_mode_flags = ['dict_literals', 'overload_getitem', 'bound_methods', 'hash_literals', 'overload_operators', 'truthiness', 'jsx'];
|
|
79
|
+
var python_mode_flags = ['dict_literals', 'overload_getitem', 'bound_methods', 'hash_literals', 'overload_operators', 'truthiness', 'jsx', 'type_enforcement'];
|
|
80
80
|
python_mode_flags.forEach(function(f) { if (!(f in global_scoped_flags)) global_scoped_flags[f] = true; });
|
|
81
81
|
if (!argv.pythonize_strings) OUTPUT_OPTIONS.pythonize_strings = true;
|
|
82
82
|
}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"use strict"; /*jshint node:true */
|
|
8
8
|
|
|
9
9
|
var has_prop = Object.prototype.hasOwnProperty.call.bind(Object.prototype.hasOwnProperty);
|
|
10
|
-
var PYTHON_MODE_FLAGS = ['dict_literals', 'overload_getitem', 'bound_methods', 'hash_literals', 'overload_operators', 'truthiness', 'jsx'];
|
|
10
|
+
var PYTHON_MODE_FLAGS = ['dict_literals', 'overload_getitem', 'bound_methods', 'hash_literals', 'overload_operators', 'truthiness', 'jsx', 'type_enforcement'];
|
|
11
11
|
|
|
12
12
|
function build_scoped_flags(flags_str) {
|
|
13
13
|
var result = Object.create(null);
|
|
@@ -28,8 +28,8 @@ module.exports = function(compiler, baselib, runjs, name, vf_context) {
|
|
|
28
28
|
runjs(print_ast(compiler.parse(''), true));
|
|
29
29
|
runjs('var __name__ = "' + (name || '__embedded__') + '";');
|
|
30
30
|
|
|
31
|
-
function print_ast(ast, keep_baselib, keep_docstrings, js_version, private_scope, write_name,
|
|
32
|
-
var output_options = {omit_baselib:!keep_baselib, write_name:!!write_name, private_scope:!!private_scope, beautify:true, js_version: (js_version || 6), keep_docstrings:keep_docstrings,
|
|
31
|
+
function print_ast(ast, keep_baselib, keep_docstrings, js_version, private_scope, write_name, pythonize_strings) {
|
|
32
|
+
var output_options = {omit_baselib:!keep_baselib, write_name:!!write_name, private_scope:!!private_scope, beautify:true, js_version: (js_version || 6), keep_docstrings:keep_docstrings, pythonize_strings:!!pythonize_strings};
|
|
33
33
|
if (keep_baselib) output_options.baselib_plain = baselib;
|
|
34
34
|
var output = new compiler.OutputStream(output_options);
|
|
35
35
|
ast.print(output);
|
|
@@ -105,8 +105,8 @@ module.exports = function(compiler, baselib, runjs, name, vf_context) {
|
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
107
|
|
|
108
|
-
function print_ast_with_sourcemap(ast, keep_baselib, keep_docstrings, js_version, private_scope, write_name,
|
|
109
|
-
var output_options = {omit_baselib:!keep_baselib, write_name:!!write_name, private_scope:!!private_scope, beautify:true, js_version:(js_version||6), keep_docstrings:keep_docstrings,
|
|
108
|
+
function print_ast_with_sourcemap(ast, keep_baselib, keep_docstrings, js_version, private_scope, write_name, pythonize_strings, source_name, source_content) {
|
|
109
|
+
var output_options = {omit_baselib:!keep_baselib, write_name:!!write_name, private_scope:!!private_scope, beautify:true, js_version:(js_version||6), keep_docstrings:keep_docstrings, pythonize_strings:!!pythonize_strings};
|
|
110
110
|
if (keep_baselib) output_options.baselib_plain = baselib;
|
|
111
111
|
var raw_mappings = [];
|
|
112
112
|
var output = new compiler.OutputStream(output_options);
|
|
@@ -171,7 +171,7 @@ module.exports = function(compiler, baselib, runjs, name, vf_context) {
|
|
|
171
171
|
});
|
|
172
172
|
}
|
|
173
173
|
var pythonize_strings = (opts.legacy_rapydscript !== true) ? true : !!opts.pythonize_strings;
|
|
174
|
-
var ans = print_ast(this.toplevel, opts.keep_baselib, opts.keep_docstrings, opts.js_version, opts.private_scope, opts.write_name,
|
|
174
|
+
var ans = print_ast(this.toplevel, opts.keep_baselib, opts.keep_docstrings, opts.js_version, opts.private_scope, opts.write_name, pythonize_strings);
|
|
175
175
|
if (opts.export_main) {
|
|
176
176
|
ans = ans.replace(/^(function\smain)/gm, 'export $1')
|
|
177
177
|
.replace(/^(async\sfunction\smain)/gm, 'export $1');
|
|
@@ -233,7 +233,7 @@ module.exports = function(compiler, baselib, runjs, name, vf_context) {
|
|
|
233
233
|
var result = print_ast_with_sourcemap(
|
|
234
234
|
this.toplevel,
|
|
235
235
|
opts.keep_baselib, opts.keep_docstrings, opts.js_version,
|
|
236
|
-
opts.private_scope, opts.write_name,
|
|
236
|
+
opts.private_scope, opts.write_name,
|
|
237
237
|
pythonize_strings_sm,
|
|
238
238
|
opts.filename || '<input>',
|
|
239
239
|
code
|
package/tools/export.js
CHANGED
|
@@ -229,7 +229,8 @@ function compile(code, filename, options) {
|
|
|
229
229
|
|
|
230
230
|
function create_embedded_compiler(runjs) {
|
|
231
231
|
var c = vrequire('tools/embedded_compiler.js');
|
|
232
|
-
|
|
232
|
+
if (!RapydScript) RapydScript = create_compiler();
|
|
233
|
+
return c(RapydScript, data['baselib-plain-pretty.js'], runjs);
|
|
233
234
|
}
|
|
234
235
|
|
|
235
236
|
function web_repl() {
|
|
@@ -238,7 +239,8 @@ function web_repl() {
|
|
|
238
239
|
set: function(vf) { current_virtual_files = vf; },
|
|
239
240
|
clear: function() { current_virtual_files = null; }
|
|
240
241
|
};
|
|
241
|
-
|
|
242
|
+
if (!RapydScript) RapydScript = create_compiler();
|
|
243
|
+
return repl(RapydScript, data['baselib-plain-pretty.js'], vf_context);
|
|
242
244
|
}
|
|
243
245
|
|
|
244
246
|
function init_repl(options) {
|
package/web-repl/main.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
function compile(code) {
|
|
21
|
-
return web_repl.compile(code, {
|
|
21
|
+
return web_repl.compile(code, {tree_shake: false, export_main: true, virtual_files: VIRTUAL_FILES, legacy_rapydscript: false});
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
function runjs(code) {
|