rapydscript-ns 0.9.4 → 0.9.5

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 CHANGED
@@ -1,3 +1,12 @@
1
+ version 0.9.5
2
+ =======================
3
+ * Added support for `__slots__` enforcement via JS Proxy (subclass merging, graceful fallback)
4
+ * Added support for exception `.args` property (all exception classes capture constructor arguments)
5
+ * Added support for dict `|` (merge) and `|=` (update) operators
6
+ * Added Python-style `repr()` formatting: single-quoted strings, `repr()` applied to container elements
7
+ * Added `interface extends` support in the language service TypeScript definition parser
8
+ * Fix: Improved type checking for bitwise and unary operators (raises `TypeError` for invalid types)
9
+
1
10
  version 0.9.4
2
11
  =======================
3
12
  * 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`)
package/PYTHON_GAPS.md CHANGED
@@ -77,17 +77,7 @@ when interoperating with JS APIs that return plain objects.
77
77
 
78
78
  ---
79
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
80
+ ### 1.5 Multiple Inheritance MRO
91
81
 
92
82
  **Python:** C3 linearization guarantees a deterministic and consistent method resolution order.
93
83
  **RapydScript:** Built on the JS prototype chain. In diamond inheritance or complex hierarchies
@@ -100,18 +90,7 @@ name. Hard to debug because no error is raised.
100
90
 
101
91
  ## 2. Missing Language Features
102
92
 
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
93
+ ### 2.1 `__del__` Destructor — No Guaranteed Finalizer
115
94
 
116
95
  `__del__` methods are not called reliably. JavaScript's GC is non-deterministic and provides
117
96
  no equivalent to CPython's reference-counting finalizer.
@@ -124,7 +103,7 @@ that timing is not guaranteed.
124
103
 
125
104
  ---
126
105
 
127
- ### 2.3 `locals()` Always Returns Empty Dict
106
+ ### 2.2 `locals()` Always Returns Empty Dict
128
107
 
129
108
  `vars()`, `locals()`, and `globals()` all exist as builtins. JavaScript provides no mechanism
130
109
  to introspect local variables at runtime, so `locals()` always returns an empty dict.
@@ -134,7 +113,7 @@ Python code that uses `locals()` for string template substitution
134
113
 
135
114
  ---
136
115
 
137
- ### 2.4 `from module import *` Not Allowed
116
+ ### 2.3 `from module import *` Not Allowed
138
117
 
139
118
  Star imports are intentionally unsupported to prevent namespace pollution. Python developers
140
119
  who rely on them (e.g., `from math import *`) must enumerate imports explicitly.
@@ -143,7 +122,7 @@ who rely on them (e.g., `from math import *`) must enumerate imports explicitly.
143
122
 
144
123
  ---
145
124
 
146
- ### 2.5 `asynccontextmanager` Not Available
125
+ ### 2.4 `asynccontextmanager` Not Available
147
126
 
148
127
  `contextlib.asynccontextmanager` is absent. Only synchronous `@contextmanager` is implemented.
149
128
  `async with` itself is also not supported — async context managers need `.acquire()`/`.release()`
@@ -151,7 +130,7 @@ calls instead.
151
130
 
152
131
  ---
153
132
 
154
- ### 2.6 f-string Debugging Format `f'{x=}'` Not Supported
133
+ ### 2.5 f-string Debugging Format `f'{x=}'` Not Supported
155
134
 
156
135
  Python 3.8+ supports `f'{x=}'` which expands to `f'x={repr(x)}'`. This is not implemented.
157
136
 
@@ -162,7 +141,7 @@ print(f'{x=}') # Python: "x=42". RapydScript: syntax error or wrong output
162
141
 
163
142
  ---
164
143
 
165
- ### 2.7 Ellipsis Evaluates to `undefined`
144
+ ### 2.6 Ellipsis Evaluates to `undefined`
166
145
 
167
146
  `...` (Ellipsis) parses as a valid expression but evaluates to JS `undefined` rather than
168
147
  Python's `Ellipsis` singleton object. Code that stores `...` in containers or checks
@@ -342,7 +321,6 @@ Priority weighs frequency-of-need, effort-to-implement, and whether a workaround
342
321
  | Priority | Feature | Effort | Impact |
343
322
  |---|---|---|---|
344
323
  | High | `enum.IntEnum`, `IntFlag`, `Flag` | Medium | Protocol and permission modeling; bitfield enums |
345
- | Medium | `__slots__` enforcement via `Proxy` | Medium | Memory and API documentation |
346
324
  | Medium | `hashlib` shim over Web Crypto | Medium | Avoids verbatim Web Crypto calls in user code |
347
325
  | Medium | `fractions` module | Medium | Exact rational arithmetic |
348
326
  | Medium | f-string `f'{x=}'` debugging format | Low | Developer experience |
package/README.md CHANGED
@@ -3312,16 +3312,26 @@ finally:
3312
3312
  cleanup()
3313
3313
  ```
3314
3314
 
3315
+ Like Python, exceptions accept variadic arguments stored in `.args`:
3316
+
3317
+ ```py
3318
+ e = ValueError('bad input', 42)
3319
+ print(e.args) # ['bad input', 42]
3320
+ print(e.args[0]) # 'bad input'
3321
+ print(e.message) # 'bad input' (first arg, for JS Error compatibility)
3322
+ ```
3323
+
3315
3324
  You can create your own Exception classes by inheriting from `Exception`, which
3316
3325
  is the JavaScript Error class, for more details on this, see the [MDN documentation](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Error).
3317
3326
 
3318
3327
  ```py
3319
3328
  class MyError(Exception):
3320
- def __init__(self, message):
3321
- self.name = 'MyError'
3322
- self.message = message
3329
+ def __init__(self, code, detail):
3330
+ Exception.__init__(self, code, detail)
3331
+ self.code = code
3332
+ self.detail = detail
3323
3333
 
3324
- raise MyError('This is a custom error!')
3334
+ raise MyError(404, 'not found')
3325
3335
  ```
3326
3336
 
3327
3337
  You can catch multiple exception types in one `except` clause. Both the comma form and the tuple form are supported:
@@ -4013,6 +4023,7 @@ Python Feature Coverage
4013
4023
  | `super()` — 0-arg and 2-arg forms | `super().method()` and `super(Cls, self).method()` both work |
4014
4024
  | `except TypeA, TypeB as e:` | RapydScript comma-separated form; catches multiple exception types |
4015
4025
  | `except (TypeA, TypeError) as e:` | Tuple form also supported |
4026
+ | `Exception.args` variadic constructor | `Exception('a', 'b').args == ['a', 'b']`; `.message` set to first arg for JS compatibility; works on all builtin and custom exception subclasses |
4016
4027
  | `except*` / `ExceptionGroup` (Python 3.11+) | Full support: `ExceptionGroup` class with `subgroup()`/`split()`; `except*` dispatches to typed handlers, re-raises unmatched; bare `except*:` catches all remaining |
4017
4028
  | `try / else` | `else` block runs only when no exception was raised |
4018
4029
  | `for / else` | `else` block runs when loop completes without `break`; nested break isolation works |
@@ -4158,7 +4169,6 @@ This restores the original RapydScript behavior: plain JS objects for `{}`, no o
4158
4169
 
4159
4170
  | Feature | Notes |
4160
4171
  |---------------------------------------|-----------------------------------------------------------------------------------------|
4161
- | `__slots__` enforcement | Accepted, but does not restrict attribute assignment |
4162
4172
  | `locals()` | Returns an empty `dict`. JS has no runtime mechanism for introspecting local variables. |
4163
4173
  | `input(prompt)` | There is no simple cli input in browser; use `prompt()` |
4164
4174
  | `compile()` | Python compile/code objects have no JS equivalent |
@@ -4226,7 +4236,7 @@ Features that exist in RapydScript but behave differently from standard Python:
4226
4236
  | `//` floor division on floats | `math.floor(a/b)` always | uses `Math.floor` - same result for well-behaved floats |
4227
4237
  | `%` on negative numbers | Result takes the sign of the divisor (`-7 % 3 == 2`) | Same as Python by default (via `python_modulo`, on by default). Disable with `from __python__ import no_python_modulo` to revert to raw JS remainder semantics. |
4228
4238
  | `global` / `nonlocal` scoping | Full cross-scope declaration | `global` works for module-level; if a variable exists in both an intermediate outer scope **and** the module-level scope, the outer scope takes precedence (differs from Python where `global` always forces module-level) |
4229
- | `Exception.message` | Not standard; use `.args[0]` | `.message` is the standard attribute (JS `Error` style) |
4239
+ | `Exception.message` | Not standard; use `.args[0]` | `.args` is populated (like Python); `.message` also set to first arg for JS `Error` compatibility |
4230
4240
  | Function call argument count | Too few args → `TypeError`; too many → `TypeError` | Too few args → extra params are `undefined`; too many → extras silently discarded. No `TypeError` is raised in either case. |
4231
4241
  | Positional-only param enforcement | Passing by keyword raises `TypeError` | Passing by keyword is silently ignored — the named arg is discarded and the parameter gets `undefined` (no error raised) |
4232
4242
  | Keyword-only param enforcement | Passing positionally raises `TypeError` | Passing positionally raises no error — the extra positional arg is silently discarded and the default value is used |
package/TODO.md CHANGED
@@ -1,9 +1,9 @@
1
1
 
2
-
3
2
  - remove repl_mode and make repl make a new context for each "run" press
4
3
 
5
4
  - vscode plugin based on language service?
6
5
 
7
6
 
8
- I would like you to add support for [python 7n style literal] to rapydscript. It should have the same syntax as the Python implementation, and be transpiled into equivalent javascript. Ensure with unit tests that it transpiles and the output JS runs correctly, and that the language service correctly handles it in parsed code. Make sure it works in the web-repl. Update the README if it has any outdated info about this, and the PYTHON_FEATURE_COVERAGE report. Add a simple example to the bottom of the TODO document using this feature (make no other changes to that file). Remove the suggestion from PYTHON_GAPS if it is there.
7
+ I would like you to add support for [python style __slots__ enforcement] to rapydscript. It should have the same syntax as the Python implementation, and be transpiled into equivalent javascript. Ensure with unit tests that it transpiles and the output JS runs correctly, and that the language service correctly handles it in parsed code. Make sure it works in the web-repl. Update the README if it has any outdated info about this, and the PYTHON_FEATURE_COVERAGE report. Add a simple example to the bottom of the TODO document using this feature (make no other changes to that file). Remove the suggestion from PYTHON_GAPS if it is there. Run the full unit test suite to check for regressions.
8
+
9
9