python2ts 1.2.0 → 1.3.0
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.
|
@@ -214,7 +214,48 @@ var PYTHON_TO_JS_NAMES = {
|
|
|
214
214
|
// core module
|
|
215
215
|
// ============================================================================
|
|
216
216
|
floordiv: "floorDiv",
|
|
217
|
-
divmod: "divMod"
|
|
217
|
+
divmod: "divMod",
|
|
218
|
+
// ============================================================================
|
|
219
|
+
// hashlib module
|
|
220
|
+
// ============================================================================
|
|
221
|
+
pbkdf2_hmac: "pbkdf2Hmac",
|
|
222
|
+
compare_digest: "compareDigest",
|
|
223
|
+
file_digest: "fileDigest",
|
|
224
|
+
new: "newHash",
|
|
225
|
+
// ============================================================================
|
|
226
|
+
// pathlib module (Path methods)
|
|
227
|
+
// ============================================================================
|
|
228
|
+
read_text: "readText",
|
|
229
|
+
write_text: "writeText",
|
|
230
|
+
read_bytes: "readBytes",
|
|
231
|
+
write_bytes: "writeBytes",
|
|
232
|
+
is_file: "isFile",
|
|
233
|
+
is_dir: "isDir",
|
|
234
|
+
is_symlink: "isSymlink",
|
|
235
|
+
symlink_to: "symlinkTo",
|
|
236
|
+
link_to: "linkTo",
|
|
237
|
+
// ============================================================================
|
|
238
|
+
// shutil module
|
|
239
|
+
// ============================================================================
|
|
240
|
+
copy2: "copy2",
|
|
241
|
+
copytree: "copytree",
|
|
242
|
+
rmtree: "rmtree",
|
|
243
|
+
disk_usage: "diskUsage",
|
|
244
|
+
copymode: "copyMode",
|
|
245
|
+
copystat: "copyStat",
|
|
246
|
+
copyfile: "copyFile",
|
|
247
|
+
get_terminal_size: "getTerminalSize",
|
|
248
|
+
// ============================================================================
|
|
249
|
+
// tempfile module
|
|
250
|
+
// ============================================================================
|
|
251
|
+
mkstemp: "mkstemp",
|
|
252
|
+
mkdtemp: "mkdtemp",
|
|
253
|
+
gettempdir: "getTempDir",
|
|
254
|
+
// ============================================================================
|
|
255
|
+
// glob module
|
|
256
|
+
// ============================================================================
|
|
257
|
+
iglob: "iglob",
|
|
258
|
+
rglob: "rglob"
|
|
218
259
|
};
|
|
219
260
|
function toJsName(pythonName) {
|
|
220
261
|
return PYTHON_TO_JS_NAMES[pythonName] ?? pythonName;
|
|
@@ -412,7 +453,7 @@ function transformPythonType(node, ctx) {
|
|
|
412
453
|
}
|
|
413
454
|
}
|
|
414
455
|
function extractTypeAnnotation(typeDef, ctx) {
|
|
415
|
-
if (
|
|
456
|
+
if (typeDef?.name !== "TypeDef") return null;
|
|
416
457
|
const children = getChildren(typeDef);
|
|
417
458
|
const typeNode = children.find((c) => c.name !== ":" && c.name !== "->");
|
|
418
459
|
if (typeNode) {
|
|
@@ -422,7 +463,7 @@ function extractTypeAnnotation(typeDef, ctx) {
|
|
|
422
463
|
}
|
|
423
464
|
function extractTypeModifiers(typeDef, ctx) {
|
|
424
465
|
const result = { isFinal: false, isClassVar: false };
|
|
425
|
-
if (
|
|
466
|
+
if (typeDef?.name !== "TypeDef") return result;
|
|
426
467
|
const children = getChildren(typeDef);
|
|
427
468
|
const typeNode = children.find((c) => c.name !== ":" && c.name !== "->");
|
|
428
469
|
if (!typeNode) return result;
|
|
@@ -478,7 +519,7 @@ function isDocstringNode(node, ctx) {
|
|
|
478
519
|
if (node.name !== "ExpressionStatement") return false;
|
|
479
520
|
const children = getChildren(node);
|
|
480
521
|
const firstChild = children[0];
|
|
481
|
-
if (
|
|
522
|
+
if (firstChild?.name !== "String") return false;
|
|
482
523
|
const text = getNodeText(firstChild, ctx.source);
|
|
483
524
|
return text.startsWith('"""') || text.startsWith("'''");
|
|
484
525
|
}
|
|
@@ -561,7 +602,7 @@ function parseDocstring(content) {
|
|
|
561
602
|
descriptionLines.push(trimmed);
|
|
562
603
|
break;
|
|
563
604
|
case "params": {
|
|
564
|
-
const googleMatch =
|
|
605
|
+
const googleMatch = /^(\w+)\s*(?:\([^)]*\))?\s*:\s*(.*)$/.exec(trimmed);
|
|
565
606
|
if (googleMatch) {
|
|
566
607
|
flushParam();
|
|
567
608
|
currentParamName = googleMatch[1] ?? "";
|
|
@@ -589,7 +630,7 @@ function parseDocstring(content) {
|
|
|
589
630
|
break;
|
|
590
631
|
}
|
|
591
632
|
case "throws": {
|
|
592
|
-
const throwsMatch =
|
|
633
|
+
const throwsMatch = /^(\w+)\s*:\s*(.*)$/.exec(trimmed);
|
|
593
634
|
if (throwsMatch) {
|
|
594
635
|
flushThrows();
|
|
595
636
|
currentThrowsType = throwsMatch[1] ?? "Error";
|
|
@@ -1043,7 +1084,7 @@ function isChainedComparison(node) {
|
|
|
1043
1084
|
if (node.name !== "BinaryExpression") return false;
|
|
1044
1085
|
const children = getChildren(node);
|
|
1045
1086
|
const op = children[1];
|
|
1046
|
-
if (
|
|
1087
|
+
if (op?.name !== "CompareOp") return false;
|
|
1047
1088
|
return true;
|
|
1048
1089
|
}
|
|
1049
1090
|
function extractRightOperand(node, ctx) {
|
|
@@ -1435,6 +1476,52 @@ function transformCallExpression(node, ctx) {
|
|
|
1435
1476
|
case "capwords":
|
|
1436
1477
|
ctx.usesRuntime.add("string/capWords");
|
|
1437
1478
|
return `capWords(${args})`;
|
|
1479
|
+
// glob module - async functions (direct import)
|
|
1480
|
+
case "glob":
|
|
1481
|
+
ctx.usesRuntime.add("glob/glob");
|
|
1482
|
+
return `await glob(${args})`;
|
|
1483
|
+
case "iglob":
|
|
1484
|
+
ctx.usesRuntime.add("glob/iglob");
|
|
1485
|
+
return `await iglob(${args})`;
|
|
1486
|
+
case "rglob":
|
|
1487
|
+
ctx.usesRuntime.add("glob/rglob");
|
|
1488
|
+
return `await rglob(${args})`;
|
|
1489
|
+
// shutil module - async functions (direct import)
|
|
1490
|
+
case "copy":
|
|
1491
|
+
ctx.usesRuntime.add("shutil/copy");
|
|
1492
|
+
return `await copy(${args})`;
|
|
1493
|
+
case "copy2":
|
|
1494
|
+
ctx.usesRuntime.add("shutil/copy2");
|
|
1495
|
+
return `await copy2(${args})`;
|
|
1496
|
+
case "copytree":
|
|
1497
|
+
ctx.usesRuntime.add("shutil/copytree");
|
|
1498
|
+
return `await copytree(${args})`;
|
|
1499
|
+
case "move":
|
|
1500
|
+
ctx.usesRuntime.add("shutil/move");
|
|
1501
|
+
return `await move(${args})`;
|
|
1502
|
+
case "rmtree":
|
|
1503
|
+
ctx.usesRuntime.add("shutil/rmtree");
|
|
1504
|
+
return `await rmtree(${args})`;
|
|
1505
|
+
case "which":
|
|
1506
|
+
ctx.usesRuntime.add("shutil/which");
|
|
1507
|
+
return `await which(${args})`;
|
|
1508
|
+
// tempfile module - async functions (direct import)
|
|
1509
|
+
case "mkstemp":
|
|
1510
|
+
ctx.usesRuntime.add("tempfile/mkstemp");
|
|
1511
|
+
return `await mkstemp(${args})`;
|
|
1512
|
+
case "mkdtemp":
|
|
1513
|
+
ctx.usesRuntime.add("tempfile/mkdtemp");
|
|
1514
|
+
return `await mkdtemp(${args})`;
|
|
1515
|
+
case "NamedTemporaryFile":
|
|
1516
|
+
ctx.usesRuntime.add("tempfile/NamedTemporaryFile");
|
|
1517
|
+
return `await NamedTemporaryFile.create(${args})`;
|
|
1518
|
+
case "TemporaryDirectory":
|
|
1519
|
+
ctx.usesRuntime.add("tempfile/TemporaryDirectory");
|
|
1520
|
+
return `await TemporaryDirectory.create(${args})`;
|
|
1521
|
+
// pathlib module
|
|
1522
|
+
case "Path":
|
|
1523
|
+
ctx.usesRuntime.add("pathlib/Path");
|
|
1524
|
+
return `new Path(${args})`;
|
|
1438
1525
|
/* v8 ignore next 3 -- pass-through for user-defined functions @preserve */
|
|
1439
1526
|
default:
|
|
1440
1527
|
return `${transformNode(callee, ctx)}(${args})`;
|
|
@@ -1453,9 +1540,10 @@ function transformModuleCall(calleeName, args, ctx) {
|
|
|
1453
1540
|
inf: "inf",
|
|
1454
1541
|
nan: "nan"
|
|
1455
1542
|
};
|
|
1456
|
-
|
|
1543
|
+
const mathConstant = mathConstants[funcName];
|
|
1544
|
+
if (mathConstant !== void 0) {
|
|
1457
1545
|
ctx.usesRuntime.add(`math/${funcName}`);
|
|
1458
|
-
return
|
|
1546
|
+
return mathConstant;
|
|
1459
1547
|
}
|
|
1460
1548
|
ctx.usesRuntime.add(`math/${funcName}`);
|
|
1461
1549
|
return `${funcName}(${args})`;
|
|
@@ -1470,14 +1558,45 @@ function transformModuleCall(calleeName, args, ctx) {
|
|
|
1470
1558
|
return `${funcName}(${args})`;
|
|
1471
1559
|
}
|
|
1472
1560
|
if (moduleName === "os") {
|
|
1561
|
+
const asyncPathFuncs = [
|
|
1562
|
+
"exists",
|
|
1563
|
+
"isfile",
|
|
1564
|
+
"isdir",
|
|
1565
|
+
"islink",
|
|
1566
|
+
"realpath",
|
|
1567
|
+
"getsize",
|
|
1568
|
+
"getmtime",
|
|
1569
|
+
"getatime",
|
|
1570
|
+
"getctime"
|
|
1571
|
+
];
|
|
1572
|
+
const asyncOsFuncs = [
|
|
1573
|
+
"listdir",
|
|
1574
|
+
"mkdir",
|
|
1575
|
+
"makedirs",
|
|
1576
|
+
"remove",
|
|
1577
|
+
"unlink",
|
|
1578
|
+
"rmdir",
|
|
1579
|
+
"removedirs",
|
|
1580
|
+
"rename",
|
|
1581
|
+
"renames",
|
|
1582
|
+
"replace",
|
|
1583
|
+
"walk",
|
|
1584
|
+
"stat"
|
|
1585
|
+
];
|
|
1473
1586
|
if (funcName.startsWith("path.")) {
|
|
1474
1587
|
const pathFuncName = funcName.slice(5);
|
|
1475
1588
|
const jsPathFunc = toJsName(pathFuncName);
|
|
1476
1589
|
ctx.usesRuntime.add("os/path");
|
|
1590
|
+
if (asyncPathFuncs.includes(pathFuncName.toLowerCase())) {
|
|
1591
|
+
return `await path.${jsPathFunc}(${args})`;
|
|
1592
|
+
}
|
|
1477
1593
|
return `path.${jsPathFunc}(${args})`;
|
|
1478
1594
|
}
|
|
1479
1595
|
const jsName = toJsName(funcName);
|
|
1480
1596
|
ctx.usesRuntime.add(`os/${jsName}`);
|
|
1597
|
+
if (asyncOsFuncs.includes(funcName.toLowerCase())) {
|
|
1598
|
+
return `await ${jsName}(${args})`;
|
|
1599
|
+
}
|
|
1481
1600
|
return `${jsName}(${args})`;
|
|
1482
1601
|
}
|
|
1483
1602
|
if (moduleName === "datetime") {
|
|
@@ -1518,6 +1637,67 @@ function transformModuleCall(calleeName, args, ctx) {
|
|
|
1518
1637
|
}
|
|
1519
1638
|
return `${funcName}(${args})`;
|
|
1520
1639
|
}
|
|
1640
|
+
if (moduleName === "hashlib") {
|
|
1641
|
+
const jsName = toJsName(funcName);
|
|
1642
|
+
ctx.usesRuntime.add(`hashlib/${jsName}`);
|
|
1643
|
+
if (["pbkdf2_hmac", "scrypt", "compare_digest", "file_digest"].includes(funcName)) {
|
|
1644
|
+
const asyncJsName = toJsName(funcName);
|
|
1645
|
+
return `await ${asyncJsName}(${args})`;
|
|
1646
|
+
}
|
|
1647
|
+
return `${jsName}(${args})`;
|
|
1648
|
+
}
|
|
1649
|
+
if (moduleName === "shutil") {
|
|
1650
|
+
const asyncShutilFuncs = [
|
|
1651
|
+
"copy",
|
|
1652
|
+
"copy2",
|
|
1653
|
+
"copytree",
|
|
1654
|
+
"move",
|
|
1655
|
+
"rmtree",
|
|
1656
|
+
"which",
|
|
1657
|
+
"disk_usage",
|
|
1658
|
+
"copymode",
|
|
1659
|
+
"copystat",
|
|
1660
|
+
"copyfile"
|
|
1661
|
+
];
|
|
1662
|
+
const jsName = toJsName(funcName);
|
|
1663
|
+
ctx.usesRuntime.add(`shutil/${jsName}`);
|
|
1664
|
+
if (asyncShutilFuncs.includes(funcName.toLowerCase())) {
|
|
1665
|
+
return `await ${jsName}(${args})`;
|
|
1666
|
+
}
|
|
1667
|
+
return `${jsName}(${args})`;
|
|
1668
|
+
}
|
|
1669
|
+
if (moduleName === "glob") {
|
|
1670
|
+
const asyncGlobFuncs = ["glob", "iglob", "rglob"];
|
|
1671
|
+
const jsName = toJsName(funcName);
|
|
1672
|
+
ctx.usesRuntime.add(`glob/${jsName}`);
|
|
1673
|
+
if (asyncGlobFuncs.includes(funcName.toLowerCase())) {
|
|
1674
|
+
return `await ${jsName}(${args})`;
|
|
1675
|
+
}
|
|
1676
|
+
return `${jsName}(${args})`;
|
|
1677
|
+
}
|
|
1678
|
+
if (moduleName === "tempfile") {
|
|
1679
|
+
const asyncTempfileFuncs = ["mkstemp", "mkdtemp"];
|
|
1680
|
+
const jsName = toJsName(funcName);
|
|
1681
|
+
ctx.usesRuntime.add(`tempfile/${jsName}`);
|
|
1682
|
+
if (funcName === "NamedTemporaryFile") {
|
|
1683
|
+
return `await NamedTemporaryFile.create(${args})`;
|
|
1684
|
+
}
|
|
1685
|
+
if (funcName === "TemporaryDirectory") {
|
|
1686
|
+
return `await TemporaryDirectory.create(${args})`;
|
|
1687
|
+
}
|
|
1688
|
+
if (asyncTempfileFuncs.includes(funcName.toLowerCase())) {
|
|
1689
|
+
return `await ${jsName}(${args})`;
|
|
1690
|
+
}
|
|
1691
|
+
return `${jsName}(${args})`;
|
|
1692
|
+
}
|
|
1693
|
+
if (moduleName === "pathlib") {
|
|
1694
|
+
const jsName = toJsName(funcName);
|
|
1695
|
+
ctx.usesRuntime.add(`pathlib/${jsName}`);
|
|
1696
|
+
if (funcName === "Path") {
|
|
1697
|
+
return `new Path(${args})`;
|
|
1698
|
+
}
|
|
1699
|
+
return `${jsName}(${args})`;
|
|
1700
|
+
}
|
|
1521
1701
|
return null;
|
|
1522
1702
|
}
|
|
1523
1703
|
function transformMethodCall(callee, args, ctx) {
|
|
@@ -1529,6 +1709,29 @@ function transformMethodCall(callee, args, ctx) {
|
|
|
1529
1709
|
if (obj.name === "MemberExpression") {
|
|
1530
1710
|
return null;
|
|
1531
1711
|
}
|
|
1712
|
+
if (obj.name === "VariableName") {
|
|
1713
|
+
const objName = getNodeText(obj, ctx.source);
|
|
1714
|
+
const knownModules = [
|
|
1715
|
+
"shutil",
|
|
1716
|
+
"glob",
|
|
1717
|
+
"tempfile",
|
|
1718
|
+
"pathlib",
|
|
1719
|
+
"os",
|
|
1720
|
+
"math",
|
|
1721
|
+
"random",
|
|
1722
|
+
"json",
|
|
1723
|
+
"datetime",
|
|
1724
|
+
"re",
|
|
1725
|
+
"string",
|
|
1726
|
+
"functools",
|
|
1727
|
+
"itertools",
|
|
1728
|
+
"collections",
|
|
1729
|
+
"hashlib"
|
|
1730
|
+
];
|
|
1731
|
+
if (knownModules.includes(objName)) {
|
|
1732
|
+
return null;
|
|
1733
|
+
}
|
|
1734
|
+
}
|
|
1532
1735
|
const objCode = transformNode(obj, ctx);
|
|
1533
1736
|
const methodName = getNodeText(methodNode, ctx.source);
|
|
1534
1737
|
switch (methodName) {
|
|
@@ -1687,6 +1890,26 @@ function transformMethodCall(callee, args, ctx) {
|
|
|
1687
1890
|
case "issuperset":
|
|
1688
1891
|
ctx.usesRuntime.add("set");
|
|
1689
1892
|
return `set.issuperset(${objCode}, ${args})`;
|
|
1893
|
+
// Hash object methods (hashlib) - async
|
|
1894
|
+
case "digest":
|
|
1895
|
+
return `await ${objCode}.digest()`;
|
|
1896
|
+
case "hexdigest":
|
|
1897
|
+
return `await ${objCode}.hexdigest()`;
|
|
1898
|
+
// Path object methods (pathlib) - async
|
|
1899
|
+
// Only handle snake_case methods that are unique to Path
|
|
1900
|
+
case "is_file":
|
|
1901
|
+
case "is_dir":
|
|
1902
|
+
case "is_symlink":
|
|
1903
|
+
case "read_text":
|
|
1904
|
+
case "write_text":
|
|
1905
|
+
case "read_bytes":
|
|
1906
|
+
case "write_bytes":
|
|
1907
|
+
case "symlink_to":
|
|
1908
|
+
case "link_to":
|
|
1909
|
+
case "iterdir": {
|
|
1910
|
+
const jsMethod = toJsName(methodName);
|
|
1911
|
+
return `await ${objCode}.${jsMethod}(${args})`;
|
|
1912
|
+
}
|
|
1690
1913
|
/* v8 ignore next 2 -- unknown method, let caller handle @preserve */
|
|
1691
1914
|
default:
|
|
1692
1915
|
return null;
|
|
@@ -1734,7 +1957,7 @@ function transformArgList(node, ctx) {
|
|
|
1734
1957
|
}
|
|
1735
1958
|
if (item.name === "VariableName") {
|
|
1736
1959
|
const nextItem = items[i + 1];
|
|
1737
|
-
if (nextItem
|
|
1960
|
+
if (nextItem?.name === "AssignOp") {
|
|
1738
1961
|
const valueItem = items[i + 2];
|
|
1739
1962
|
if (valueItem) {
|
|
1740
1963
|
const name = getNodeText(item, ctx.source);
|
|
@@ -1998,8 +2221,8 @@ function transformMatchStatement(node, ctx) {
|
|
|
1998
2221
|
if (child.name === "match" || child.name === ":") continue;
|
|
1999
2222
|
if (child.name === "MatchBody") {
|
|
2000
2223
|
matchBody = child;
|
|
2001
|
-
} else
|
|
2002
|
-
subject
|
|
2224
|
+
} else {
|
|
2225
|
+
subject ??= child;
|
|
2003
2226
|
}
|
|
2004
2227
|
}
|
|
2005
2228
|
if (!subject || !matchBody) return getNodeText(node, ctx.source);
|
|
@@ -2049,8 +2272,8 @@ function transformMatchAsIfElse(subjectCode, clauses, ctx) {
|
|
|
2049
2272
|
body = child;
|
|
2050
2273
|
} else if (child.name === "Guard") {
|
|
2051
2274
|
guard = child;
|
|
2052
|
-
} else
|
|
2053
|
-
pattern
|
|
2275
|
+
} else {
|
|
2276
|
+
pattern ??= child;
|
|
2054
2277
|
}
|
|
2055
2278
|
}
|
|
2056
2279
|
if (!pattern || !body) continue;
|
|
@@ -2276,8 +2499,8 @@ function transformMatchClause(node, ctx, indent) {
|
|
|
2276
2499
|
if (child.name === "case" || child.name === ":") continue;
|
|
2277
2500
|
if (child.name === "Body") {
|
|
2278
2501
|
body = child;
|
|
2279
|
-
} else
|
|
2280
|
-
pattern
|
|
2502
|
+
} else {
|
|
2503
|
+
pattern ??= child;
|
|
2281
2504
|
}
|
|
2282
2505
|
}
|
|
2283
2506
|
if (!pattern || !body) return "";
|
|
@@ -2397,7 +2620,7 @@ function transformTryStatement(node, ctx) {
|
|
|
2397
2620
|
}
|
|
2398
2621
|
if (child.name === "try") {
|
|
2399
2622
|
const nextBody = children[i + 1];
|
|
2400
|
-
if (nextBody
|
|
2623
|
+
if (nextBody?.name === "Body") {
|
|
2401
2624
|
tryBody = nextBody;
|
|
2402
2625
|
i += 2;
|
|
2403
2626
|
continue;
|
|
@@ -2435,7 +2658,7 @@ function transformTryStatement(node, ctx) {
|
|
|
2435
2658
|
}
|
|
2436
2659
|
if (child.name === "finally") {
|
|
2437
2660
|
const nextBody = children[i + 1];
|
|
2438
|
-
if (nextBody
|
|
2661
|
+
if (nextBody?.name === "Body") {
|
|
2439
2662
|
finallyBody = nextBody;
|
|
2440
2663
|
i += 2;
|
|
2441
2664
|
continue;
|
|
@@ -2453,7 +2676,7 @@ ${baseIndent}}`;
|
|
|
2453
2676
|
if (exceptBodies.length > 0) {
|
|
2454
2677
|
const firstExcept = exceptBodies[0];
|
|
2455
2678
|
if (firstExcept) {
|
|
2456
|
-
const catchVar = firstExcept.varName
|
|
2679
|
+
const catchVar = firstExcept.varName ?? "e";
|
|
2457
2680
|
let catchBody = transformBody(firstExcept.body, ctx);
|
|
2458
2681
|
const isEmpty = !catchBody.trim();
|
|
2459
2682
|
if (isEmpty) {
|
|
@@ -2477,7 +2700,7 @@ ${baseIndent}}`;
|
|
|
2477
2700
|
const exc = exceptBodies[idx];
|
|
2478
2701
|
if (!exc) continue;
|
|
2479
2702
|
const excBodyCode = transformBody(exc.body, ctx);
|
|
2480
|
-
const excVar = exc.varName
|
|
2703
|
+
const excVar = exc.varName ?? catchVar;
|
|
2481
2704
|
if (exc.type) {
|
|
2482
2705
|
const condition = idx === 0 ? "if" : "} else if";
|
|
2483
2706
|
const mappedType = mapExceptionType(exc.type);
|
|
@@ -2532,7 +2755,7 @@ function mapExceptionType(pythonType) {
|
|
|
2532
2755
|
NameError: "ReferenceError",
|
|
2533
2756
|
SyntaxError: "SyntaxError"
|
|
2534
2757
|
};
|
|
2535
|
-
return mapping[pythonType]
|
|
2758
|
+
return mapping[pythonType] ?? "Error";
|
|
2536
2759
|
}
|
|
2537
2760
|
function transformRaiseStatement(node, ctx) {
|
|
2538
2761
|
const children = getChildren(node);
|
|
@@ -2622,9 +2845,9 @@ function transformSimpleImport(children, ctx) {
|
|
|
2622
2845
|
const moduleName = getNodeText(child, ctx.source);
|
|
2623
2846
|
let alias = null;
|
|
2624
2847
|
const nextChild = children[i + 1];
|
|
2625
|
-
if (nextChild
|
|
2848
|
+
if (nextChild?.name === "as") {
|
|
2626
2849
|
const aliasChild = children[i + 2];
|
|
2627
|
-
if (aliasChild
|
|
2850
|
+
if (aliasChild?.name === "VariableName") {
|
|
2628
2851
|
alias = getNodeText(aliasChild, ctx.source);
|
|
2629
2852
|
i += 3;
|
|
2630
2853
|
names.push({ module: moduleName, alias });
|
|
@@ -2644,7 +2867,7 @@ function transformSimpleImport(children, ctx) {
|
|
|
2644
2867
|
return "";
|
|
2645
2868
|
}
|
|
2646
2869
|
return filteredNames.map(({ module, alias }) => {
|
|
2647
|
-
const importName = alias
|
|
2870
|
+
const importName = alias ?? module;
|
|
2648
2871
|
return `import * as ${importName} from "${module}"`;
|
|
2649
2872
|
}).join("\n");
|
|
2650
2873
|
}
|
|
@@ -2720,9 +2943,9 @@ function transformFromImport(children, ctx) {
|
|
|
2720
2943
|
if (child.name === "VariableName") {
|
|
2721
2944
|
const name = getNodeText(child, ctx.source);
|
|
2722
2945
|
const nextChild = children[i + 1];
|
|
2723
|
-
if (nextChild
|
|
2946
|
+
if (nextChild?.name === "as") {
|
|
2724
2947
|
const aliasChild = children[i + 2];
|
|
2725
|
-
if (aliasChild
|
|
2948
|
+
if (aliasChild?.name === "VariableName") {
|
|
2726
2949
|
imports.push({ name, alias: getNodeText(aliasChild, ctx.source) });
|
|
2727
2950
|
i += 2;
|
|
2728
2951
|
continue;
|
|
@@ -2746,7 +2969,7 @@ function transformFromImport(children, ctx) {
|
|
|
2746
2969
|
if (moduleName) {
|
|
2747
2970
|
modulePath += moduleName;
|
|
2748
2971
|
} else if (imports.length > 0) {
|
|
2749
|
-
modulePath += imports[0]?.name
|
|
2972
|
+
modulePath += imports[0]?.name ?? "";
|
|
2750
2973
|
}
|
|
2751
2974
|
} else {
|
|
2752
2975
|
modulePath = moduleName;
|
|
@@ -2757,7 +2980,7 @@ function transformFromImport(children, ctx) {
|
|
|
2757
2980
|
if (relativeDots > 0 && !moduleName && imports.length === 1) {
|
|
2758
2981
|
const imp = imports[0];
|
|
2759
2982
|
if (imp) {
|
|
2760
|
-
const importName = imp.alias
|
|
2983
|
+
const importName = imp.alias ?? imp.name;
|
|
2761
2984
|
return `import * as ${importName} from "${modulePath}"`;
|
|
2762
2985
|
}
|
|
2763
2986
|
}
|
|
@@ -2796,9 +3019,9 @@ function transformWithStatement(node, ctx) {
|
|
|
2796
3019
|
const expr = child;
|
|
2797
3020
|
let varName = null;
|
|
2798
3021
|
const nextChild = children[i + 1];
|
|
2799
|
-
if (nextChild
|
|
3022
|
+
if (nextChild?.name === "as") {
|
|
2800
3023
|
const varChild = children[i + 2];
|
|
2801
|
-
if (varChild
|
|
3024
|
+
if (varChild?.name === "VariableName") {
|
|
2802
3025
|
varName = getNodeText(varChild, ctx.source);
|
|
2803
3026
|
i += 3;
|
|
2804
3027
|
} else {
|
|
@@ -2871,7 +3094,7 @@ function extractParamNames(node, source) {
|
|
|
2871
3094
|
}
|
|
2872
3095
|
if (child.name === "*" || getNodeText(child, source) === "*") {
|
|
2873
3096
|
const nextChild = children[i + 1];
|
|
2874
|
-
if (nextChild
|
|
3097
|
+
if (nextChild?.name === "VariableName") {
|
|
2875
3098
|
names.push(getNodeText(nextChild, source));
|
|
2876
3099
|
i += 2;
|
|
2877
3100
|
continue;
|
|
@@ -2881,7 +3104,7 @@ function extractParamNames(node, source) {
|
|
|
2881
3104
|
}
|
|
2882
3105
|
if (child.name === "**" || getNodeText(child, source) === "**") {
|
|
2883
3106
|
const nextChild = children[i + 1];
|
|
2884
|
-
if (nextChild
|
|
3107
|
+
if (nextChild?.name === "VariableName") {
|
|
2885
3108
|
names.push(getNodeText(nextChild, source));
|
|
2886
3109
|
i += 2;
|
|
2887
3110
|
continue;
|
|
@@ -3252,7 +3475,7 @@ function transformMethodParamListImpl(node, ctx, includeTypes) {
|
|
|
3252
3475
|
isFirstParam = false;
|
|
3253
3476
|
if (child.name === "*" || getNodeText(child, ctx.source) === "*") {
|
|
3254
3477
|
const nextChild = children[i + 1];
|
|
3255
|
-
if (nextChild
|
|
3478
|
+
if (nextChild?.name === "VariableName") {
|
|
3256
3479
|
const name = getNodeText(nextChild, ctx.source);
|
|
3257
3480
|
params.push(`...${name}`);
|
|
3258
3481
|
i += 2;
|
|
@@ -3263,7 +3486,7 @@ function transformMethodParamListImpl(node, ctx, includeTypes) {
|
|
|
3263
3486
|
}
|
|
3264
3487
|
if (child.name === "**" || getNodeText(child, ctx.source) === "**") {
|
|
3265
3488
|
const nextChild = children[i + 1];
|
|
3266
|
-
if (nextChild
|
|
3489
|
+
if (nextChild?.name === "VariableName") {
|
|
3267
3490
|
const name = getNodeText(nextChild, ctx.source);
|
|
3268
3491
|
params.push(name);
|
|
3269
3492
|
i += 2;
|
|
@@ -3606,7 +3829,7 @@ function parseDataclassFieldFromExpression(node, ctx) {
|
|
|
3606
3829
|
}
|
|
3607
3830
|
function parseFieldDefaultFactory(callNode, ctx) {
|
|
3608
3831
|
const text = getNodeText(callNode, ctx.source);
|
|
3609
|
-
const factoryMatch =
|
|
3832
|
+
const factoryMatch = /default_factory\s*=\s*(\w+)/.exec(text);
|
|
3610
3833
|
if (factoryMatch) {
|
|
3611
3834
|
const factory = factoryMatch[1];
|
|
3612
3835
|
if (factory === "list") return "[]";
|
|
@@ -3614,7 +3837,7 @@ function parseFieldDefaultFactory(callNode, ctx) {
|
|
|
3614
3837
|
if (factory === "set") return "new Set()";
|
|
3615
3838
|
if (factory) return `${factory}()`;
|
|
3616
3839
|
}
|
|
3617
|
-
const defaultMatch =
|
|
3840
|
+
const defaultMatch = /default\s*=\s*([^,)]+)/.exec(text);
|
|
3618
3841
|
if (defaultMatch) {
|
|
3619
3842
|
return defaultMatch[1]?.trim() ?? "undefined";
|
|
3620
3843
|
}
|
|
@@ -3833,9 +4056,8 @@ function parseEnumMember(node, ctx) {
|
|
|
3833
4056
|
function checkSequentialEnum(members) {
|
|
3834
4057
|
if (members.length === 0) return true;
|
|
3835
4058
|
if (members.some((m) => m.value === "auto")) return true;
|
|
3836
|
-
const
|
|
3837
|
-
if (
|
|
3838
|
-
const values = numericMembers.map((m) => m.numericValue);
|
|
4059
|
+
const values = members.map((m) => m.numericValue).filter((v) => v !== null);
|
|
4060
|
+
if (values.length !== members.length) return false;
|
|
3839
4061
|
const firstValue = values[0];
|
|
3840
4062
|
if (firstValue === void 0) return false;
|
|
3841
4063
|
for (let i = 1; i < values.length; i++) {
|
|
@@ -3917,7 +4139,7 @@ function transformProtocol(className, parentClasses, body, ctx) {
|
|
|
3917
4139
|
members.push(`${memberIndent}${sig}`);
|
|
3918
4140
|
}
|
|
3919
4141
|
} else if (child.name === "ExpressionStatement" || child.name === "AssignStatement") {
|
|
3920
|
-
const field = parseDataclassFieldFromExpression(child, ctx)
|
|
4142
|
+
const field = parseDataclassFieldFromExpression(child, ctx) ?? parseDataclassFieldFromAssignment(child, ctx);
|
|
3921
4143
|
if (field) {
|
|
3922
4144
|
members.push(`${memberIndent}${field.name}: ${field.tsType}`);
|
|
3923
4145
|
}
|
|
@@ -4016,18 +4238,18 @@ function transformParamList(node, ctx) {
|
|
|
4016
4238
|
let i = 0;
|
|
4017
4239
|
const parseParam = (startIndex) => {
|
|
4018
4240
|
const child = children[startIndex];
|
|
4019
|
-
if (
|
|
4241
|
+
if (child?.name !== "VariableName") return null;
|
|
4020
4242
|
const nameCode = getNodeText(child, ctx.source);
|
|
4021
4243
|
let tsType = null;
|
|
4022
4244
|
let defaultValue = null;
|
|
4023
4245
|
let offset = 1;
|
|
4024
4246
|
const nextChild = children[startIndex + 1];
|
|
4025
|
-
if (nextChild
|
|
4247
|
+
if (nextChild?.name === "TypeDef") {
|
|
4026
4248
|
tsType = extractTypeAnnotation(nextChild, ctx);
|
|
4027
4249
|
offset = 2;
|
|
4028
4250
|
}
|
|
4029
4251
|
const afterType = children[startIndex + offset];
|
|
4030
|
-
if (afterType
|
|
4252
|
+
if (afterType?.name === "AssignOp") {
|
|
4031
4253
|
const defaultValChild = children[startIndex + offset + 1];
|
|
4032
4254
|
if (defaultValChild) {
|
|
4033
4255
|
defaultValue = transformNode(defaultValChild, ctx);
|
|
@@ -4058,10 +4280,10 @@ function transformParamList(node, ctx) {
|
|
|
4058
4280
|
}
|
|
4059
4281
|
if (child.name === "*" || getNodeText(child, ctx.source) === "*") {
|
|
4060
4282
|
const nextChild = children[i + 1];
|
|
4061
|
-
if (nextChild
|
|
4283
|
+
if (nextChild?.name === "VariableName") {
|
|
4062
4284
|
const name = getNodeText(nextChild, ctx.source);
|
|
4063
4285
|
const typeChild = children[i + 2];
|
|
4064
|
-
if (typeChild
|
|
4286
|
+
if (typeChild?.name === "TypeDef") {
|
|
4065
4287
|
const tsType = extractTypeAnnotation(typeChild, ctx);
|
|
4066
4288
|
restParam = tsType ? `...${name}: ${tsType}[]` : `...${name}`;
|
|
4067
4289
|
i += 3;
|
|
@@ -4078,7 +4300,7 @@ function transformParamList(node, ctx) {
|
|
|
4078
4300
|
}
|
|
4079
4301
|
if (child.name === "**" || getNodeText(child, ctx.source) === "**") {
|
|
4080
4302
|
const nextChild = children[i + 1];
|
|
4081
|
-
if (nextChild
|
|
4303
|
+
if (nextChild?.name === "VariableName") {
|
|
4082
4304
|
kwargsParam = getNodeText(nextChild, ctx.source);
|
|
4083
4305
|
i += 2;
|
|
4084
4306
|
continue;
|
|
@@ -4804,4 +5026,3 @@ export {
|
|
|
4804
5026
|
/* v8 ignore next -- bare yield statement @preserve */
|
|
4805
5027
|
/* v8 ignore next 2 -- fallback for future/unknown runtime functions @preserve */
|
|
4806
5028
|
/* v8 ignore start -- async wrappers tested via CLI @preserve */
|
|
4807
|
-
//# sourceMappingURL=chunk-MEHQCUVO.js.map
|
package/dist/cli/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
transpileAsync
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-LNOL3BMB.js";
|
|
5
5
|
|
|
6
6
|
// src/cli/index.ts
|
|
7
7
|
import { parseArgs } from "util";
|
|
@@ -113,4 +113,3 @@ main().catch((error) => {
|
|
|
113
113
|
console.error(`Unexpected error: ${String(error)}`);
|
|
114
114
|
process.exit(1);
|
|
115
115
|
});
|
|
116
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
transpile,
|
|
13
13
|
transpileAsync,
|
|
14
14
|
walkTree
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-LNOL3BMB.js";
|
|
16
16
|
export {
|
|
17
17
|
debugTree,
|
|
18
18
|
formatCode,
|
|
@@ -28,4 +28,3 @@ export {
|
|
|
28
28
|
transpileAsync,
|
|
29
29
|
walkTree
|
|
30
30
|
};
|
|
31
|
-
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "python2ts",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "AST-based Python to TypeScript transpiler. Convert Python code to clean, idiomatic TypeScript with full type preservation.",
|
|
5
5
|
"homepage": "https://sebastian-software.github.io/python2ts/",
|
|
6
6
|
"repository": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"eslint": "^9.39.2",
|
|
54
54
|
"prettier": "^3.8.0",
|
|
55
55
|
"typescript-eslint": "^8.53.1",
|
|
56
|
-
"pythonlib": "
|
|
56
|
+
"pythonlib": "2.0.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"tsup": "^8.5.1",
|