tywrap 0.5.1 → 0.6.1
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 +112 -97
- package/dist/core/annotation-parser.js.map +1 -1
- package/dist/core/discovery.d.ts +17 -0
- package/dist/core/discovery.d.ts.map +1 -1
- package/dist/core/discovery.js +85 -49
- 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/core/validation.d.ts +23 -0
- package/dist/core/validation.d.ts.map +1 -1
- package/dist/core/validation.js +52 -48
- package/dist/core/validation.js.map +1 -1
- package/dist/dev.d.ts.map +1 -1
- package/dist/dev.js +175 -133
- package/dist/dev.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} +26 -11
- package/dist/runtime/bridge-codec.d.ts.map +1 -0
- package/dist/runtime/{safe-codec.js → bridge-codec.js} +69 -72
- 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 +23 -5
- package/dist/runtime/rpc-client.d.ts.map +1 -1
- package/dist/runtime/rpc-client.js +36 -31
- package/dist/runtime/rpc-client.js.map +1 -1
- package/dist/runtime/{process-io.d.ts → subprocess-transport.d.ts} +25 -9
- package/dist/runtime/subprocess-transport.d.ts.map +1 -0
- package/dist/runtime/{process-io.js → subprocess-transport.js} +60 -41
- 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 +0 -5
- package/dist/tywrap.d.ts.map +1 -1
- package/dist/tywrap.js +0 -20
- package/dist/tywrap.js.map +1 -1
- package/dist/utils/cache.d.ts +13 -2
- package/dist/utils/cache.d.ts.map +1 -1
- package/dist/utils/cache.js +52 -60
- 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/utils/python.d.ts.map +1 -1
- package/dist/utils/python.js +28 -17
- package/dist/utils/python.js.map +1 -1
- package/dist/utils/runtime.d.ts.map +1 -1
- package/dist/utils/runtime.js +22 -16
- package/dist/utils/runtime.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 -2
- 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 +135 -123
- package/src/core/discovery.ts +102 -54
- package/src/core/emit-call.ts +171 -0
- package/src/core/generator.ts +67 -263
- package/src/core/mapper.ts +125 -110
- package/src/core/validation.ts +84 -48
- package/src/dev.ts +237 -153
- package/src/index.ts +11 -68
- package/src/runtime/bounded-context.ts +2 -2
- package/src/runtime/{safe-codec.ts → bridge-codec.ts} +83 -95
- 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 +51 -40
- package/src/runtime/{process-io.ts → subprocess-transport.ts} +77 -47
- 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 +0 -24
- package/src/utils/cache.ts +61 -63
- package/src/utils/codec.ts +217 -196
- package/src/utils/python.ts +33 -20
- package/src/utils/runtime.ts +24 -13
- package/src/version.ts +12 -0
- 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/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/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
|
|
package/src/core/validation.ts
CHANGED
|
@@ -195,60 +195,96 @@ export class ValidationEngine {
|
|
|
195
195
|
errors: AnalysisError[],
|
|
196
196
|
warnings: AnalysisWarning[]
|
|
197
197
|
): void {
|
|
198
|
-
|
|
199
|
-
if (this.isEmptyType(func.returnType) && func.name !== '__init__') {
|
|
200
|
-
if (this.config.allowMissingTypeHints) {
|
|
201
|
-
warnings.push({
|
|
202
|
-
type: 'missing-type',
|
|
203
|
-
message: `Function '${func.name}' is missing return type annotation`,
|
|
204
|
-
});
|
|
205
|
-
} else if (this.config.strictTypeChecking) {
|
|
206
|
-
// In strict mode without allowMissingTypeHints, we warn first then error
|
|
207
|
-
warnings.push({
|
|
208
|
-
type: 'missing-type',
|
|
209
|
-
message: `Function '${func.name}' is missing return type annotation`,
|
|
210
|
-
});
|
|
211
|
-
errors.push({
|
|
212
|
-
type: 'type',
|
|
213
|
-
message: `Function '${func.name}' requires return type annotation`,
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
}
|
|
198
|
+
this.checkReturnTypeHint(func, errors, warnings);
|
|
217
199
|
|
|
218
200
|
// Check parameter types (skip 'self' and 'cls' parameters)
|
|
219
201
|
for (const param of func.parameters) {
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
type: 'missing-type',
|
|
224
|
-
message: `Parameter '${param.name}' in function '${func.name}' is missing type annotation`,
|
|
225
|
-
});
|
|
226
|
-
} else if (this.config.strictTypeChecking) {
|
|
227
|
-
// In strict mode without allowMissingTypeHints, we warn first then error
|
|
228
|
-
warnings.push({
|
|
229
|
-
type: 'missing-type',
|
|
230
|
-
message: `Parameter '${param.name}' in function '${func.name}' is missing type annotation`,
|
|
231
|
-
});
|
|
232
|
-
errors.push({
|
|
233
|
-
type: 'type',
|
|
234
|
-
message: `Parameter '${param.name}' in function '${func.name}' requires type annotation`,
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
}
|
|
202
|
+
this.checkParameterTypeHint(func, param, errors, warnings);
|
|
203
|
+
this.checkParameterTypeStructure(param, errors);
|
|
204
|
+
}
|
|
238
205
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
206
|
+
this.checkReturnTypeStructure(func, errors);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Emit a missing-type warning, and—in strict mode—an accompanying error.
|
|
211
|
+
* In strict mode without allowMissingTypeHints, we warn first then error.
|
|
212
|
+
*/
|
|
213
|
+
private reportMissingType(
|
|
214
|
+
warningMessage: string,
|
|
215
|
+
errorMessage: string,
|
|
216
|
+
warnings: AnalysisWarning[],
|
|
217
|
+
errors: AnalysisError[]
|
|
218
|
+
): void {
|
|
219
|
+
if (this.config.allowMissingTypeHints) {
|
|
220
|
+
warnings.push({ type: 'missing-type', message: warningMessage });
|
|
221
|
+
} else if (this.config.strictTypeChecking) {
|
|
222
|
+
warnings.push({ type: 'missing-type', message: warningMessage });
|
|
223
|
+
errors.push({ type: 'type', message: errorMessage });
|
|
249
224
|
}
|
|
225
|
+
}
|
|
250
226
|
|
|
251
|
-
|
|
227
|
+
/**
|
|
228
|
+
* Check the function return type annotation (skip __init__ methods as they
|
|
229
|
+
* conventionally don't need return type annotations).
|
|
230
|
+
*/
|
|
231
|
+
private checkReturnTypeHint(
|
|
232
|
+
func: PythonFunction,
|
|
233
|
+
errors: AnalysisError[],
|
|
234
|
+
warnings: AnalysisWarning[]
|
|
235
|
+
): void {
|
|
236
|
+
if (this.isEmptyType(func.returnType) && func.name !== '__init__') {
|
|
237
|
+
this.reportMissingType(
|
|
238
|
+
`Function '${func.name}' is missing return type annotation`,
|
|
239
|
+
`Function '${func.name}' requires return type annotation`,
|
|
240
|
+
warnings,
|
|
241
|
+
errors
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Check a single parameter's type annotation (skip 'self' and 'cls').
|
|
248
|
+
*/
|
|
249
|
+
private checkParameterTypeHint(
|
|
250
|
+
func: PythonFunction,
|
|
251
|
+
param: PythonFunction['parameters'][number],
|
|
252
|
+
errors: AnalysisError[],
|
|
253
|
+
warnings: AnalysisWarning[]
|
|
254
|
+
): void {
|
|
255
|
+
if (this.isEmptyType(param.type) && param.name !== 'self' && param.name !== 'cls') {
|
|
256
|
+
this.reportMissingType(
|
|
257
|
+
`Parameter '${param.name}' in function '${func.name}' is missing type annotation`,
|
|
258
|
+
`Parameter '${param.name}' in function '${func.name}' requires type annotation`,
|
|
259
|
+
warnings,
|
|
260
|
+
errors
|
|
261
|
+
);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Validate a single parameter's type structure only in strict mode
|
|
267
|
+
* (skip 'self' and 'cls' parameters).
|
|
268
|
+
*/
|
|
269
|
+
private checkParameterTypeStructure(
|
|
270
|
+
param: PythonFunction['parameters'][number],
|
|
271
|
+
errors: AnalysisError[]
|
|
272
|
+
): void {
|
|
273
|
+
if (
|
|
274
|
+
this.config.strictTypeChecking &&
|
|
275
|
+
!this.config.allowMissingTypeHints &&
|
|
276
|
+
param.name !== 'self' &&
|
|
277
|
+
param.name !== 'cls'
|
|
278
|
+
) {
|
|
279
|
+
const typeErrors = this.validateTypeAnnotation(param.type, `parameter '${param.name}'`);
|
|
280
|
+
errors.push(...typeErrors);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Validate the return type structure only in strict mode.
|
|
286
|
+
*/
|
|
287
|
+
private checkReturnTypeStructure(func: PythonFunction, errors: AnalysisError[]): void {
|
|
252
288
|
if (this.config.strictTypeChecking && !this.config.allowMissingTypeHints) {
|
|
253
289
|
const returnTypeErrors = this.validateTypeAnnotation(func.returnType, 'return type');
|
|
254
290
|
errors.push(...returnTypeErrors);
|