tywrap 0.5.0 → 0.6.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.
- package/dist/cli.js +8 -6
- package/dist/cli.js.map +1 -1
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +236 -147
- package/dist/config/index.js.map +1 -1
- package/dist/core/annotation-parser.d.ts.map +1 -1
- package/dist/core/annotation-parser.js +93 -83
- package/dist/core/annotation-parser.js.map +1 -1
- package/dist/core/discovery.d.ts.map +1 -1
- package/dist/core/discovery.js +26 -0
- package/dist/core/discovery.js.map +1 -1
- package/dist/core/emit-call.d.ts +58 -0
- package/dist/core/emit-call.d.ts.map +1 -0
- package/dist/core/emit-call.js +103 -0
- package/dist/core/emit-call.js.map +1 -0
- package/dist/core/generator.d.ts +2 -0
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/core/generator.js +54 -211
- package/dist/core/generator.js.map +1 -1
- package/dist/core/mapper.d.ts.map +1 -1
- package/dist/core/mapper.js +118 -104
- package/dist/core/mapper.js.map +1 -1
- package/dist/index.d.ts +6 -25
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -31
- package/dist/index.js.map +1 -1
- package/dist/runtime/bounded-context.d.ts +2 -2
- package/dist/runtime/bounded-context.js +2 -2
- package/dist/runtime/{safe-codec.d.ts → bridge-codec.d.ts} +11 -11
- package/dist/runtime/bridge-codec.d.ts.map +1 -0
- package/dist/runtime/{safe-codec.js → bridge-codec.js} +26 -26
- package/dist/runtime/bridge-codec.js.map +1 -0
- package/dist/runtime/{http-io.d.ts → http-transport.d.ts} +6 -6
- package/dist/runtime/http-transport.d.ts.map +1 -0
- package/dist/runtime/{http-io.js → http-transport.js} +3 -3
- package/dist/runtime/http-transport.js.map +1 -0
- package/dist/runtime/http.d.ts +3 -3
- package/dist/runtime/http.d.ts.map +1 -1
- package/dist/runtime/http.js +4 -4
- package/dist/runtime/http.js.map +1 -1
- package/dist/runtime/index.d.ts +9 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +9 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/node.d.ts +6 -6
- package/dist/runtime/node.d.ts.map +1 -1
- package/dist/runtime/node.js +7 -7
- package/dist/runtime/node.js.map +1 -1
- package/dist/runtime/pooled-transport.d.ts +11 -11
- package/dist/runtime/pooled-transport.d.ts.map +1 -1
- package/dist/runtime/pooled-transport.js +10 -10
- package/dist/runtime/pooled-transport.js.map +1 -1
- package/dist/runtime/pyodide-bootstrap-core.generated.d.ts.map +1 -1
- package/dist/runtime/pyodide-bootstrap-core.generated.js +1 -1
- package/dist/runtime/pyodide-bootstrap-core.generated.js.map +1 -1
- package/dist/runtime/{pyodide-io.d.ts → pyodide-transport.d.ts} +8 -8
- package/dist/runtime/pyodide-transport.d.ts.map +1 -0
- package/dist/runtime/{pyodide-io.js → pyodide-transport.js} +5 -5
- package/dist/runtime/pyodide-transport.js.map +1 -0
- package/dist/runtime/pyodide.d.ts +3 -3
- package/dist/runtime/pyodide.d.ts.map +1 -1
- package/dist/runtime/pyodide.js +5 -5
- package/dist/runtime/pyodide.js.map +1 -1
- package/dist/runtime/rpc-client.d.ts +5 -5
- package/dist/runtime/rpc-client.d.ts.map +1 -1
- package/dist/runtime/rpc-client.js +6 -7
- package/dist/runtime/rpc-client.js.map +1 -1
- package/dist/runtime/{process-io.d.ts → subprocess-transport.d.ts} +9 -9
- package/dist/runtime/subprocess-transport.d.ts.map +1 -0
- package/dist/runtime/{process-io.js → subprocess-transport.js} +6 -6
- package/dist/runtime/subprocess-transport.js.map +1 -0
- package/dist/runtime/{worker-pool.d.ts → transport-pool.d.ts} +15 -15
- package/dist/runtime/transport-pool.d.ts.map +1 -0
- package/dist/runtime/{worker-pool.js → transport-pool.js} +6 -6
- package/dist/runtime/transport-pool.js.map +1 -0
- package/dist/runtime/transport.d.ts +14 -8
- package/dist/runtime/transport.d.ts.map +1 -1
- package/dist/runtime/transport.js +10 -4
- package/dist/runtime/transport.js.map +1 -1
- package/dist/types/index.d.ts +10 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/tywrap.d.ts.map +1 -1
- package/dist/tywrap.js +1 -3
- package/dist/tywrap.js.map +1 -1
- package/dist/utils/cache.d.ts +2 -2
- package/dist/utils/cache.d.ts.map +1 -1
- package/dist/utils/cache.js +2 -2
- package/dist/utils/cache.js.map +1 -1
- package/dist/utils/codec.d.ts +1 -1
- package/dist/utils/codec.d.ts.map +1 -1
- package/dist/utils/codec.js +181 -182
- package/dist/utils/codec.js.map +1 -1
- package/dist/version.d.ts +12 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +12 -0
- package/dist/version.js.map +1 -0
- package/package.json +3 -5
- package/runtime/__pycache__/safe_codec.cpython-311.pyc +0 -0
- package/runtime/__pycache__/tywrap_bridge_core.cpython-311.pyc +0 -0
- package/runtime/python_bridge.py +54 -6
- package/runtime/safe_codec.py +8 -8
- package/runtime/tywrap_bridge_core.py +159 -23
- package/src/cli.ts +8 -12
- package/src/config/index.ts +271 -165
- package/src/core/annotation-parser.ts +112 -105
- package/src/core/discovery.ts +32 -0
- package/src/core/emit-call.ts +171 -0
- package/src/core/generator.ts +67 -263
- package/src/core/mapper.ts +125 -110
- package/src/index.ts +11 -68
- package/src/runtime/bounded-context.ts +2 -2
- package/src/runtime/{safe-codec.ts → bridge-codec.ts} +27 -27
- package/src/runtime/{http-io.ts → http-transport.ts} +5 -5
- package/src/runtime/http.ts +5 -5
- package/src/runtime/index.ts +23 -1
- package/src/runtime/node.ts +15 -15
- package/src/runtime/pooled-transport.ts +15 -15
- package/src/runtime/pyodide-bootstrap-core.generated.ts +1 -1
- package/src/runtime/{pyodide-io.ts → pyodide-transport.ts} +7 -7
- package/src/runtime/pyodide.ts +6 -6
- package/src/runtime/rpc-client.ts +12 -8
- package/src/runtime/{process-io.ts → subprocess-transport.ts} +8 -8
- package/src/runtime/{worker-pool.ts → transport-pool.ts} +26 -26
- package/src/runtime/transport.ts +15 -8
- package/src/types/index.ts +10 -1
- package/src/tywrap.ts +1 -3
- package/src/utils/cache.ts +2 -2
- package/src/utils/codec.ts +217 -196
- package/src/version.ts +12 -0
- package/dist/core/analyzer.d.ts +0 -64
- package/dist/core/analyzer.d.ts.map +0 -1
- package/dist/core/analyzer.js +0 -710
- package/dist/core/analyzer.js.map +0 -1
- package/dist/runtime/http-io.d.ts.map +0 -1
- package/dist/runtime/http-io.js.map +0 -1
- package/dist/runtime/optimized-node.d.ts +0 -23
- package/dist/runtime/optimized-node.d.ts.map +0 -1
- package/dist/runtime/optimized-node.js +0 -23
- package/dist/runtime/optimized-node.js.map +0 -1
- package/dist/runtime/process-io.d.ts.map +0 -1
- package/dist/runtime/process-io.js.map +0 -1
- package/dist/runtime/protocol.d.ts +0 -3
- package/dist/runtime/protocol.d.ts.map +0 -1
- package/dist/runtime/protocol.js +0 -3
- package/dist/runtime/protocol.js.map +0 -1
- package/dist/runtime/pyodide-io.d.ts.map +0 -1
- package/dist/runtime/pyodide-io.js.map +0 -1
- package/dist/runtime/safe-codec.d.ts.map +0 -1
- package/dist/runtime/safe-codec.js.map +0 -1
- package/dist/runtime/worker-pool.d.ts.map +0 -1
- package/dist/runtime/worker-pool.js.map +0 -1
- package/dist/utils/bundle-optimizer.d.ts +0 -182
- package/dist/utils/bundle-optimizer.d.ts.map +0 -1
- package/dist/utils/bundle-optimizer.js +0 -680
- package/dist/utils/bundle-optimizer.js.map +0 -1
- package/dist/utils/memory-profiler.d.ts +0 -123
- package/dist/utils/memory-profiler.d.ts.map +0 -1
- package/dist/utils/memory-profiler.js +0 -426
- package/dist/utils/memory-profiler.js.map +0 -1
- package/dist/utils/parallel-processor.d.ts +0 -146
- package/dist/utils/parallel-processor.d.ts.map +0 -1
- package/dist/utils/parallel-processor.js +0 -707
- package/dist/utils/parallel-processor.js.map +0 -1
- package/src/core/analyzer.ts +0 -824
- package/src/runtime/optimized-node.ts +0 -25
- package/src/runtime/protocol.ts +0 -2
- package/src/utils/bundle-optimizer.ts +0 -876
- package/src/utils/memory-profiler.ts +0 -582
- package/src/utils/parallel-processor.ts +0 -955
package/src/core/generator.ts
CHANGED
|
@@ -14,6 +14,12 @@ import type {
|
|
|
14
14
|
} from '../types/index.js';
|
|
15
15
|
import { globalCache } from '../utils/cache.js';
|
|
16
16
|
|
|
17
|
+
import {
|
|
18
|
+
emitArgGuards,
|
|
19
|
+
emitCallPrelude,
|
|
20
|
+
type CallDescriptor,
|
|
21
|
+
type CallEmitHelpers,
|
|
22
|
+
} from './emit-call.js';
|
|
17
23
|
import { TypeMapper } from './mapper.js';
|
|
18
24
|
|
|
19
25
|
interface GenericRenderParam {
|
|
@@ -336,6 +342,21 @@ export class CodeGenerator {
|
|
|
336
342
|
return `(${base} && (${keyCheck}))`;
|
|
337
343
|
}
|
|
338
344
|
|
|
345
|
+
/** Helpers passed to the shared call-emission module (they depend on `this`). */
|
|
346
|
+
private callEmitHelpers(): CallEmitHelpers {
|
|
347
|
+
return {
|
|
348
|
+
escapeIdentifier: (name: string): string => this.escapeIdentifier(name),
|
|
349
|
+
renderLooksLikeKwargsExpr: (
|
|
350
|
+
valueExpr: string,
|
|
351
|
+
options: {
|
|
352
|
+
keywordOnlyNames: string[];
|
|
353
|
+
requiredKwOnlyNames: string[];
|
|
354
|
+
hasVarKwArgs: boolean;
|
|
355
|
+
}
|
|
356
|
+
): string => this.renderLooksLikeKwargsExpr(valueExpr, options),
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
339
360
|
generateFunctionWrapper(
|
|
340
361
|
func: PythonFunction,
|
|
341
362
|
moduleName?: string,
|
|
@@ -492,96 +513,26 @@ export class CodeGenerator {
|
|
|
492
513
|
}
|
|
493
514
|
|
|
494
515
|
const overloadDecl = overloads.length > 0 ? `${overloads.join('\n')}\n` : '';
|
|
495
|
-
const guardLines: string[] = [];
|
|
496
|
-
if (hasKwArgs && positionalOnlyNames.length > 0) {
|
|
497
|
-
guardLines.push(
|
|
498
|
-
` const __positionalOnly = ${JSON.stringify(positionalOnlyNames)} as const;`
|
|
499
|
-
);
|
|
500
|
-
guardLines.push(` for (const key of __positionalOnly) {`);
|
|
501
|
-
guardLines.push(` if (__kwargs && Object.prototype.hasOwnProperty.call(__kwargs, key)) {`);
|
|
502
|
-
guardLines.push(
|
|
503
|
-
` throw new Error(\`${func.name} does not accept positional-only argument "\${key}" as a keyword argument\`);`
|
|
504
|
-
);
|
|
505
|
-
guardLines.push(` }`);
|
|
506
|
-
guardLines.push(` }`);
|
|
507
|
-
}
|
|
508
|
-
if (hasKwArgs && requiredKwOnlyNames.length > 0) {
|
|
509
|
-
guardLines.push(
|
|
510
|
-
` const __requiredKwOnly = ${JSON.stringify(requiredKwOnlyNames)} as const;`
|
|
511
|
-
);
|
|
512
|
-
guardLines.push(` const __missing: string[] = [];`);
|
|
513
|
-
guardLines.push(` for (const key of __requiredKwOnly) {`);
|
|
514
|
-
guardLines.push(
|
|
515
|
-
` if (!__kwargs || !Object.prototype.hasOwnProperty.call(__kwargs, key)) {`
|
|
516
|
-
);
|
|
517
|
-
guardLines.push(` __missing.push(key);`);
|
|
518
|
-
guardLines.push(` }`);
|
|
519
|
-
guardLines.push(` }`);
|
|
520
|
-
guardLines.push(` if (__missing.length > 0) {`);
|
|
521
|
-
guardLines.push(
|
|
522
|
-
` throw new Error(\`Missing required keyword-only arguments for ${func.name}: \${__missing.join(', ')}\`);`
|
|
523
|
-
);
|
|
524
|
-
guardLines.push(` }`);
|
|
525
|
-
}
|
|
526
|
-
const guards = guardLines.length > 0 ? `${guardLines.join('\n')}\n` : '';
|
|
527
516
|
|
|
528
517
|
const firstOptionalPosIndex = positionalParams.findIndex(p => p.optional);
|
|
529
518
|
const requiredPosCount =
|
|
530
519
|
firstOptionalPosIndex >= 0 ? firstOptionalPosIndex : positionalParams.length;
|
|
531
|
-
const
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
requiredKwOnlyNames,
|
|
548
|
-
hasVarKwArgs,
|
|
549
|
-
});
|
|
550
|
-
callPreludeLines.push(
|
|
551
|
-
` if (__kwargs === undefined && __args.length > ${requiredPosCount}) {`
|
|
552
|
-
);
|
|
553
|
-
callPreludeLines.push(` const __candidate = __args[__args.length - 1];`);
|
|
554
|
-
callPreludeLines.push(` if (${looksLikeKwargs}) {`);
|
|
555
|
-
callPreludeLines.push(` __kwargs = __candidate as any;`);
|
|
556
|
-
callPreludeLines.push(` __args.pop();`);
|
|
557
|
-
callPreludeLines.push(` }`);
|
|
558
|
-
callPreludeLines.push(` }`);
|
|
559
|
-
}
|
|
560
|
-
if (varArgsParam) {
|
|
561
|
-
const vname = this.escapeIdentifier(varArgsParam.name);
|
|
562
|
-
if (needsVarArgsArray) {
|
|
563
|
-
const looksLikeKwargs = this.renderLooksLikeKwargsExpr(vname, {
|
|
564
|
-
keywordOnlyNames,
|
|
565
|
-
requiredKwOnlyNames,
|
|
566
|
-
hasVarKwArgs,
|
|
567
|
-
});
|
|
568
|
-
callPreludeLines.push(` let __varargs: unknown[] = [];`);
|
|
569
|
-
callPreludeLines.push(` if (${vname} !== undefined) {`);
|
|
570
|
-
callPreludeLines.push(` if (globalThis.Array.isArray(${vname})) {`);
|
|
571
|
-
callPreludeLines.push(` __varargs = ${vname};`);
|
|
572
|
-
callPreludeLines.push(` } else if (__kwargs === undefined && ${looksLikeKwargs}) {`);
|
|
573
|
-
callPreludeLines.push(` __kwargs = ${vname} as any;`);
|
|
574
|
-
callPreludeLines.push(` } else {`);
|
|
575
|
-
callPreludeLines.push(
|
|
576
|
-
` throw new Error(\`${func.name} expected ${varArgsParam.name} to be an array\`);`
|
|
577
|
-
);
|
|
578
|
-
callPreludeLines.push(` }`);
|
|
579
|
-
callPreludeLines.push(` }`);
|
|
580
|
-
callPreludeLines.push(` __args.push(...__varargs);`);
|
|
581
|
-
} else {
|
|
582
|
-
callPreludeLines.push(` __args.push(...${vname});`);
|
|
583
|
-
}
|
|
584
|
-
}
|
|
520
|
+
const callDescriptor: CallDescriptor = {
|
|
521
|
+
positionalParams,
|
|
522
|
+
varArgsParam,
|
|
523
|
+
needsVarArgsArray,
|
|
524
|
+
hasKwArgs,
|
|
525
|
+
hasVarKwArgs,
|
|
526
|
+
keywordOnlyNames,
|
|
527
|
+
requiredKwOnlyNames,
|
|
528
|
+
positionalOnlyNames,
|
|
529
|
+
requiredPosCount,
|
|
530
|
+
indent: ' ',
|
|
531
|
+
errorLabel: func.name,
|
|
532
|
+
};
|
|
533
|
+
const guardLines = emitArgGuards(callDescriptor);
|
|
534
|
+
const guards = guardLines.length > 0 ? `${guardLines.join('\n')}\n` : '';
|
|
535
|
+
const callPreludeLines = emitCallPrelude(callDescriptor, this.callEmitHelpers());
|
|
585
536
|
const callPrelude = callPreludeLines.length > 0 ? `${callPreludeLines.join('\n')}\n` : '';
|
|
586
537
|
|
|
587
538
|
const ts = `${jsdoc}${overloadDecl}export async function ${fname}${typeParamDecl}(${paramDecl}): Promise<${returnType}> {
|
|
@@ -797,97 +748,23 @@ ${callPrelude}${guards} return getRuntimeBridge().call('${moduleId}', '${func.n
|
|
|
797
748
|
}
|
|
798
749
|
const overloadDecl = overloads.length > 0 ? `${overloads.join('\n')}\n` : '';
|
|
799
750
|
|
|
800
|
-
const
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
const looksLikeKwargs = this.renderLooksLikeKwargsExpr('__candidate', {
|
|
815
|
-
keywordOnlyNames,
|
|
816
|
-
requiredKwOnlyNames,
|
|
817
|
-
hasVarKwArgs,
|
|
818
|
-
});
|
|
819
|
-
callPreludeLines.push(
|
|
820
|
-
` if (__kwargs === undefined && __args.length > ${requiredPosCount}) {`
|
|
821
|
-
);
|
|
822
|
-
callPreludeLines.push(` const __candidate = __args[__args.length - 1];`);
|
|
823
|
-
callPreludeLines.push(` if (${looksLikeKwargs}) {`);
|
|
824
|
-
callPreludeLines.push(` __kwargs = __candidate as any;`);
|
|
825
|
-
callPreludeLines.push(` __args.pop();`);
|
|
826
|
-
callPreludeLines.push(` }`);
|
|
827
|
-
callPreludeLines.push(` }`);
|
|
828
|
-
}
|
|
829
|
-
if (varArgsParam) {
|
|
830
|
-
const vname = this.escapeIdentifier(varArgsParam.name);
|
|
831
|
-
if (needsVarArgsArray) {
|
|
832
|
-
const looksLikeKwargs = this.renderLooksLikeKwargsExpr(vname, {
|
|
833
|
-
keywordOnlyNames,
|
|
834
|
-
requiredKwOnlyNames,
|
|
835
|
-
hasVarKwArgs,
|
|
836
|
-
});
|
|
837
|
-
callPreludeLines.push(` let __varargs: unknown[] = [];`);
|
|
838
|
-
callPreludeLines.push(` if (${vname} !== undefined) {`);
|
|
839
|
-
callPreludeLines.push(` if (globalThis.Array.isArray(${vname})) {`);
|
|
840
|
-
callPreludeLines.push(` __varargs = ${vname};`);
|
|
841
|
-
callPreludeLines.push(
|
|
842
|
-
` } else if (__kwargs === undefined && ${looksLikeKwargs}) {`
|
|
843
|
-
);
|
|
844
|
-
callPreludeLines.push(` __kwargs = ${vname} as any;`);
|
|
845
|
-
callPreludeLines.push(` } else {`);
|
|
846
|
-
callPreludeLines.push(
|
|
847
|
-
` throw new Error(\`${method.name} expected ${varArgsParam.name} to be an array\`);`
|
|
848
|
-
);
|
|
849
|
-
callPreludeLines.push(` }`);
|
|
850
|
-
callPreludeLines.push(` }`);
|
|
851
|
-
callPreludeLines.push(` __args.push(...__varargs);`);
|
|
852
|
-
} else {
|
|
853
|
-
callPreludeLines.push(` __args.push(...${vname});`);
|
|
854
|
-
}
|
|
855
|
-
}
|
|
751
|
+
const callDescriptor: CallDescriptor = {
|
|
752
|
+
positionalParams,
|
|
753
|
+
varArgsParam,
|
|
754
|
+
needsVarArgsArray,
|
|
755
|
+
hasKwArgs: needsKwargsParam,
|
|
756
|
+
hasVarKwArgs,
|
|
757
|
+
keywordOnlyNames,
|
|
758
|
+
requiredKwOnlyNames,
|
|
759
|
+
positionalOnlyNames,
|
|
760
|
+
requiredPosCount,
|
|
761
|
+
indent: ' ',
|
|
762
|
+
errorLabel: method.name,
|
|
763
|
+
};
|
|
764
|
+
const callPreludeLines = emitCallPrelude(callDescriptor, this.callEmitHelpers());
|
|
856
765
|
const callPrelude = callPreludeLines.length > 0 ? `${callPreludeLines.join('\n')}\n` : '';
|
|
857
766
|
|
|
858
|
-
const guardLines
|
|
859
|
-
if (needsKwargsParam && positionalOnlyNames.length > 0) {
|
|
860
|
-
guardLines.push(
|
|
861
|
-
` const __positionalOnly = ${JSON.stringify(positionalOnlyNames)} as const;`
|
|
862
|
-
);
|
|
863
|
-
guardLines.push(` for (const key of __positionalOnly) {`);
|
|
864
|
-
guardLines.push(
|
|
865
|
-
` if (__kwargs && Object.prototype.hasOwnProperty.call(__kwargs, key)) {`
|
|
866
|
-
);
|
|
867
|
-
guardLines.push(
|
|
868
|
-
` throw new Error(\`${method.name} does not accept positional-only argument "\${key}" as a keyword argument\`);`
|
|
869
|
-
);
|
|
870
|
-
guardLines.push(` }`);
|
|
871
|
-
guardLines.push(` }`);
|
|
872
|
-
}
|
|
873
|
-
if (needsKwargsParam && requiredKwOnlyNames.length > 0) {
|
|
874
|
-
guardLines.push(
|
|
875
|
-
` const __requiredKwOnly = ${JSON.stringify(requiredKwOnlyNames)} as const;`
|
|
876
|
-
);
|
|
877
|
-
guardLines.push(` const __missing: string[] = [];`);
|
|
878
|
-
guardLines.push(` for (const key of __requiredKwOnly) {`);
|
|
879
|
-
guardLines.push(
|
|
880
|
-
` if (!__kwargs || !Object.prototype.hasOwnProperty.call(__kwargs, key)) {`
|
|
881
|
-
);
|
|
882
|
-
guardLines.push(` __missing.push(key);`);
|
|
883
|
-
guardLines.push(` }`);
|
|
884
|
-
guardLines.push(` }`);
|
|
885
|
-
guardLines.push(` if (__missing.length > 0) {`);
|
|
886
|
-
guardLines.push(
|
|
887
|
-
` throw new Error(\`Missing required keyword-only arguments for ${method.name}: \${__missing.join(', ')}\`);`
|
|
888
|
-
);
|
|
889
|
-
guardLines.push(` }`);
|
|
890
|
-
}
|
|
767
|
+
const guardLines = emitArgGuards(callDescriptor);
|
|
891
768
|
const guards = guardLines.length > 0 ? `${guardLines.join('\n')}\n` : '';
|
|
892
769
|
|
|
893
770
|
methodBodies.push(`${overloadDecl} async ${mname}${methodTypeParamDecl}(${paramsDecl}): Promise<${returnType}> {
|
|
@@ -994,95 +871,22 @@ ${callPrelude}${guards} return getRuntimeBridge().callMethod(this.__handle, '
|
|
|
994
871
|
? overloadDecl
|
|
995
872
|
: ` static create${classTypeParamDecl}(${paramsDecl}): Promise<${classSelfType}>;\n`;
|
|
996
873
|
|
|
997
|
-
const
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
if (needsKwargsParam && requiredPosCount < positionalParams.length) {
|
|
1012
|
-
const looksLikeKwargs = this.renderLooksLikeKwargsExpr('__candidate', {
|
|
1013
|
-
keywordOnlyNames,
|
|
1014
|
-
requiredKwOnlyNames,
|
|
1015
|
-
hasVarKwArgs,
|
|
1016
|
-
});
|
|
1017
|
-
callPreludeLines.push(
|
|
1018
|
-
` if (__kwargs === undefined && __args.length > ${requiredPosCount}) {`
|
|
1019
|
-
);
|
|
1020
|
-
callPreludeLines.push(` const __candidate = __args[__args.length - 1];`);
|
|
1021
|
-
callPreludeLines.push(` if (${looksLikeKwargs}) {`);
|
|
1022
|
-
callPreludeLines.push(` __kwargs = __candidate as any;`);
|
|
1023
|
-
callPreludeLines.push(` __args.pop();`);
|
|
1024
|
-
callPreludeLines.push(` }`);
|
|
1025
|
-
callPreludeLines.push(` }`);
|
|
1026
|
-
}
|
|
1027
|
-
if (varArgsParam) {
|
|
1028
|
-
const vname = this.escapeIdentifier(varArgsParam.name);
|
|
1029
|
-
if (needsVarArgsArray) {
|
|
1030
|
-
const looksLikeKwargs = this.renderLooksLikeKwargsExpr(vname, {
|
|
1031
|
-
keywordOnlyNames,
|
|
1032
|
-
requiredKwOnlyNames,
|
|
1033
|
-
hasVarKwArgs,
|
|
1034
|
-
});
|
|
1035
|
-
callPreludeLines.push(` let __varargs: unknown[] = [];`);
|
|
1036
|
-
callPreludeLines.push(` if (${vname} !== undefined) {`);
|
|
1037
|
-
callPreludeLines.push(` if (globalThis.Array.isArray(${vname})) {`);
|
|
1038
|
-
callPreludeLines.push(` __varargs = ${vname};`);
|
|
1039
|
-
callPreludeLines.push(` } else if (__kwargs === undefined && ${looksLikeKwargs}) {`);
|
|
1040
|
-
callPreludeLines.push(` __kwargs = ${vname} as any;`);
|
|
1041
|
-
callPreludeLines.push(` } else {`);
|
|
1042
|
-
callPreludeLines.push(
|
|
1043
|
-
` throw new Error(\`__init__ expected ${varArgsParam.name} to be an array\`);`
|
|
1044
|
-
);
|
|
1045
|
-
callPreludeLines.push(` }`);
|
|
1046
|
-
callPreludeLines.push(` }`);
|
|
1047
|
-
callPreludeLines.push(` __args.push(...__varargs);`);
|
|
1048
|
-
} else {
|
|
1049
|
-
callPreludeLines.push(` __args.push(...${vname});`);
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
874
|
+
const callDescriptor: CallDescriptor = {
|
|
875
|
+
positionalParams,
|
|
876
|
+
varArgsParam,
|
|
877
|
+
needsVarArgsArray,
|
|
878
|
+
hasKwArgs: needsKwargsParam,
|
|
879
|
+
hasVarKwArgs,
|
|
880
|
+
keywordOnlyNames,
|
|
881
|
+
requiredKwOnlyNames,
|
|
882
|
+
positionalOnlyNames,
|
|
883
|
+
requiredPosCount,
|
|
884
|
+
indent: ' ',
|
|
885
|
+
errorLabel: '__init__',
|
|
886
|
+
};
|
|
887
|
+
const callPreludeLines = emitCallPrelude(callDescriptor, this.callEmitHelpers());
|
|
1052
888
|
const callPrelude = callPreludeLines.length > 0 ? `${callPreludeLines.join('\n')}\n` : '';
|
|
1053
|
-
|
|
1054
|
-
if (needsKwargsParam && positionalOnlyNames.length > 0) {
|
|
1055
|
-
guardLines.push(
|
|
1056
|
-
` const __positionalOnly = ${JSON.stringify(positionalOnlyNames)} as const;`
|
|
1057
|
-
);
|
|
1058
|
-
guardLines.push(` for (const key of __positionalOnly) {`);
|
|
1059
|
-
guardLines.push(
|
|
1060
|
-
` if (__kwargs && Object.prototype.hasOwnProperty.call(__kwargs, key)) {`
|
|
1061
|
-
);
|
|
1062
|
-
guardLines.push(
|
|
1063
|
-
` throw new Error(\`__init__ does not accept positional-only argument "\${key}" as a keyword argument\`);`
|
|
1064
|
-
);
|
|
1065
|
-
guardLines.push(` }`);
|
|
1066
|
-
guardLines.push(` }`);
|
|
1067
|
-
}
|
|
1068
|
-
if (needsKwargsParam && requiredKwOnlyNames.length > 0) {
|
|
1069
|
-
guardLines.push(
|
|
1070
|
-
` const __requiredKwOnly = ${JSON.stringify(requiredKwOnlyNames)} as const;`
|
|
1071
|
-
);
|
|
1072
|
-
guardLines.push(` const __missing: string[] = [];`);
|
|
1073
|
-
guardLines.push(` for (const key of __requiredKwOnly) {`);
|
|
1074
|
-
guardLines.push(
|
|
1075
|
-
` if (!__kwargs || !Object.prototype.hasOwnProperty.call(__kwargs, key)) {`
|
|
1076
|
-
);
|
|
1077
|
-
guardLines.push(` __missing.push(key);`);
|
|
1078
|
-
guardLines.push(` }`);
|
|
1079
|
-
guardLines.push(` }`);
|
|
1080
|
-
guardLines.push(` if (__missing.length > 0) {`);
|
|
1081
|
-
guardLines.push(
|
|
1082
|
-
` throw new Error(\`Missing required keyword-only arguments for __init__: \${__missing.join(', ')}\`);`
|
|
1083
|
-
);
|
|
1084
|
-
guardLines.push(` }`);
|
|
1085
|
-
}
|
|
889
|
+
const guardLines = emitArgGuards(callDescriptor);
|
|
1086
890
|
|
|
1087
891
|
return {
|
|
1088
892
|
overloadDecl,
|
package/src/core/mapper.ts
CHANGED
|
@@ -503,119 +503,134 @@ export class TypeMapper {
|
|
|
503
503
|
readonly: false,
|
|
504
504
|
});
|
|
505
505
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
if (name === 'timedelta') {
|
|
519
|
-
return { kind: 'primitive', name: 'number' };
|
|
520
|
-
}
|
|
521
|
-
if (name === 'Decimal' || name === 'UUID') {
|
|
522
|
-
return { kind: 'primitive', name: 'string' };
|
|
523
|
-
}
|
|
524
|
-
if (
|
|
525
|
-
name === 'Path' ||
|
|
526
|
-
name === 'PurePath' ||
|
|
527
|
-
name === 'PosixPath' ||
|
|
528
|
-
name === 'WindowsPath'
|
|
529
|
-
) {
|
|
530
|
-
return { kind: 'primitive', name: 'string' };
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
if (this.hasPreset('pandas')) {
|
|
536
|
-
const allowModule = !moduleName || moduleName.startsWith('pandas');
|
|
537
|
-
if (allowModule) {
|
|
538
|
-
if (name === 'DataFrame') {
|
|
539
|
-
const recordsArray: TSArrayType = { kind: 'array', elementType: recordObject };
|
|
540
|
-
return { kind: 'union', types: [recordObject, recordsArray] };
|
|
541
|
-
}
|
|
542
|
-
if (name === 'Series') {
|
|
543
|
-
const valuesArray: TSArrayType = {
|
|
544
|
-
kind: 'array',
|
|
545
|
-
elementType: { kind: 'primitive', name: 'unknown' },
|
|
546
|
-
};
|
|
547
|
-
return { kind: 'union', types: [valuesArray, recordObject] };
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
if (this.hasPreset('pydantic')) {
|
|
553
|
-
const allowModule = !moduleName || moduleName.startsWith('pydantic');
|
|
554
|
-
if (allowModule && name === 'BaseModel') {
|
|
555
|
-
return recordObject;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
506
|
+
const baseProps = [prop('shape', numberArray), prop('dtype', stringType, true)];
|
|
507
|
+
const buildSparse = (format: 'csr' | 'csc' | 'coo'): TSObjectType => ({
|
|
508
|
+
kind: 'object',
|
|
509
|
+
properties: [
|
|
510
|
+
prop('format', { kind: 'literal', value: format }),
|
|
511
|
+
...baseProps,
|
|
512
|
+
prop('data', unknownArray),
|
|
513
|
+
...(format === 'coo'
|
|
514
|
+
? [prop('row', numberArray), prop('col', numberArray)]
|
|
515
|
+
: [prop('indices', numberArray), prop('indptr', numberArray)]),
|
|
516
|
+
],
|
|
517
|
+
});
|
|
558
518
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
519
|
+
// Each entry pairs a preset with the module(s) it owns and a name->type resolver.
|
|
520
|
+
// Entries are evaluated in order; the first enabled preset whose module is allowed
|
|
521
|
+
// and whose resolver returns a type wins. This preserves the prior cascading-`if`
|
|
522
|
+
// precedence while keeping the per-preset rules table-driven.
|
|
523
|
+
const presetResolvers: ReadonlyArray<{
|
|
524
|
+
preset: TypePreset;
|
|
525
|
+
allowModule: (moduleName: string | undefined) => boolean;
|
|
526
|
+
resolve: (name: string) => TypescriptType | undefined;
|
|
527
|
+
}> = [
|
|
528
|
+
{
|
|
529
|
+
preset: 'stdlib',
|
|
530
|
+
allowModule: m =>
|
|
531
|
+
!m || m === 'datetime' || m === 'decimal' || m === 'uuid' || m === 'pathlib',
|
|
532
|
+
resolve: n => {
|
|
533
|
+
if (n === 'datetime' || n === 'date' || n === 'time') {
|
|
534
|
+
return { kind: 'primitive', name: 'string' };
|
|
535
|
+
}
|
|
536
|
+
if (n === 'timedelta') {
|
|
537
|
+
return { kind: 'primitive', name: 'number' };
|
|
538
|
+
}
|
|
539
|
+
if (n === 'Decimal' || n === 'UUID') {
|
|
540
|
+
return { kind: 'primitive', name: 'string' };
|
|
541
|
+
}
|
|
542
|
+
if (n === 'Path' || n === 'PurePath' || n === 'PosixPath' || n === 'WindowsPath') {
|
|
543
|
+
return { kind: 'primitive', name: 'string' };
|
|
544
|
+
}
|
|
545
|
+
return undefined;
|
|
546
|
+
},
|
|
547
|
+
},
|
|
548
|
+
{
|
|
549
|
+
preset: 'pandas',
|
|
550
|
+
allowModule: m => !m || m.startsWith('pandas'),
|
|
551
|
+
resolve: n => {
|
|
552
|
+
if (n === 'DataFrame') {
|
|
553
|
+
const recordsArray: TSArrayType = { kind: 'array', elementType: recordObject };
|
|
554
|
+
return { kind: 'union', types: [recordObject, recordsArray] };
|
|
555
|
+
}
|
|
556
|
+
if (n === 'Series') {
|
|
557
|
+
const valuesArray: TSArrayType = {
|
|
558
|
+
kind: 'array',
|
|
559
|
+
elementType: { kind: 'primitive', name: 'unknown' },
|
|
560
|
+
};
|
|
561
|
+
return { kind: 'union', types: [valuesArray, recordObject] };
|
|
562
|
+
}
|
|
563
|
+
return undefined;
|
|
564
|
+
},
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
preset: 'pydantic',
|
|
568
|
+
allowModule: m => !m || m.startsWith('pydantic'),
|
|
569
|
+
resolve: n => (n === 'BaseModel' ? recordObject : undefined),
|
|
570
|
+
},
|
|
571
|
+
{
|
|
572
|
+
preset: 'scipy',
|
|
573
|
+
allowModule: m => !m || m.startsWith('scipy'),
|
|
574
|
+
resolve: n => {
|
|
575
|
+
if (n === 'csr_matrix') {
|
|
576
|
+
return buildSparse('csr');
|
|
577
|
+
}
|
|
578
|
+
if (n === 'csc_matrix') {
|
|
579
|
+
return buildSparse('csc');
|
|
580
|
+
}
|
|
581
|
+
if (n === 'coo_matrix') {
|
|
582
|
+
return buildSparse('coo');
|
|
583
|
+
}
|
|
584
|
+
if (n === 'spmatrix') {
|
|
585
|
+
return {
|
|
586
|
+
kind: 'union',
|
|
587
|
+
types: [buildSparse('csr'), buildSparse('csc'), buildSparse('coo')],
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
return undefined;
|
|
591
|
+
},
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
preset: 'torch',
|
|
595
|
+
allowModule: m => !m || m.startsWith('torch'),
|
|
596
|
+
resolve: n =>
|
|
597
|
+
n === 'Tensor'
|
|
598
|
+
? {
|
|
599
|
+
kind: 'object',
|
|
600
|
+
properties: [
|
|
601
|
+
prop('data', unknownType),
|
|
602
|
+
prop('shape', numberArray),
|
|
603
|
+
prop('dtype', stringType, true),
|
|
604
|
+
prop('device', stringType, true),
|
|
605
|
+
],
|
|
606
|
+
}
|
|
607
|
+
: undefined,
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
preset: 'sklearn',
|
|
611
|
+
allowModule: m => !m || m.startsWith('sklearn'),
|
|
612
|
+
resolve: n =>
|
|
613
|
+
n === 'BaseEstimator'
|
|
614
|
+
? {
|
|
615
|
+
kind: 'object',
|
|
616
|
+
properties: [
|
|
617
|
+
prop('className', stringType),
|
|
618
|
+
prop('module', stringType),
|
|
619
|
+
prop('version', stringType, true),
|
|
620
|
+
prop('params', recordObject),
|
|
621
|
+
],
|
|
622
|
+
}
|
|
623
|
+
: undefined,
|
|
624
|
+
},
|
|
625
|
+
];
|
|
591
626
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
return {
|
|
596
|
-
kind: 'object',
|
|
597
|
-
properties: [
|
|
598
|
-
prop('data', unknownType),
|
|
599
|
-
prop('shape', numberArray),
|
|
600
|
-
prop('dtype', stringType, true),
|
|
601
|
-
prop('device', stringType, true),
|
|
602
|
-
],
|
|
603
|
-
};
|
|
627
|
+
for (const entry of presetResolvers) {
|
|
628
|
+
if (!this.hasPreset(entry.preset) || !entry.allowModule(moduleName)) {
|
|
629
|
+
continue;
|
|
604
630
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
const allowModule = !moduleName || moduleName.startsWith('sklearn');
|
|
609
|
-
if (allowModule && name === 'BaseEstimator') {
|
|
610
|
-
return {
|
|
611
|
-
kind: 'object',
|
|
612
|
-
properties: [
|
|
613
|
-
prop('className', stringType),
|
|
614
|
-
prop('module', stringType),
|
|
615
|
-
prop('version', stringType, true),
|
|
616
|
-
prop('params', recordObject),
|
|
617
|
-
],
|
|
618
|
-
};
|
|
631
|
+
const resolved = entry.resolve(name);
|
|
632
|
+
if (resolved !== undefined) {
|
|
633
|
+
return resolved;
|
|
619
634
|
}
|
|
620
635
|
}
|
|
621
636
|
|