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/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,31 @@
|
|
|
1
|
+
version 0.9.4
|
|
2
|
+
=======================
|
|
3
|
+
* Added the `statistics` standard library module (`mean`, `fmean`, `median`, `median_low`, `median_high`, `median_grouped`, `mode`, `multimode`, `stdev`, `pstdev`, `variance`, `pvariance`, `harmonic_mean`, `geometric_mean`, `quantiles`, `covariance`, `correlation`, `linear_regression`, `NormalDist`)
|
|
4
|
+
* Added the `pprint` standard library module (`pprint`, `pformat`, `PrettyPrinter`, `isreadable`, `isrecursive`, `saferepr`)
|
|
5
|
+
* Added `ChainMap` to the `collections` standard library module
|
|
6
|
+
* Added support for `bigint` literals and the `bigint()` builtin
|
|
7
|
+
* Fix: Added the `type` builtin to global scope
|
|
8
|
+
* Fix: Performance problem during long editor sessions in the language service
|
|
9
|
+
|
|
10
|
+
version 0.9.3
|
|
11
|
+
=======================
|
|
12
|
+
* Added the `bisect` standard library module (`bisect_left`, `bisect_right`, `bisect`, `insort_left`, `insort_right`, `insort`, optional `key` parameter)
|
|
13
|
+
* Added the `base64` standard library module
|
|
14
|
+
* Added the `string` standard library module (character constants, `Template`, `Formatter`)
|
|
15
|
+
* Added the `html` standard library module (`escape`, `unescape`, `HTMLParser`, etc.)
|
|
16
|
+
* Added the `asyncio` standard library module (`sleep()`, `gather()`, `create_task()`, etc.)
|
|
17
|
+
* Added the `urllib` standard library module
|
|
18
|
+
* Added the `http` standard library module (`HTTPStatus`, `HTTPConnection`, `HTTPSConnection`, `HTTPResponse`, `SimpleCookie`, `Morsel`, `CookieError`)
|
|
19
|
+
* Added the `csv` standard library module (`reader`, `writer`, `DictReader`, `DictWriter`, `Dialect`, `register_dialect`, QUOTE_* constants, etc.)
|
|
20
|
+
* Added the `textwrap` standard library module (`TextWrapper`, `wrap`, `fill`, `shorten`, `dedent`, `indent`)
|
|
21
|
+
* Added the `logging` standard library module (`getLogger`, `basicConfig`, `Logger`, `Handler`, `StreamHandler`, `Formatter`, `Filter`, level constants, etc.)
|
|
22
|
+
* Added the `heapq` standard library module (`heappush`, `heappop`, `heapify`, `heapreplace`, `heappushpop`, `nlargest`, `nsmallest`)
|
|
23
|
+
* Added support for parenthesized `with` statements: `with (A() as a, B() as b):` — multi-line and trailing comma supported
|
|
24
|
+
* Added support for async generators (`async def` with `yield`) and `async for` — compiles to JS `async function*` (wrapped) and `for await ... of`
|
|
25
|
+
* Added support for `float("inf")` and `float("-inf")`
|
|
26
|
+
* Added `long()` type and improved pretty-printing of `type()` return values
|
|
27
|
+
* Language service: bare imports now correctly provide type hints; infinite loop warning
|
|
28
|
+
|
|
1
29
|
version 0.9.2
|
|
2
30
|
=======================
|
|
3
31
|
* Added the contextlib standard library
|
package/PYTHON_GAPS.md
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
# RapydScript-NS: Python Compatibility Gaps & Browser-Friendly Additions
|
|
2
|
+
|
|
3
|
+
This document identifies features an experienced Python developer would expect that are missing
|
|
4
|
+
or behave differently in RapydScript-NS, with a focus on what is relevant and useful in a
|
|
5
|
+
browser context. Server-side features (file I/O, subprocesses, sockets, threading, etc.)
|
|
6
|
+
are excluded as they do not apply.
|
|
7
|
+
|
|
8
|
+
Items that are fully supported — even if only behind a flag — are not listed here. See the
|
|
9
|
+
README for the full feature and module support tables.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. Silent Behavioral Differences (Gotchas)
|
|
14
|
+
|
|
15
|
+
These features exist but behave differently from Python in ways that will silently produce
|
|
16
|
+
wrong results — no error is raised.
|
|
17
|
+
|
|
18
|
+
### 1.1 `is` / `is not` — Identity vs. Equality
|
|
19
|
+
|
|
20
|
+
**Python:** `is` tests object identity (pointer comparison).
|
|
21
|
+
**RapydScript:** `is` compiles to `===` (strict equality), so `x is y` is true whenever
|
|
22
|
+
`x === y`, including for equal primitive values that would be distinct Python objects.
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
a = 1000
|
|
26
|
+
b = 1000
|
|
27
|
+
a is b # False in Python (separate int objects)
|
|
28
|
+
# True in RapydScript (1000 === 1000)
|
|
29
|
+
```
|
|
30
|
+
**Impact:** Code that checks `obj is None` or `obj is sentinel_value` works correctly.
|
|
31
|
+
Code that expects `is` to return `False` for equal-but-distinct numeric values will be wrong.
|
|
32
|
+
|
|
33
|
+
**Note:** This is already documented in the README, but it is subtle and trips up experts.
|
|
34
|
+
The recommended pattern — using a unique sentinel object — works correctly.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
### 1.2 String Encoding — UTF-16 Surrogate Pairs
|
|
39
|
+
|
|
40
|
+
**Python:** Strings are sequences of Unicode code points (full 21-bit range).
|
|
41
|
+
**RapydScript:** Strings are JS strings — UTF-16. Emoji and other non-BMP characters
|
|
42
|
+
(U+10000–U+10FFFF) are represented as surrogate pairs and count as length 2.
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
s = '😀'
|
|
46
|
+
len(s) # 1 in Python, 2 in RapydScript
|
|
47
|
+
s[0] # '😀' in Python, '\uD83D' (broken surrogate) in RapydScript
|
|
48
|
+
```
|
|
49
|
+
**RapydScript provides:** `str.ulen()`, `str.uchrs()`, `str.uslice()` for code-point-aware
|
|
50
|
+
operations, but they must be used consciously.
|
|
51
|
+
|
|
52
|
+
**Impact:** Any code handling emoji, Asian CJK extension, or mathematical symbols may silently
|
|
53
|
+
produce wrong lengths or corrupt characters when sliced.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
### 1.3 `global` Scoping in Nested Functions
|
|
58
|
+
|
|
59
|
+
**Python:** `global x` inside a nested function forces `x` to refer to the module-level
|
|
60
|
+
variable, bypassing any intermediate closure scopes.
|
|
61
|
+
**RapydScript:** If a variable named `x` exists in an intermediate outer function scope,
|
|
62
|
+
that scope takes precedence over the module-level scope, even with `global x`.
|
|
63
|
+
|
|
64
|
+
**Impact:** Code with complex nested closures + `global` declarations may write to the wrong
|
|
65
|
+
scope silently.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
### 1.4 Numeric Dict Keys Are Coerced to Strings
|
|
70
|
+
|
|
71
|
+
**Python:** `d = {}; d[1] = 'a'; d['1'] = 'b'; len(d) == 2` (integer and string keys distinct).
|
|
72
|
+
**RapydScript:** The Python `dict` type (backed by ES6 `Map`) stores them distinctly, but
|
|
73
|
+
literal `{1: 'a', '1': 'b'}` and plain JS object interop may coerce integer keys to strings.
|
|
74
|
+
|
|
75
|
+
**Impact:** Code mixing numeric keys with the same string representation may produce collisions
|
|
76
|
+
when interoperating with JS APIs that return plain objects.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### 1.5 `Exception.args` vs `.message`
|
|
81
|
+
|
|
82
|
+
**Python:** `Exception('msg').args == ('msg',)` and `.message` is not a standard attribute.
|
|
83
|
+
**RapydScript:** `.message` is the primary attribute (JS `Error` convention). `.args` is
|
|
84
|
+
not populated as a tuple with the message.
|
|
85
|
+
|
|
86
|
+
**Impact:** Code accessing `.args[0]` to get the error message will get `undefined`.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### 1.6 Multiple Inheritance MRO
|
|
91
|
+
|
|
92
|
+
**Python:** C3 linearization guarantees a deterministic and consistent method resolution order.
|
|
93
|
+
**RapydScript:** Built on the JS prototype chain. In diamond inheritance or complex hierarchies
|
|
94
|
+
the order may differ from Python's C3 MRO.
|
|
95
|
+
|
|
96
|
+
**Impact:** Unexpected method is called when multiple parent classes define the same method
|
|
97
|
+
name. Hard to debug because no error is raised.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## 2. Missing Language Features
|
|
102
|
+
|
|
103
|
+
### 2.1 `__slots__` Not Enforced
|
|
104
|
+
|
|
105
|
+
`__slots__ = ['x', 'y']` is parsed and accepted but has no runtime effect — arbitrary
|
|
106
|
+
attributes can still be set on instances. No `AttributeError` is raised for assignments to
|
|
107
|
+
undeclared attributes.
|
|
108
|
+
|
|
109
|
+
**Browser relevance:** Used frequently for memory efficiency and API documentation. Enforcement
|
|
110
|
+
via `Object.seal()` or a `Proxy`-based guard would be possible in modern browsers.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
### 2.2 `__del__` Destructor — No Guaranteed Finalizer
|
|
115
|
+
|
|
116
|
+
`__del__` methods are not called reliably. JavaScript's GC is non-deterministic and provides
|
|
117
|
+
no equivalent to CPython's reference-counting finalizer.
|
|
118
|
+
|
|
119
|
+
**Browser relevance:** Low — most `__del__` usage is for file handles or network connections
|
|
120
|
+
that do not exist in the browser. However, the `FinalizationRegistry` API (available in all
|
|
121
|
+
modern browsers since 2021) could provide best-effort `__del__` support for cleanup of
|
|
122
|
+
external resources like WebGL buffers, WebSockets, etc. Worth adding with a clear caveat
|
|
123
|
+
that timing is not guaranteed.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### 2.3 `locals()` Always Returns Empty Dict
|
|
128
|
+
|
|
129
|
+
`vars()`, `locals()`, and `globals()` all exist as builtins. JavaScript provides no mechanism
|
|
130
|
+
to introspect local variables at runtime, so `locals()` always returns an empty dict.
|
|
131
|
+
`globals()` works on module-level/global state, and `vars(obj)` introspects the passed object.
|
|
132
|
+
Python code that uses `locals()` for string template substitution
|
|
133
|
+
(e.g., `'{x}'.format(**locals())`) will break silently.
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### 2.4 `from module import *` Not Allowed
|
|
138
|
+
|
|
139
|
+
Star imports are intentionally unsupported to prevent namespace pollution. Python developers
|
|
140
|
+
who rely on them (e.g., `from math import *`) must enumerate imports explicitly.
|
|
141
|
+
|
|
142
|
+
**Impact:** Not a behavioral difference, but a friction point when porting code.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### 2.5 `asynccontextmanager` Not Available
|
|
147
|
+
|
|
148
|
+
`contextlib.asynccontextmanager` is absent. Only synchronous `@contextmanager` is implemented.
|
|
149
|
+
`async with` itself is also not supported — async context managers need `.acquire()`/`.release()`
|
|
150
|
+
calls instead.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
### 2.6 f-string Debugging Format `f'{x=}'` Not Supported
|
|
155
|
+
|
|
156
|
+
Python 3.8+ supports `f'{x=}'` which expands to `f'x={repr(x)}'`. This is not implemented.
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
x = 42
|
|
160
|
+
print(f'{x=}') # Python: "x=42". RapydScript: syntax error or wrong output
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
### 2.7 Ellipsis Evaluates to `undefined`
|
|
166
|
+
|
|
167
|
+
`...` (Ellipsis) parses as a valid expression but evaluates to JS `undefined` rather than
|
|
168
|
+
Python's `Ellipsis` singleton object. Code that stores `...` in containers or checks
|
|
169
|
+
`x is Ellipsis` will behave incorrectly.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 3. Missing Standard Library Modules (Browser-Relevant)
|
|
174
|
+
|
|
175
|
+
These are absent from `src/lib/` and have no substitute.
|
|
176
|
+
|
|
177
|
+
### 3.1 `enum.IntEnum`, `IntFlag`, and `Flag`
|
|
178
|
+
|
|
179
|
+
The `enum` module provides `Enum` but not `IntEnum` (auto-comparable with integers),
|
|
180
|
+
`StrEnum` (Python 3.11+), `IntFlag`, or `Flag` (bitfield enums). These are common in protocol
|
|
181
|
+
implementations, permission systems, and state machines.
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
from enum import IntEnum
|
|
185
|
+
class Color(IntEnum):
|
|
186
|
+
RED = 1
|
|
187
|
+
GREEN = 2
|
|
188
|
+
Color.RED < Color.GREEN # True — comparison with int semantics
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
### 3.2 `hashlib` — Cryptographic Hashing
|
|
194
|
+
|
|
195
|
+
`hashlib.sha256`, `hashlib.md5`, etc. The Web Crypto API provides `crypto.subtle.digest`
|
|
196
|
+
but its async/buffer-based interface is awkward. A thin `hashlib`-compatible wrapper over
|
|
197
|
+
`crypto.subtle` with a synchronous-friendly API (using the sync `crypto.getRandomValues`)
|
|
198
|
+
for non-cryptographic hashes would be valuable.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
### 3.3 `fractions` — Rational Arithmetic
|
|
203
|
+
|
|
204
|
+
`Fraction(numerator, denominator)` with full arithmetic. Useful for music theory apps,
|
|
205
|
+
math tutoring tools, and any domain requiring exact rational computation.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
### 3.4 `difflib` — Sequence Comparison
|
|
210
|
+
|
|
211
|
+
`difflib.unified_diff`, `difflib.SequenceMatcher`, `difflib.get_close_matches`. Useful
|
|
212
|
+
for browser-based code editors, version comparison tools, and fuzzy matching UIs.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
### 3.5 `decimal` — Decimal Arithmetic
|
|
217
|
+
|
|
218
|
+
`Decimal` arithmetic avoids floating-point rounding errors. Essential for financial
|
|
219
|
+
calculations in browser apps (e-commerce, budgeting tools). JS does not have a built-in
|
|
220
|
+
equivalent; a pure-JS implementation would need to be compiled in.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 4. Tricky Patterns That Require Workarounds
|
|
225
|
+
|
|
226
|
+
These are not missing features but patterns that silently work differently or require
|
|
227
|
+
non-obvious syntax.
|
|
228
|
+
|
|
229
|
+
### 4.1 Python String Methods on String Literals
|
|
230
|
+
|
|
231
|
+
String literals in RapydScript do NOT have Python methods (`.strip()`, `.join()`, etc.)
|
|
232
|
+
available by default in all contexts. Using string methods requires:
|
|
233
|
+
|
|
234
|
+
- `from pythonize import strings; strings()` (patches `String.prototype` at runtime), or
|
|
235
|
+
- the `--pythonize-strings` compiler option, or
|
|
236
|
+
- calling `str.strip(s)` (module-level form) instead of `s.strip()`
|
|
237
|
+
|
|
238
|
+
**Impact:** The most common pattern in Python — `s.strip().split(',')` — will throw a
|
|
239
|
+
`TypeError` in some contexts without the above setup.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
### 4.2 Multi-line Anonymous Functions in Call Arguments
|
|
244
|
+
|
|
245
|
+
Multi-line `def` blocks cannot be used as inline arguments to function calls:
|
|
246
|
+
|
|
247
|
+
```python
|
|
248
|
+
# Does NOT compile correctly:
|
|
249
|
+
result = map(def(x):
|
|
250
|
+
return x * 2
|
|
251
|
+
, my_list)
|
|
252
|
+
|
|
253
|
+
# Must use a named helper:
|
|
254
|
+
def double(x):
|
|
255
|
+
return x * 2
|
|
256
|
+
result = map(double, my_list)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
### 4.3 JavaScript Reserved Words as Identifiers
|
|
262
|
+
|
|
263
|
+
All JavaScript reserved words are also forbidden in RapydScript. Common Python identifiers
|
|
264
|
+
that break: `default`, `delete`, `switch`, `case`, `break`, `var`, `void`, `typeof`,
|
|
265
|
+
`instanceof`. Also cannot be used as keyword argument names in function calls.
|
|
266
|
+
|
|
267
|
+
```python
|
|
268
|
+
def configure(default=None): # 'default' is reserved — compile error
|
|
269
|
+
...
|
|
270
|
+
# Must rename: def configure(dflt=None):
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
### 4.4 Class Named `Error` Shadows JS `Error`
|
|
276
|
+
|
|
277
|
+
Defining a class named `Error` (e.g., `class Error(Exception)`) compiles to a JS function
|
|
278
|
+
that shadows the global `JS Error` constructor. If that class is then imported in another
|
|
279
|
+
module context (e.g., the web REPL), the import line `var Error = ρσ_modules.mymod.Error`
|
|
280
|
+
shadows the native `Error`, causing infinite recursion in `Exception.__init__`.
|
|
281
|
+
|
|
282
|
+
**Workaround:** Never name a RapydScript class `Error`. Use `MyError`, `AppError`,
|
|
283
|
+
`ValueError` (which is already defined in baselib), etc.
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
### 4.5 `Cls.method(arg)` vs `@Cls.method`
|
|
288
|
+
|
|
289
|
+
`Cls.method(arg)` compiles to `Cls.prototype.method.call(arg)` (unbound Python 2 style).
|
|
290
|
+
`@Cls.method` as a decorator stores the constructor property and calls it differently.
|
|
291
|
+
These are different lookup paths. A method that must work both as a decorator and as a
|
|
292
|
+
direct class call needs to be installed on both `cls.property` and `cls.prototype.property`.
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
### 4.6 `range` Cannot Be Shadowed as a Parameter Name
|
|
297
|
+
|
|
298
|
+
```python
|
|
299
|
+
def histogram(data, range): # compile/runtime error — range shadows builtin
|
|
300
|
+
...
|
|
301
|
+
# Must rename: def histogram(data, data_range):
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
This extends to other builtins: prefer prefixed parameter names when a parameter naturally
|
|
305
|
+
matches a builtin name.
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
### 4.7 Verbatim Blocks Are Truly Verbatim — No Escape Processing
|
|
310
|
+
|
|
311
|
+
Inside `v'...'` blocks, Python escape sequences are NOT processed. `\n` in a v-block
|
|
312
|
+
becomes a literal backslash-n in the JS output, not a newline.
|
|
313
|
+
|
|
314
|
+
```python
|
|
315
|
+
# Wrong — \n is not a newline in the regex:
|
|
316
|
+
pat = v'/foo\nbar/'
|
|
317
|
+
|
|
318
|
+
# Right — write the exact JS you want:
|
|
319
|
+
pat = v'/foo\nbar/' # only works as a real newline if you have a literal newline
|
|
320
|
+
```
|
|
321
|
+
For regex literals, write exactly the JS you want. Double-escaping (`\\n`) produces `\\n`
|
|
322
|
+
in JS (two characters), not a newline.
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
### 4.8 `jstype(x) is 'number'` for `typeof` Checks
|
|
327
|
+
|
|
328
|
+
Python's `type(x)` does not return a string. For JS-style `typeof` checks:
|
|
329
|
+
|
|
330
|
+
```python
|
|
331
|
+
jstype(x) is 'number' # correct
|
|
332
|
+
type(x) is int # also works for pure RS objects
|
|
333
|
+
```
|
|
334
|
+
The `jstype()` builtin is the RS equivalent of JS's `typeof`.
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## 5. Summary Priority Table
|
|
339
|
+
|
|
340
|
+
Priority weighs frequency-of-need, effort-to-implement, and whether a workaround exists.
|
|
341
|
+
|
|
342
|
+
| Priority | Feature | Effort | Impact |
|
|
343
|
+
|---|---|---|---|
|
|
344
|
+
| High | `enum.IntEnum`, `IntFlag`, `Flag` | Medium | Protocol and permission modeling; bitfield enums |
|
|
345
|
+
| Medium | `__slots__` enforcement via `Proxy` | Medium | Memory and API documentation |
|
|
346
|
+
| Medium | `hashlib` shim over Web Crypto | Medium | Avoids verbatim Web Crypto calls in user code |
|
|
347
|
+
| Medium | `fractions` module | Medium | Exact rational arithmetic |
|
|
348
|
+
| Medium | f-string `f'{x=}'` debugging format | Low | Developer experience |
|
|
349
|
+
| Low | `asynccontextmanager` + `async with` | Medium | Async resource management |
|
|
350
|
+
| Low | `__del__` via `FinalizationRegistry` | Medium | Resource cleanup (best-effort) |
|
|
351
|
+
| Low | `difflib` module | High | Text diff, fuzzy matching |
|
|
352
|
+
| Low | `decimal` module | High | Financial calculations |
|