rapydscript-ns 0.9.2 → 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/.agignore +1 -1
- package/.github/workflows/ci.yml +38 -38
- package/=template.pyj +5 -5
- package/CHANGELOG.md +19 -0
- package/HACKING.md +103 -103
- package/LICENSE +24 -24
- package/PYTHON_GAPS.md +420 -0
- package/README.md +153 -29
- package/TODO.md +16 -118
- package/add-toc-to-readme +2 -2
- package/bin/export +75 -75
- package/bin/rapydscript +70 -70
- package/bin/web-repl-export +102 -102
- package/build +2 -2
- package/language-service/index.js +237 -8
- package/memory/project_string_impl.md +43 -0
- package/package.json +1 -1
- package/publish.py +37 -37
- 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/session.vim +4 -4
- package/setup.cfg +2 -2
- 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/compiler.pyj +36 -36
- package/src/errors.pyj +30 -30
- package/src/lib/aes.pyj +646 -646
- 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/copy.pyj +120 -120
- package/src/lib/csv.pyj +494 -0
- package/src/lib/elementmaker.pyj +83 -83
- package/src/lib/encodings.pyj +126 -126
- package/src/lib/gettext.pyj +569 -569
- 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/itertools.pyj +580 -580
- package/src/lib/logging.pyj +672 -0
- package/src/lib/math.pyj +193 -193
- package/src/lib/operator.pyj +11 -11
- package/src/lib/pythonize.pyj +20 -20
- package/src/lib/random.pyj +118 -118
- package/src/lib/react.pyj +74 -74
- package/src/lib/string.pyj +357 -0
- package/src/lib/textwrap.pyj +329 -0
- package/src/lib/traceback.pyj +63 -63
- 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/lib/uuid.pyj +77 -77
- 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 +202 -3
- package/src/monaco-language-service/dts.js +550 -550
- package/src/monaco-language-service/scope.js +1 -0
- package/src/output/comments.pyj +45 -45
- package/src/output/exceptions.pyj +201 -201
- package/src/output/functions.pyj +152 -6
- package/src/output/jsx.pyj +164 -164
- 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/output/treeshake.pyj +182 -182
- package/src/output/utils.pyj +72 -72
- package/src/parse.pyj +80 -17
- package/src/string_interpolation.pyj +72 -72
- package/src/tokenizer.pyj +1 -1
- package/src/unicode_aliases.pyj +576 -576
- package/src/utils.pyj +192 -192
- package/test/_import_one.pyj +37 -37
- package/test/_import_two/__init__.pyj +11 -11
- package/test/_import_two/level2/deep.pyj +4 -4
- package/test/_import_two/other.pyj +6 -6
- package/test/_import_two/sub.pyj +13 -13
- package/test/aes_vectors.pyj +421 -421
- package/test/annotations.pyj +80 -80
- 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/decorators.pyj +77 -77
- package/test/docstrings.pyj +39 -39
- package/test/elementmaker_test.pyj +45 -45
- package/test/float_special.pyj +64 -0
- package/test/functions.pyj +151 -151
- package/test/generators.pyj +41 -41
- package/test/generic.pyj +370 -370
- 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/internationalization.pyj +73 -73
- package/test/lint.pyj +164 -164
- package/test/logging.pyj +356 -0
- package/test/long.pyj +130 -0
- package/test/loops.pyj +85 -85
- package/test/numpy.pyj +734 -734
- 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/repl.pyj +121 -121
- package/test/scoped_flags.pyj +76 -76
- 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 +14 -6
- package/test/unit/language-service-completions.js +119 -0
- package/test/unit/language-service-dts.js +543 -543
- package/test/unit/language-service-hover.js +455 -455
- package/test/unit/language-service-scope.js +32 -0
- package/test/unit/language-service.js +127 -3
- 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 -367
- package/tools/completer.js +131 -131
- package/tools/embedded_compiler.js +7 -7
- package/tools/gettext.js +185 -185
- package/tools/ini.js +65 -65
- package/tools/msgfmt.js +187 -187
- package/tools/repl.js +223 -223
- package/tools/test.js +118 -118
- package/tools/utils.js +128 -128
- package/tools/web_repl.js +95 -95
- package/try +41 -41
- package/web-repl/env.js +196 -196
- package/web-repl/index.html +163 -163
- package/web-repl/main.js +1 -1
- package/web-repl/prism.css +139 -139
- package/web-repl/prism.js +113 -113
- package/web-repl/rapydscript.js +224 -224
- package/web-repl/sha1.js +25 -25
- package/test/omit_function_metadata.pyj +0 -20
|
@@ -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]
|
package/src/lib/html.pyj
ADDED
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
###########################################################
|
|
2
|
+
# RapydScript Standard Library
|
|
3
|
+
# Author: RapydScript-NS Contributors
|
|
4
|
+
# Copyright 2024 RapydScript-NS Contributors
|
|
5
|
+
# License: Apache License 2.0
|
|
6
|
+
# This library is covered under Apache license, so that
|
|
7
|
+
# you can distribute it with your RapydScript applications.
|
|
8
|
+
###########################################################
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Python-compatible html module.
|
|
12
|
+
#
|
|
13
|
+
# Provides:
|
|
14
|
+
# escape(s, quote=True) -- escape HTML special characters
|
|
15
|
+
# unescape(s) -- decode HTML entities to Unicode characters
|
|
16
|
+
# HTMLParser -- event-driven HTML parser; subclass and
|
|
17
|
+
# override handle_* methods to process elements
|
|
18
|
+
#
|
|
19
|
+
# HTMLParser is modelled on Python's html.parser.HTMLParser.
|
|
20
|
+
# It is implemented with a regex-based JS tokeniser and works in
|
|
21
|
+
# both Node.js and browser environments.
|
|
22
|
+
#
|
|
23
|
+
# NOTE: Python's html.parser sub-module is not a separate import.
|
|
24
|
+
# Use `from html import HTMLParser` or `import html; html.HTMLParser`.
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# ---------------------------------------------------------------------------
|
|
28
|
+
# Internal JS helpers
|
|
29
|
+
# ---------------------------------------------------------------------------
|
|
30
|
+
|
|
31
|
+
v"""
|
|
32
|
+
// Named HTML5 entities (full HTML4 set + selected HTML5 additions).
|
|
33
|
+
var _html_named = {
|
|
34
|
+
'amp':'&','lt':'<','gt':'>','quot':'"','apos':"'",
|
|
35
|
+
'nbsp':' ','iexcl':'¡','cent':'¢','pound':'£',
|
|
36
|
+
'curren':'¤','yen':'¥','brvbar':'¦','sect':'§',
|
|
37
|
+
'uml':'¨','copy':'©','ordf':'ª','laquo':'«',
|
|
38
|
+
'not':'¬','shy':'','reg':'®','macr':'¯',
|
|
39
|
+
'deg':'°','plusmn':'±','sup2':'²','sup3':'³',
|
|
40
|
+
'acute':'´','micro':'µ','para':'¶','middot':'·',
|
|
41
|
+
'cedil':'¸','sup1':'¹','ordm':'º','raquo':'»',
|
|
42
|
+
'frac14':'¼','frac12':'½','frac34':'¾','iquest':'¿',
|
|
43
|
+
'Agrave':'À','Aacute':'Á','Acirc':'Â','Atilde':'Ã',
|
|
44
|
+
'Auml':'Ä','Aring':'Å','AElig':'Æ','Ccedil':'Ç',
|
|
45
|
+
'Egrave':'È','Eacute':'É','Ecirc':'Ê','Euml':'Ë',
|
|
46
|
+
'Igrave':'Ì','Iacute':'Í','Icirc':'Î','Iuml':'Ï',
|
|
47
|
+
'ETH':'Ð','Ntilde':'Ñ','Ograve':'Ò','Oacute':'Ó',
|
|
48
|
+
'Ocirc':'Ô','Otilde':'Õ','Ouml':'Ö','times':'×',
|
|
49
|
+
'Oslash':'Ø','Ugrave':'Ù','Uacute':'Ú','Ucirc':'Û',
|
|
50
|
+
'Uuml':'Ü','Yacute':'Ý','THORN':'Þ','szlig':'ß',
|
|
51
|
+
'agrave':'à','aacute':'á','acirc':'â','atilde':'ã',
|
|
52
|
+
'auml':'ä','aring':'å','aelig':'æ','ccedil':'ç',
|
|
53
|
+
'egrave':'è','eacute':'é','ecirc':'ê','euml':'ë',
|
|
54
|
+
'igrave':'ì','iacute':'í','icirc':'î','iuml':'ï',
|
|
55
|
+
'eth':'ð','ntilde':'ñ','ograve':'ò','oacute':'ó',
|
|
56
|
+
'ocirc':'ô','otilde':'õ','ouml':'ö','divide':'÷',
|
|
57
|
+
'oslash':'ø','ugrave':'ù','uacute':'ú','ucirc':'û',
|
|
58
|
+
'uuml':'ü','yacute':'ý','thorn':'þ','yuml':'ÿ',
|
|
59
|
+
'OElig':'Œ','oelig':'œ','Scaron':'Š','scaron':'š',
|
|
60
|
+
'Yuml':'Ÿ','fnof':'ƒ','circ':'ˆ','tilde':'˜',
|
|
61
|
+
'Alpha':'Α','Beta':'Β','Gamma':'Γ','Delta':'Δ',
|
|
62
|
+
'Epsilon':'Ε','Zeta':'Ζ','Eta':'Η','Theta':'Θ',
|
|
63
|
+
'Iota':'Ι','Kappa':'Κ','Lambda':'Λ','Mu':'Μ',
|
|
64
|
+
'Nu':'Ν','Xi':'Ξ','Omicron':'Ο','Pi':'Π',
|
|
65
|
+
'Rho':'Ρ','Sigma':'Σ','Tau':'Τ','Upsilon':'Υ',
|
|
66
|
+
'Phi':'Φ','Chi':'Χ','Psi':'Ψ','Omega':'Ω',
|
|
67
|
+
'alpha':'α','beta':'β','gamma':'γ','delta':'δ',
|
|
68
|
+
'epsilon':'ε','zeta':'ζ','eta':'η','theta':'θ',
|
|
69
|
+
'iota':'ι','kappa':'κ','lambda':'λ','mu':'μ',
|
|
70
|
+
'nu':'ν','xi':'ξ','omicron':'ο','pi':'π',
|
|
71
|
+
'rho':'ρ','sigmaf':'ς','sigma':'σ','tau':'τ',
|
|
72
|
+
'upsilon':'υ','phi':'φ','chi':'χ','psi':'ψ',
|
|
73
|
+
'omega':'ω','thetasym':'ϑ','upsih':'ϒ','piv':'ϖ',
|
|
74
|
+
'ensp':' ','emsp':' ','thinsp':' ','zwnj':'',
|
|
75
|
+
'zwj':'','lrm':'','rlm':'','ndash':'–',
|
|
76
|
+
'mdash':'—','lsquo':'‘','rsquo':'’','sbquo':'‚',
|
|
77
|
+
'ldquo':'“','rdquo':'”','bdquo':'„','dagger':'†',
|
|
78
|
+
'Dagger':'‡','bull':'•','hellip':'…','permil':'‰',
|
|
79
|
+
'prime':'′','Prime':'″','lsaquo':'‹','rsaquo':'›',
|
|
80
|
+
'oline':'‾','frasl':'⁄','euro':'€','image':'ℑ',
|
|
81
|
+
'weierp':'℘','real':'ℜ','trade':'™','alefsym':'ℵ',
|
|
82
|
+
'larr':'←','uarr':'↑','rarr':'→','darr':'↓',
|
|
83
|
+
'harr':'↔','crarr':'↵','lArr':'⇐','uArr':'⇑',
|
|
84
|
+
'rArr':'⇒','dArr':'⇓','hArr':'⇔','forall':'∀',
|
|
85
|
+
'part':'∂','exist':'∃','empty':'∅','nabla':'∇',
|
|
86
|
+
'isin':'∈','notin':'∉','ni':'∋','prod':'∏',
|
|
87
|
+
'sum':'∑','minus':'−','lowast':'∗','radic':'√',
|
|
88
|
+
'prop':'∝','infin':'∞','ang':'∠','and':'∧',
|
|
89
|
+
'or':'∨','cap':'∩','cup':'∪','int':'∫',
|
|
90
|
+
'there4':'∴','sim':'∼','cong':'≅','asymp':'≈',
|
|
91
|
+
'ne':'≠','equiv':'≡','le':'≤','ge':'≥',
|
|
92
|
+
'sub':'⊂','sup':'⊃','nsub':'⊄','sube':'⊆',
|
|
93
|
+
'supe':'⊇','oplus':'⊕','otimes':'⊗','perp':'⊥',
|
|
94
|
+
'sdot':'⋅','lceil':'⌈','rceil':'⌉','lfloor':'⌊',
|
|
95
|
+
'rfloor':'⌋','lang':'〈','rang':'〉','loz':'◊',
|
|
96
|
+
'spades':'♠','clubs':'♣','hearts':'♥','diams':'♦',
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
function _html_do_escape(s, quote) {
|
|
100
|
+
s = String(s).split('&').join('&').split('<').join('<').split('>').join('>');
|
|
101
|
+
if (quote) {
|
|
102
|
+
s = s.split('"').join('"').split("'").join(''');
|
|
103
|
+
}
|
|
104
|
+
return s;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function _html_do_unescape(s) {
|
|
108
|
+
return String(s).replace(/&(#[xX][0-9a-fA-F]+|#[0-9]+|[a-zA-Z][a-zA-Z0-9]*);/g, function(m, entity) {
|
|
109
|
+
if (entity.charAt(0) === '#') {
|
|
110
|
+
var e = entity.slice(1), code;
|
|
111
|
+
if (e.charAt(0) === 'x' || e.charAt(0) === 'X') {
|
|
112
|
+
code = parseInt(e.slice(1), 16);
|
|
113
|
+
} else {
|
|
114
|
+
code = parseInt(e, 10);
|
|
115
|
+
}
|
|
116
|
+
if (!isNaN(code)) {
|
|
117
|
+
return String.fromCodePoint ? String.fromCodePoint(code) : String.fromCharCode(code);
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
var ch = _html_named[entity];
|
|
121
|
+
if (ch !== undefined) return ch;
|
|
122
|
+
}
|
|
123
|
+
return m;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Regex-based tokeniser that drives HTMLParser.handle_* callbacks.
|
|
128
|
+
function _html_parser_feed(parser, data) {
|
|
129
|
+
var pos = 0;
|
|
130
|
+
var n = data.length;
|
|
131
|
+
|
|
132
|
+
while (pos < n) {
|
|
133
|
+
// Text run up to the next '<'
|
|
134
|
+
if (data[pos] !== '<') {
|
|
135
|
+
var nxt = data.indexOf('<', pos);
|
|
136
|
+
if (nxt < 0) nxt = n;
|
|
137
|
+
var text = data.slice(pos, nxt);
|
|
138
|
+
if (text) {
|
|
139
|
+
if (parser.convert_charrefs) text = _html_do_unescape(text);
|
|
140
|
+
parser.handle_data(text);
|
|
141
|
+
}
|
|
142
|
+
pos = nxt;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Comment: <!-- ... -->
|
|
147
|
+
if (data.slice(pos, pos + 4) === '<!--') {
|
|
148
|
+
var ce = data.indexOf('-->', pos + 4);
|
|
149
|
+
if (ce < 0) {
|
|
150
|
+
var rem = data.slice(pos);
|
|
151
|
+
parser.handle_data(parser.convert_charrefs ? _html_do_unescape(rem) : rem);
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
parser.handle_comment(data.slice(pos + 4, ce));
|
|
155
|
+
pos = ce + 3;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// CDATA section: <![CDATA[...]]>
|
|
160
|
+
if (data.slice(pos, pos + 9) === '<![CDATA[') {
|
|
161
|
+
var cd = data.indexOf(']]>', pos + 9);
|
|
162
|
+
if (cd < 0) { parser.handle_data(data.slice(pos)); break; }
|
|
163
|
+
parser.handle_data(data.slice(pos + 9, cd));
|
|
164
|
+
pos = cd + 3;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Declaration: <!...> (DOCTYPE, etc.)
|
|
169
|
+
if (data.slice(pos, pos + 2) === '<!' && pos + 2 < n && data[pos + 2] !== '-') {
|
|
170
|
+
var de = data.indexOf('>', pos + 2);
|
|
171
|
+
if (de < 0) { parser.handle_data(data.slice(pos)); break; }
|
|
172
|
+
parser.handle_decl(data.slice(pos + 2, de));
|
|
173
|
+
pos = de + 1;
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Processing instruction: <?...?>
|
|
178
|
+
if (data.slice(pos, pos + 2) === '<?') {
|
|
179
|
+
var pe = data.indexOf('?>', pos + 2);
|
|
180
|
+
if (pe < 0) { parser.handle_data(data.slice(pos)); break; }
|
|
181
|
+
parser.handle_pi(data.slice(pos + 2, pe));
|
|
182
|
+
pos = pe + 2;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// End tag: </tag>
|
|
187
|
+
if (data.slice(pos, pos + 2) === '</') {
|
|
188
|
+
var em = /^<\/([a-zA-Z][a-zA-Z0-9_:.-]*)[ \t\n\r\f]*>/.exec(data.slice(pos));
|
|
189
|
+
if (em) {
|
|
190
|
+
parser.handle_endtag(em[1].toLowerCase());
|
|
191
|
+
pos += em[0].length;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Start tag: <tag ...>
|
|
197
|
+
var sm = /^<([a-zA-Z][a-zA-Z0-9_:.-]*)/.exec(data.slice(pos));
|
|
198
|
+
if (sm) {
|
|
199
|
+
var tag_name = sm[1].toLowerCase();
|
|
200
|
+
var p = pos + sm[0].length;
|
|
201
|
+
var attrs = [];
|
|
202
|
+
var tag_done = false;
|
|
203
|
+
|
|
204
|
+
while (p < n) {
|
|
205
|
+
// skip whitespace
|
|
206
|
+
while (p < n && ' \t\n\r\f'.indexOf(data[p]) >= 0) p++;
|
|
207
|
+
if (p >= n) break;
|
|
208
|
+
|
|
209
|
+
if (data[p] === '>') { p++; break; }
|
|
210
|
+
|
|
211
|
+
// self-closing />
|
|
212
|
+
if (data[p] === '/' && p + 1 < n && data[p + 1] === '>') {
|
|
213
|
+
p += 2;
|
|
214
|
+
parser._starttag_text = data.slice(pos, p);
|
|
215
|
+
parser.handle_starttag(tag_name, attrs);
|
|
216
|
+
parser.handle_endtag(tag_name);
|
|
217
|
+
pos = p;
|
|
218
|
+
tag_done = true;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// attribute name
|
|
223
|
+
var anm = /^([^\s=\/>]+)/.exec(data.slice(p));
|
|
224
|
+
if (!anm) { p++; continue; }
|
|
225
|
+
var aname = anm[1];
|
|
226
|
+
p += anm[0].length;
|
|
227
|
+
|
|
228
|
+
// skip whitespace before optional '='
|
|
229
|
+
while (p < n && ' \t\n\r\f'.indexOf(data[p]) >= 0) p++;
|
|
230
|
+
|
|
231
|
+
var aval = null;
|
|
232
|
+
if (p < n && data[p] === '=') {
|
|
233
|
+
p++;
|
|
234
|
+
while (p < n && ' \t\n\r\f'.indexOf(data[p]) >= 0) p++;
|
|
235
|
+
if (p < n && (data[p] === '"' || data[p] === "'")) {
|
|
236
|
+
var q = data[p]; p++;
|
|
237
|
+
var qe = data.indexOf(q, p);
|
|
238
|
+
if (qe < 0) qe = n;
|
|
239
|
+
aval = data.slice(p, qe);
|
|
240
|
+
if (parser.convert_charrefs) aval = _html_do_unescape(aval);
|
|
241
|
+
p = qe + 1;
|
|
242
|
+
} else {
|
|
243
|
+
var uv = /^([^ \t\n\r\f>\/]+)/.exec(data.slice(p));
|
|
244
|
+
if (uv) {
|
|
245
|
+
aval = uv[1];
|
|
246
|
+
if (parser.convert_charrefs) aval = _html_do_unescape(aval);
|
|
247
|
+
p += uv[0].length;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
attrs.push([aname, aval]);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (!tag_done) {
|
|
255
|
+
parser._starttag_text = data.slice(pos, p);
|
|
256
|
+
parser.handle_starttag(tag_name, attrs);
|
|
257
|
+
pos = p;
|
|
258
|
+
}
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Unmatched '<': treat as literal data
|
|
263
|
+
parser.handle_data('<');
|
|
264
|
+
pos++;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
"""
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
# ---------------------------------------------------------------------------
|
|
271
|
+
# Public API
|
|
272
|
+
# ---------------------------------------------------------------------------
|
|
273
|
+
|
|
274
|
+
def escape(s, quote=True):
|
|
275
|
+
"""Escape special HTML characters in s.
|
|
276
|
+
|
|
277
|
+
Converts &, <, > to HTML-safe sequences.
|
|
278
|
+
If quote is True (default), also converts " to " and ' to '.
|
|
279
|
+
Returns the escaped string.
|
|
280
|
+
"""
|
|
281
|
+
return _html_do_escape(s, quote)
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def unescape(s):
|
|
285
|
+
"""Convert all named and numeric character references in s to Unicode characters.
|
|
286
|
+
|
|
287
|
+
Handles &name; named references, &#NNN; decimal references, and &#xHH; hex
|
|
288
|
+
references. Unknown named references are left intact.
|
|
289
|
+
"""
|
|
290
|
+
return _html_do_unescape(s)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class HTMLParser:
|
|
294
|
+
"""Minimal, event-driven HTML parser.
|
|
295
|
+
|
|
296
|
+
Subclass and override handle_* methods to process the parsed HTML.
|
|
297
|
+
|
|
298
|
+
Parameters:
|
|
299
|
+
convert_charrefs -- if True (default), character references in text data
|
|
300
|
+
and attribute values are automatically decoded to
|
|
301
|
+
Unicode before the handle_* callback is invoked.
|
|
302
|
+
|
|
303
|
+
Usage::
|
|
304
|
+
class MyParser(HTMLParser):
|
|
305
|
+
def handle_starttag(self, tag, attrs):
|
|
306
|
+
print('Start:', tag, attrs)
|
|
307
|
+
def handle_endtag(self, tag):
|
|
308
|
+
print('End:', tag)
|
|
309
|
+
def handle_data(self, data):
|
|
310
|
+
print('Data:', data)
|
|
311
|
+
p = MyParser()
|
|
312
|
+
p.feed('<a href="http://example.com">Click & go</a>')
|
|
313
|
+
"""
|
|
314
|
+
|
|
315
|
+
def __init__(self, convert_charrefs=True):
|
|
316
|
+
self.convert_charrefs = convert_charrefs
|
|
317
|
+
self._starttag_text = None
|
|
318
|
+
self.reset()
|
|
319
|
+
|
|
320
|
+
def reset(self):
|
|
321
|
+
"""Reset the parser state. Called implicitly by __init__."""
|
|
322
|
+
pass
|
|
323
|
+
|
|
324
|
+
def feed(self, data):
|
|
325
|
+
"""Feed a string of HTML to the parser. May be called repeatedly."""
|
|
326
|
+
_html_parser_feed(self, data)
|
|
327
|
+
|
|
328
|
+
def close(self):
|
|
329
|
+
"""Flush any remaining buffered data. Call when done feeding."""
|
|
330
|
+
pass
|
|
331
|
+
|
|
332
|
+
def get_starttag_text(self):
|
|
333
|
+
"""Return the raw text of the most recently opened start tag."""
|
|
334
|
+
return self._starttag_text
|
|
335
|
+
|
|
336
|
+
# ------------------------------------------------------------------
|
|
337
|
+
# Override these in subclasses
|
|
338
|
+
# ------------------------------------------------------------------
|
|
339
|
+
|
|
340
|
+
def handle_starttag(self, tag, attrs):
|
|
341
|
+
"""Handle an opening tag.
|
|
342
|
+
|
|
343
|
+
tag -- lowercase tag name
|
|
344
|
+
attrs -- list of [name, value] pairs; value is None for bare attributes
|
|
345
|
+
"""
|
|
346
|
+
pass
|
|
347
|
+
|
|
348
|
+
def handle_endtag(self, tag):
|
|
349
|
+
"""Handle a closing tag. tag is lowercase."""
|
|
350
|
+
pass
|
|
351
|
+
|
|
352
|
+
def handle_data(self, data):
|
|
353
|
+
"""Handle text content between tags."""
|
|
354
|
+
pass
|
|
355
|
+
|
|
356
|
+
def handle_comment(self, data):
|
|
357
|
+
"""Handle a comment (text inside <!-- ... -->)."""
|
|
358
|
+
pass
|
|
359
|
+
|
|
360
|
+
def handle_entityref(self, name):
|
|
361
|
+
"""Handle a named entity reference &name; (only when convert_charrefs=False)."""
|
|
362
|
+
pass
|
|
363
|
+
|
|
364
|
+
def handle_charref(self, name):
|
|
365
|
+
"""Handle a numeric character reference &#NNN; (only when convert_charrefs=False)."""
|
|
366
|
+
pass
|
|
367
|
+
|
|
368
|
+
def handle_decl(self, decl):
|
|
369
|
+
"""Handle a DOCTYPE or other declaration."""
|
|
370
|
+
pass
|
|
371
|
+
|
|
372
|
+
def handle_pi(self, data):
|
|
373
|
+
"""Handle a processing instruction."""
|
|
374
|
+
pass
|
|
375
|
+
|
|
376
|
+
def unknown_decl(self, data):
|
|
377
|
+
"""Handle an unrecognised declaration."""
|
|
378
|
+
pass
|
|
379
|
+
|
|
380
|
+
def error(self, message):
|
|
381
|
+
"""Raise a parse error."""
|
|
382
|
+
raise Exception(message)
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
###########################################################
|
|
2
|
+
# RapydScript Standard Library
|
|
3
|
+
# http — HTTP utilities
|
|
4
|
+
###########################################################
|
|
5
|
+
#
|
|
6
|
+
# Sub-modules:
|
|
7
|
+
# http.client — HTTP/HTTPS connections (HTTPConnection, HTTPSConnection)
|
|
8
|
+
# http.cookies — Cookie parsing and generation (SimpleCookie, Morsel)
|
|
9
|
+
#
|
|
10
|
+
# Top-level exports:
|
|
11
|
+
# HTTPStatus — HTTP status code constants
|
|
12
|
+
#
|
|
13
|
+
# Usage:
|
|
14
|
+
# from http import HTTPStatus
|
|
15
|
+
# from http.client import HTTPConnection, HTTPSConnection, HTTPException
|
|
16
|
+
# from http.cookies import SimpleCookie, CookieError
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class HTTPStatus:
|
|
20
|
+
"""HTTP status code constants.
|
|
21
|
+
|
|
22
|
+
Class attributes map symbolic names to integer status codes.
|
|
23
|
+
Each attribute value is the integer status code.
|
|
24
|
+
"""
|
|
25
|
+
# 1xx Informational
|
|
26
|
+
CONTINUE = 100
|
|
27
|
+
SWITCHING_PROTOCOLS = 101
|
|
28
|
+
PROCESSING = 102
|
|
29
|
+
EARLY_HINTS = 103
|
|
30
|
+
|
|
31
|
+
# 2xx Success
|
|
32
|
+
OK = 200
|
|
33
|
+
CREATED = 201
|
|
34
|
+
ACCEPTED = 202
|
|
35
|
+
NON_AUTHORITATIVE_INFORMATION = 203
|
|
36
|
+
NO_CONTENT = 204
|
|
37
|
+
RESET_CONTENT = 205
|
|
38
|
+
PARTIAL_CONTENT = 206
|
|
39
|
+
MULTI_STATUS = 207
|
|
40
|
+
ALREADY_REPORTED = 208
|
|
41
|
+
IM_USED = 226
|
|
42
|
+
|
|
43
|
+
# 3xx Redirection
|
|
44
|
+
MULTIPLE_CHOICES = 300
|
|
45
|
+
MOVED_PERMANENTLY = 301
|
|
46
|
+
FOUND = 302
|
|
47
|
+
SEE_OTHER = 303
|
|
48
|
+
NOT_MODIFIED = 304
|
|
49
|
+
USE_PROXY = 305
|
|
50
|
+
TEMPORARY_REDIRECT = 307
|
|
51
|
+
PERMANENT_REDIRECT = 308
|
|
52
|
+
|
|
53
|
+
# 4xx Client Error
|
|
54
|
+
BAD_REQUEST = 400
|
|
55
|
+
UNAUTHORIZED = 401
|
|
56
|
+
PAYMENT_REQUIRED = 402
|
|
57
|
+
FORBIDDEN = 403
|
|
58
|
+
NOT_FOUND = 404
|
|
59
|
+
METHOD_NOT_ALLOWED = 405
|
|
60
|
+
NOT_ACCEPTABLE = 406
|
|
61
|
+
PROXY_AUTHENTICATION_REQUIRED = 407
|
|
62
|
+
REQUEST_TIMEOUT = 408
|
|
63
|
+
CONFLICT = 409
|
|
64
|
+
GONE = 410
|
|
65
|
+
LENGTH_REQUIRED = 411
|
|
66
|
+
PRECONDITION_FAILED = 412
|
|
67
|
+
REQUEST_ENTITY_TOO_LARGE = 413
|
|
68
|
+
REQUEST_URI_TOO_LONG = 414
|
|
69
|
+
UNSUPPORTED_MEDIA_TYPE = 415
|
|
70
|
+
REQUESTED_RANGE_NOT_SATISFIABLE = 416
|
|
71
|
+
EXPECTATION_FAILED = 417
|
|
72
|
+
IM_A_TEAPOT = 418
|
|
73
|
+
MISDIRECTED_REQUEST = 421
|
|
74
|
+
UNPROCESSABLE_ENTITY = 422
|
|
75
|
+
LOCKED = 423
|
|
76
|
+
FAILED_DEPENDENCY = 424
|
|
77
|
+
TOO_EARLY = 425
|
|
78
|
+
UPGRADE_REQUIRED = 426
|
|
79
|
+
PRECONDITION_REQUIRED = 428
|
|
80
|
+
TOO_MANY_REQUESTS = 429
|
|
81
|
+
REQUEST_HEADER_FIELDS_TOO_LARGE = 431
|
|
82
|
+
UNAVAILABLE_FOR_LEGAL_REASONS = 451
|
|
83
|
+
|
|
84
|
+
# 5xx Server Error
|
|
85
|
+
INTERNAL_SERVER_ERROR = 500
|
|
86
|
+
NOT_IMPLEMENTED = 501
|
|
87
|
+
BAD_GATEWAY = 502
|
|
88
|
+
SERVICE_UNAVAILABLE = 503
|
|
89
|
+
GATEWAY_TIMEOUT = 504
|
|
90
|
+
HTTP_VERSION_NOT_SUPPORTED = 505
|
|
91
|
+
VARIANT_ALSO_NEGOTIATES = 506
|
|
92
|
+
INSUFFICIENT_STORAGE = 507
|
|
93
|
+
LOOP_DETECTED = 508
|
|
94
|
+
NOT_EXTENDED = 510
|
|
95
|
+
NETWORK_AUTHENTICATION_REQUIRED = 511
|
|
96
|
+
|
|
97
|
+
def __init__(self):
|
|
98
|
+
raise TypeError('HTTPStatus cannot be instantiated')
|