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.
@@ -1652,6 +1652,78 @@ function make_tests(Diagnostics, RS, STDLIB_MODULES) {
1652
1652
  },
1653
1653
  },
1654
1654
 
1655
+ // ── Exception.args ───────────────────────────────────────────────
1656
+ {
1657
+ name: "exception_args_no_errors",
1658
+ description: "Accessing .args on caught exception produces no diagnostics",
1659
+ run: function () {
1660
+ var markers = d().check([
1661
+ "try:",
1662
+ " raise ValueError('oops', 123)",
1663
+ "except ValueError as e:",
1664
+ " x = e.args",
1665
+ " y = e.args[0]",
1666
+ " z = len(e.args)",
1667
+ ].join("\n"));
1668
+ assert.deepStrictEqual(markers, [],
1669
+ "Expected no markers for exception .args access, got: " + JSON.stringify(markers));
1670
+ },
1671
+ },
1672
+ {
1673
+ name: "exception_args_custom_class_no_errors",
1674
+ description: "Custom exception class with variadic __init__ produces no diagnostics",
1675
+ run: function () {
1676
+ var markers = d().check([
1677
+ "class MyError(Exception):",
1678
+ " def __init__(self, code, detail):",
1679
+ " Exception.__init__(self, code, detail)",
1680
+ " self.code = code",
1681
+ "e = MyError(404, 'not found')",
1682
+ "x = e.args",
1683
+ ].join("\n"));
1684
+ assert.deepStrictEqual(markers, [],
1685
+ "Expected no markers for custom exception .args, got: " + JSON.stringify(markers));
1686
+ },
1687
+ },
1688
+
1689
+ // ── __slots__ ──────────────────────────────────────────────────────
1690
+ {
1691
+ name: "slots_no_errors",
1692
+ description: "Class with __slots__ produces no linter errors",
1693
+ run: function () {
1694
+ var markers = d().check([
1695
+ "class Point:",
1696
+ " __slots__ = ['x', 'y']",
1697
+ " def __init__(self, x, y):",
1698
+ " self.x = x",
1699
+ " self.y = y",
1700
+ "p = Point(1, 2)",
1701
+ ].join("\n"));
1702
+ assert.deepStrictEqual(markers, [],
1703
+ "Expected no markers for __slots__ class, got: " + JSON.stringify(markers));
1704
+ },
1705
+ },
1706
+ {
1707
+ name: "slots_subclass_no_errors",
1708
+ description: "Subclass with __slots__ produces no linter errors",
1709
+ run: function () {
1710
+ var markers = d().check([
1711
+ "class Base:",
1712
+ " __slots__ = ['x']",
1713
+ " def __init__(self):",
1714
+ " self.x = 1",
1715
+ "class Child(Base):",
1716
+ " __slots__ = ['y']",
1717
+ " def __init__(self):",
1718
+ " Base.__init__(self)",
1719
+ " self.y = 2",
1720
+ "c = Child()",
1721
+ ].join("\n"));
1722
+ assert.deepStrictEqual(markers, [],
1723
+ "Expected no markers for __slots__ subclass, got: " + JSON.stringify(markers));
1724
+ },
1725
+ },
1726
+
1655
1727
  ];
1656
1728
 
1657
1729
  return TESTS;
@@ -1379,7 +1379,7 @@ var TESTS = [
1379
1379
  var js = bundle_compile(repl, [
1380
1380
  "msg = 'hello'",
1381
1381
  "nums = [1, 2, 3]",
1382
- "assrt.equal(f'{msg=!r}', 'msg=\"hello\"')",
1382
+ "assrt.equal(f'{msg=!r}', \"msg='hello'\")",
1383
1383
  "assrt.equal(f'{nums=!r}', 'nums=[1, 2, 3]')",
1384
1384
  ].join("\n"));
1385
1385
  run_js(js);
@@ -4016,14 +4016,14 @@ var TESTS = [
4016
4016
  "assrt.equal(pformat(None), 'None')",
4017
4017
  "assrt.equal(pformat(True), 'True')",
4018
4018
  "assrt.equal(pformat(42), '42')",
4019
- "assrt.equal(pformat('hi'), '\"hi\"')",
4019
+ "assrt.equal(pformat('hi'), \"'hi'\")",
4020
4020
  // empty containers
4021
4021
  "assrt.equal(pformat([]), '[]')",
4022
4022
  "assrt.equal(pformat({}), '{}')",
4023
4023
  "assrt.equal(pformat(set()), 'set()')",
4024
4024
  // short containers fit on one line
4025
4025
  "assrt.equal(pformat([1, 2, 3]), '[1, 2, 3]')",
4026
- "assrt.equal(pformat({'a': 1, 'b': 2}), '{\"a\": 1, \"b\": 2}')",
4026
+ "assrt.equal(pformat({'a': 1, 'b': 2}), \"{'a': 1, 'b': 2}\")",
4027
4027
  "assrt.equal(pformat(frozenset([1])), 'frozenset({1})')",
4028
4028
  ].join("\n"));
4029
4029
  run_js(js);
@@ -4040,7 +4040,7 @@ var TESTS = [
4040
4040
  // wide list breaks one element per line
4041
4041
  "assrt.equal(pformat([1, 2, 3], width=5), '[1,\\n 2,\\n 3]')",
4042
4042
  // wide dict breaks, keys sorted by default
4043
- "assrt.equal(pformat({'name': 'Al', 'age': 3}, width=12), '{\"age\": 3,\\n \"name\": \"Al\"}')",
4043
+ "assrt.equal(pformat({'name': 'Al', 'age': 3}, width=12), \"{'age': 3,\\n 'name': 'Al'}\")",
4044
4044
  // indent parameter widens inner indentation
4045
4045
  "assrt.equal(pformat([1, 2, 3], width=5, indent=4), '[ 1,\\n 2,\\n 3]')",
4046
4046
  // single-element containers never break
@@ -4064,8 +4064,8 @@ var TESTS = [
4064
4064
  "d = dict()",
4065
4065
  "d.set('c', 1)",
4066
4066
  "d.set('a', 2)",
4067
- "assrt.equal(pformat(d, sort_dicts=False), '{\"c\": 1, \"a\": 2}')",
4068
- "assrt.equal(pformat(d, sort_dicts=True), '{\"a\": 2, \"c\": 1}')",
4067
+ "assrt.equal(pformat(d, sort_dicts=False), \"{'c': 1, 'a': 2}\")",
4068
+ "assrt.equal(pformat(d, sort_dicts=True), \"{'a': 2, 'c': 1}\")",
4069
4069
  // compact packs multiple items per line
4070
4070
  "compact_out = pformat([1, 2, 3, 4, 5, 6, 7, 8], compact=True, width=15)",
4071
4071
  "assrt.equal(compact_out, '[1, 2, 3, 4, 5,\\n 6, 7, 8]')",
@@ -4077,7 +4077,7 @@ var TESTS = [
4077
4077
  " self.parts.push(s)",
4078
4078
  "col = _C()",
4079
4079
  "pp(d, stream=col)",
4080
- "assrt.equal(col.parts.join(''), '{\"c\": 1, \"a\": 2}\\n')",
4080
+ "assrt.equal(col.parts.join(''), \"{'c': 1, 'a': 2}\\n\")",
4081
4081
  ].join("\n"));
4082
4082
  run_js(js);
4083
4083
  },
@@ -4092,7 +4092,7 @@ var TESTS = [
4092
4092
  "from pprint import saferepr, isreadable, isrecursive, PrettyPrinter",
4093
4093
  // saferepr of normal structures == single-line repr
4094
4094
  "assrt.equal(saferepr([1, 2, 3]), '[1, 2, 3]')",
4095
- "assrt.equal(saferepr({'a': 1}), '{\"a\": 1}')",
4095
+ "assrt.equal(saferepr({'a': 1}), \"{'a': 1}\")",
4096
4096
  // isreadable / isrecursive on plain structures
4097
4097
  "assrt.ok(isreadable([1, 2, 3]))",
4098
4098
  "assrt.ok(not isrecursive([1, 2, 3]))",
@@ -4598,6 +4598,31 @@ var TESTS = [
4598
4598
  },
4599
4599
  },
4600
4600
 
4601
+ // ── __slots__ ──────────────────────────────────────────────────────────
4602
+ {
4603
+ name: "slots_basic",
4604
+ description: "Basic __slots__ enforcement in web-repl bundle",
4605
+ run: function () {
4606
+ var repl = RS.web_repl();
4607
+ var js = bundle_compile(repl, [
4608
+ "class Point:",
4609
+ " __slots__ = ['x', 'y']",
4610
+ " def __init__(self, x, y):",
4611
+ " self.x = x",
4612
+ " self.y = y",
4613
+ "p = Point(1, 2)",
4614
+ "assrt.equal(p.x, 1)",
4615
+ "assrt.equal(p.y, 2)",
4616
+ "try:",
4617
+ " p.z = 3",
4618
+ " assrt.ok(False, 'should have raised')",
4619
+ "except AttributeError:",
4620
+ " assrt.ok(True)",
4621
+ ].join("\n"));
4622
+ run_js(js);
4623
+ },
4624
+ },
4625
+
4601
4626
  ];
4602
4627
 
4603
4628
  // ---------------------------------------------------------------------------
package/tools/utils.js CHANGED
@@ -33,11 +33,24 @@ function colored(string, color, bold) {
33
33
 
34
34
  function supports_color(stdout) {
35
35
  stdout = stdout || process.stdout;
36
- if (stdout && !stdout.isTTY) {
36
+
37
+ if (process.platform === 'win32') {
38
+ // MSYS2/MINGW/Git Bash/Cygwin: isTTY is unreliable, check TERM instead
39
+ if (/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i.test(process.env.TERM)) {
40
+ return true;
41
+ }
42
+ // Modern Windows terminals (Windows Terminal, VS Code, etc.)
43
+ if ('WT_SESSION' in process.env || process.env.TERM_PROGRAM === 'vscode' || 'COLORTERM' in process.env) {
44
+ return true;
45
+ }
46
+ // ConEmu / cmder
47
+ if (process.env.ConEmuANSI === 'ON') {
48
+ return true;
49
+ }
37
50
  return false;
38
51
  }
39
52
 
40
- if (process.platform === 'win32') {
53
+ if (stdout && !stdout.isTTY) {
41
54
  return false;
42
55
  }
43
56