tywrap 0.1.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.
Files changed (137) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +319 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +263 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config/index.d.ts +41 -0
  8. package/dist/config/index.d.ts.map +1 -0
  9. package/dist/config/index.js +234 -0
  10. package/dist/config/index.js.map +1 -0
  11. package/dist/core/analyzer.d.ts +63 -0
  12. package/dist/core/analyzer.d.ts.map +1 -0
  13. package/dist/core/analyzer.js +676 -0
  14. package/dist/core/analyzer.js.map +1 -0
  15. package/dist/core/discovery.d.ts +85 -0
  16. package/dist/core/discovery.d.ts.map +1 -0
  17. package/dist/core/discovery.js +344 -0
  18. package/dist/core/discovery.js.map +1 -0
  19. package/dist/core/generator.d.ts +37 -0
  20. package/dist/core/generator.d.ts.map +1 -0
  21. package/dist/core/generator.js +368 -0
  22. package/dist/core/generator.js.map +1 -0
  23. package/dist/core/mapper.d.ts +40 -0
  24. package/dist/core/mapper.d.ts.map +1 -0
  25. package/dist/core/mapper.js +401 -0
  26. package/dist/core/mapper.js.map +1 -0
  27. package/dist/core/validation.d.ts +79 -0
  28. package/dist/core/validation.d.ts.map +1 -0
  29. package/dist/core/validation.js +486 -0
  30. package/dist/core/validation.js.map +1 -0
  31. package/dist/index.d.ts +26 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +29 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/runtime/base.d.ts +12 -0
  36. package/dist/runtime/base.d.ts.map +1 -0
  37. package/dist/runtime/base.js +6 -0
  38. package/dist/runtime/base.js.map +1 -0
  39. package/dist/runtime/errors.d.ts +17 -0
  40. package/dist/runtime/errors.d.ts.map +1 -0
  41. package/dist/runtime/errors.js +21 -0
  42. package/dist/runtime/errors.js.map +1 -0
  43. package/dist/runtime/http.d.ts +22 -0
  44. package/dist/runtime/http.d.ts.map +1 -0
  45. package/dist/runtime/http.js +79 -0
  46. package/dist/runtime/http.js.map +1 -0
  47. package/dist/runtime/index.d.ts +8 -0
  48. package/dist/runtime/index.d.ts.map +1 -0
  49. package/dist/runtime/index.js +17 -0
  50. package/dist/runtime/index.js.map +1 -0
  51. package/dist/runtime/node.d.ts +48 -0
  52. package/dist/runtime/node.d.ts.map +1 -0
  53. package/dist/runtime/node.js +328 -0
  54. package/dist/runtime/node.js.map +1 -0
  55. package/dist/runtime/optimized-node.d.ts +131 -0
  56. package/dist/runtime/optimized-node.d.ts.map +1 -0
  57. package/dist/runtime/optimized-node.js +622 -0
  58. package/dist/runtime/optimized-node.js.map +1 -0
  59. package/dist/runtime/protocol.d.ts +3 -0
  60. package/dist/runtime/protocol.d.ts.map +1 -0
  61. package/dist/runtime/protocol.js +3 -0
  62. package/dist/runtime/protocol.js.map +1 -0
  63. package/dist/runtime/pyodide.d.ts +27 -0
  64. package/dist/runtime/pyodide.d.ts.map +1 -0
  65. package/dist/runtime/pyodide.js +191 -0
  66. package/dist/runtime/pyodide.js.map +1 -0
  67. package/dist/tools/python_suite.js +173 -0
  68. package/dist/tools/python_suite.js.map +1 -0
  69. package/dist/types/index.d.ts +299 -0
  70. package/dist/types/index.d.ts.map +1 -0
  71. package/dist/types/index.js +5 -0
  72. package/dist/types/index.js.map +1 -0
  73. package/dist/tywrap.d.ts +29 -0
  74. package/dist/tywrap.d.ts.map +1 -0
  75. package/dist/tywrap.js +589 -0
  76. package/dist/tywrap.js.map +1 -0
  77. package/dist/utils/bundle-optimizer.d.ts +182 -0
  78. package/dist/utils/bundle-optimizer.d.ts.map +1 -0
  79. package/dist/utils/bundle-optimizer.js +680 -0
  80. package/dist/utils/bundle-optimizer.js.map +1 -0
  81. package/dist/utils/cache.d.ts +149 -0
  82. package/dist/utils/cache.d.ts.map +1 -0
  83. package/dist/utils/cache.js +492 -0
  84. package/dist/utils/cache.js.map +1 -0
  85. package/dist/utils/codec.d.ts +94 -0
  86. package/dist/utils/codec.d.ts.map +1 -0
  87. package/dist/utils/codec.js +150 -0
  88. package/dist/utils/codec.js.map +1 -0
  89. package/dist/utils/logger.d.ts +42 -0
  90. package/dist/utils/logger.d.ts.map +1 -0
  91. package/dist/utils/logger.js +140 -0
  92. package/dist/utils/logger.js.map +1 -0
  93. package/dist/utils/memory-profiler.d.ts +123 -0
  94. package/dist/utils/memory-profiler.d.ts.map +1 -0
  95. package/dist/utils/memory-profiler.js +426 -0
  96. package/dist/utils/memory-profiler.js.map +1 -0
  97. package/dist/utils/parallel-processor.d.ts +146 -0
  98. package/dist/utils/parallel-processor.d.ts.map +1 -0
  99. package/dist/utils/parallel-processor.js +636 -0
  100. package/dist/utils/parallel-processor.js.map +1 -0
  101. package/dist/utils/python.d.ts +8 -0
  102. package/dist/utils/python.d.ts.map +1 -0
  103. package/dist/utils/python.js +56 -0
  104. package/dist/utils/python.js.map +1 -0
  105. package/dist/utils/runtime.d.ts +153 -0
  106. package/dist/utils/runtime.d.ts.map +1 -0
  107. package/dist/utils/runtime.js +519 -0
  108. package/dist/utils/runtime.js.map +1 -0
  109. package/package.json +136 -0
  110. package/runtime/python_bridge.py +476 -0
  111. package/src/cli.ts +331 -0
  112. package/src/config/index.ts +289 -0
  113. package/src/core/analyzer.ts +788 -0
  114. package/src/core/discovery.ts +415 -0
  115. package/src/core/generator.ts +447 -0
  116. package/src/core/mapper.ts +504 -0
  117. package/src/core/validation.ts +693 -0
  118. package/src/index.ts +83 -0
  119. package/src/runtime/base.ts +32 -0
  120. package/src/runtime/errors.ts +19 -0
  121. package/src/runtime/http.ts +132 -0
  122. package/src/runtime/index.ts +24 -0
  123. package/src/runtime/node.ts +431 -0
  124. package/src/runtime/optimized-node.ts +838 -0
  125. package/src/runtime/protocol.ts +2 -0
  126. package/src/runtime/pyodide.ts +228 -0
  127. package/src/types/global.d.ts +60 -0
  128. package/src/types/index.ts +410 -0
  129. package/src/tywrap.ts +669 -0
  130. package/src/utils/bundle-optimizer.ts +876 -0
  131. package/src/utils/cache.ts +634 -0
  132. package/src/utils/codec.ts +275 -0
  133. package/src/utils/logger.ts +201 -0
  134. package/src/utils/memory-profiler.ts +582 -0
  135. package/src/utils/parallel-processor.ts +879 -0
  136. package/src/utils/python.ts +79 -0
  137. package/src/utils/runtime.ts +616 -0
@@ -0,0 +1,504 @@
1
+ /**
2
+ * TypeMapper - Python to TypeScript type conversion
3
+ */
4
+
5
+ import type {
6
+ PythonType,
7
+ PrimitiveType as PyPrimitiveType,
8
+ CollectionType as PyCollectionType,
9
+ UnionType as PyUnionType,
10
+ OptionalType as PyOptionalType,
11
+ GenericType as PyGenericType,
12
+ TypeVarType as PyTypeVarType,
13
+ FinalType as PyFinalType,
14
+ ClassVarType as PyClassVarType,
15
+ TypescriptType,
16
+ TSPrimitiveType,
17
+ TSArrayType,
18
+ TSTupleType,
19
+ TSObjectType,
20
+ TSUnionType,
21
+ TSFunctionType,
22
+ TSGenericType,
23
+ TSCustomType,
24
+ TSIndexSignature,
25
+ TSLiteralType,
26
+ TypePreset,
27
+ } from '../types/index.js';
28
+
29
+ export type MappingContext = 'value' | 'return';
30
+
31
+ export interface TypeMapperOptions {
32
+ presets?: readonly TypePreset[];
33
+ }
34
+
35
+ export class TypeMapper {
36
+ private readonly presets: Set<TypePreset>;
37
+
38
+ constructor(options: TypeMapperOptions = {}) {
39
+ this.presets = new Set(options.presets ?? []);
40
+ }
41
+
42
+ mapPythonType(pythonType: PythonType, context: MappingContext = 'value'): TypescriptType {
43
+ switch (pythonType.kind) {
44
+ case 'primitive':
45
+ return this.mapPrimitiveType(pythonType, context);
46
+ case 'collection':
47
+ return this.mapCollectionType(pythonType);
48
+ case 'union':
49
+ return this.mapUnionType(pythonType, context);
50
+ case 'optional':
51
+ return this.mapOptionalType(pythonType, context);
52
+ case 'generic':
53
+ return this.mapGenericType(pythonType, context);
54
+ case 'custom':
55
+ return this.mapCustomType(pythonType, context);
56
+ case 'callable':
57
+ return this.mapCallableType(pythonType);
58
+ case 'literal':
59
+ return this.mapLiteralType(pythonType);
60
+ case 'annotated':
61
+ // Pass-through base for type shape; metadata used at generation when configured
62
+ return this.mapPythonType(pythonType.base, context);
63
+ case 'typevar':
64
+ return this.mapTypeVarType(pythonType, context);
65
+ case 'final':
66
+ return this.mapFinalType(pythonType, context);
67
+ case 'classvar':
68
+ return this.mapClassVarType(pythonType, context);
69
+ }
70
+ }
71
+
72
+ mapPrimitiveType(type: PyPrimitiveType, context: MappingContext = 'value'): TSPrimitiveType {
73
+ const name =
74
+ type.name === 'int' || type.name === 'float'
75
+ ? 'number'
76
+ : type.name === 'str'
77
+ ? 'string'
78
+ : type.name === 'bool'
79
+ ? 'boolean'
80
+ : type.name === 'bytes'
81
+ ? 'string'
82
+ : // None
83
+ context === 'return'
84
+ ? 'void'
85
+ : 'null';
86
+
87
+ return { kind: 'primitive', name };
88
+ }
89
+
90
+ mapCollectionType(
91
+ type: PyCollectionType
92
+ ): TSArrayType | TSTupleType | TSObjectType | TSGenericType {
93
+ // list[T] -> Array<T>
94
+ if (type.name === 'list') {
95
+ const elementType = this.mapPythonType(
96
+ type.itemTypes[0] ?? { kind: 'custom', name: 'Any', module: 'typing' }
97
+ );
98
+ return {
99
+ kind: 'array',
100
+ elementType,
101
+ } satisfies TSArrayType;
102
+ }
103
+
104
+ // tuple[T1, T2, ...] -> [T1, T2, ...] (exact arity)
105
+ if (type.name === 'tuple') {
106
+ const elementTypes: TypescriptType[] =
107
+ type.itemTypes.length > 0
108
+ ? type.itemTypes.map(t => this.mapPythonType(t))
109
+ : ([{ kind: 'primitive', name: 'undefined' }] as const);
110
+ return { kind: 'tuple', elementTypes } satisfies TSTupleType;
111
+ }
112
+
113
+ // set[T] -> Set<T>
114
+ if (type.name === 'set' || type.name === 'frozenset') {
115
+ const elementType = this.mapPythonType(
116
+ type.itemTypes[0] ?? { kind: 'custom', name: 'Any', module: 'typing' }
117
+ );
118
+ return {
119
+ kind: 'generic',
120
+ name: 'Set',
121
+ typeArgs: [elementType],
122
+ } satisfies TSGenericType;
123
+ }
124
+
125
+ // dict[K, V] -> { [key: K]: V }
126
+ if (type.name === 'dict') {
127
+ const keyPy = type.itemTypes[0] ?? { kind: 'primitive', name: 'str' };
128
+ const valPy = type.itemTypes[1] ?? { kind: 'custom', name: 'Any', module: 'typing' };
129
+ const key = this.mapPythonType(keyPy);
130
+ const value = this.mapPythonType(valPy);
131
+
132
+ const indexSignature: TSIndexSignature = {
133
+ keyType: this.asIndexKeyType(key),
134
+ valueType: value,
135
+ };
136
+
137
+ return {
138
+ kind: 'object',
139
+ properties: [],
140
+ indexSignature,
141
+ } satisfies TSObjectType;
142
+ }
143
+
144
+ // Default to object unknown index
145
+ return {
146
+ kind: 'object',
147
+ properties: [],
148
+ indexSignature: {
149
+ keyType: { kind: 'primitive', name: 'string' },
150
+ valueType: { kind: 'primitive', name: 'unknown' },
151
+ },
152
+ } satisfies TSObjectType;
153
+ }
154
+
155
+ mapUnionType(type: PyUnionType, context: MappingContext = 'value'): TSUnionType {
156
+ return {
157
+ kind: 'union',
158
+ types: type.types.map(t => this.mapPythonType(t, context)),
159
+ };
160
+ }
161
+
162
+ mapOptionalType(type: PyOptionalType, context: MappingContext = 'value'): TSUnionType {
163
+ const inner = this.mapPythonType(type.type, context);
164
+ return {
165
+ kind: 'union',
166
+ types: [inner, { kind: 'primitive', name: 'null' }],
167
+ };
168
+ }
169
+
170
+ mapGenericType(type: PyGenericType, context: MappingContext = 'value'): TSGenericType {
171
+ return {
172
+ kind: 'generic',
173
+ name: type.name,
174
+ typeArgs: type.typeArgs.map(t => this.mapPythonType(t, context)),
175
+ };
176
+ }
177
+
178
+ mapCustomType(
179
+ type: { kind: 'custom'; name: string; module?: string },
180
+ _context: MappingContext = 'value'
181
+ ): TypescriptType {
182
+ // Normalize some known typing names into TS primitives/generics
183
+ const name = type.name;
184
+ const fullName = type.module ? `${type.module}.${name}` : name;
185
+
186
+ // Top and bottom types
187
+ if (name === 'Any' || fullName === 'typing.Any') {
188
+ return { kind: 'primitive', name: 'unknown' };
189
+ }
190
+ if (
191
+ name === 'Never' ||
192
+ fullName === 'typing.Never' ||
193
+ name === 'NoReturn' ||
194
+ fullName === 'typing.NoReturn'
195
+ ) {
196
+ return { kind: 'primitive', name: 'never' };
197
+ }
198
+
199
+ // String types
200
+ if (name === 'LiteralString' || fullName === 'typing.LiteralString') {
201
+ return { kind: 'primitive', name: 'string' };
202
+ }
203
+ if (name === 'AnyStr' || fullName === 'typing.AnyStr') {
204
+ return { kind: 'primitive', name: 'string' };
205
+ }
206
+
207
+ // Object types
208
+ if (name === 'object' || fullName === 'builtins.object') {
209
+ return { kind: 'primitive', name: 'object' };
210
+ }
211
+
212
+ // Callable types
213
+ if (name === 'Callable' || fullName === 'typing.Callable') {
214
+ return {
215
+ kind: 'function',
216
+ isAsync: false,
217
+ parameters: [
218
+ {
219
+ name: 'args',
220
+ type: { kind: 'array', elementType: { kind: 'primitive', name: 'unknown' } },
221
+ optional: false,
222
+ rest: true,
223
+ },
224
+ ],
225
+ returnType: { kind: 'primitive', name: 'unknown' },
226
+ };
227
+ }
228
+
229
+ // Async types
230
+ if (name === 'Awaitable' || fullName === 'typing.Awaitable') {
231
+ return {
232
+ kind: 'generic',
233
+ name: 'Promise',
234
+ typeArgs: [{ kind: 'primitive', name: 'unknown' }],
235
+ };
236
+ }
237
+ if (name === 'Coroutine' || fullName === 'typing.Coroutine') {
238
+ return {
239
+ kind: 'generic',
240
+ name: 'Promise',
241
+ typeArgs: [{ kind: 'primitive', name: 'unknown' }],
242
+ };
243
+ }
244
+
245
+ // Collection types that should be generics
246
+ if (name === 'Sequence' || fullName === 'typing.Sequence') {
247
+ return {
248
+ kind: 'generic',
249
+ name: 'Array',
250
+ typeArgs: [{ kind: 'primitive', name: 'unknown' }],
251
+ };
252
+ }
253
+ if (name === 'Mapping' || fullName === 'typing.Mapping') {
254
+ return {
255
+ kind: 'object',
256
+ properties: [],
257
+ indexSignature: {
258
+ keyType: { kind: 'primitive', name: 'string' },
259
+ valueType: { kind: 'primitive', name: 'unknown' },
260
+ },
261
+ };
262
+ }
263
+
264
+ const presetType = this.mapPresetType(type);
265
+ if (presetType) {
266
+ return presetType;
267
+ }
268
+
269
+ // Forward references and user types
270
+ return { kind: 'custom', name: type.name, module: type.module };
271
+ }
272
+
273
+ mapCallableType(type: {
274
+ kind: 'callable';
275
+ parameters: PythonType[];
276
+ returnType: PythonType;
277
+ }): TSFunctionType {
278
+ // Support Callable[[...], R] → (...args: unknown[]) => R
279
+ const onlyEllipsis =
280
+ type.parameters.length === 1 &&
281
+ type.parameters[0]?.kind === 'custom' &&
282
+ (type.parameters[0] as { kind: 'custom'; name: string }).name === '...';
283
+
284
+ return {
285
+ kind: 'function',
286
+ isAsync: false,
287
+ parameters: onlyEllipsis
288
+ ? ([
289
+ {
290
+ name: 'args',
291
+ type: { kind: 'array', elementType: { kind: 'primitive', name: 'unknown' } },
292
+ optional: false,
293
+ rest: true,
294
+ },
295
+ ] as const satisfies TSFunctionType['parameters'])
296
+ : type.parameters.map((p, i) => ({
297
+ name: `arg${i}`,
298
+ type: this.mapPythonType(p, 'value'),
299
+ optional: false,
300
+ rest: false,
301
+ })),
302
+ returnType: this.mapPythonType(type.returnType, 'return'),
303
+ } satisfies TSFunctionType;
304
+ }
305
+
306
+ mapLiteralType(type: {
307
+ kind: 'literal';
308
+ value: string | number | boolean | null;
309
+ }): TSLiteralType {
310
+ return { kind: 'literal', value: type.value };
311
+ }
312
+
313
+ mapTypeVarType(type: PyTypeVarType, _context: MappingContext = 'value'): TSCustomType {
314
+ // TypeVar maps to a generic type parameter in TypeScript
315
+ // Bounds and constraints are not directly expressible in TypeScript type system
316
+ return {
317
+ kind: 'custom',
318
+ name: type.name,
319
+ module: 'typing',
320
+ };
321
+ }
322
+
323
+ mapFinalType(type: PyFinalType, context: MappingContext = 'value'): TypescriptType {
324
+ // Final[T] maps to T in TypeScript (no direct Final equivalent)
325
+ // The Final qualifier is more of a static analysis hint
326
+ return this.mapPythonType(type.type, context);
327
+ }
328
+
329
+ mapClassVarType(type: PyClassVarType, context: MappingContext = 'value'): TypescriptType {
330
+ // ClassVar[T] maps to T in TypeScript (class variables are just properties)
331
+ // The ClassVar qualifier is more of a static analysis hint
332
+ return this.mapPythonType(type.type, context);
333
+ }
334
+
335
+ private asIndexKeyType(key: TypescriptType): TSPrimitiveType {
336
+ if (key.kind === 'primitive' && (key.name === 'string' || key.name === 'number')) {
337
+ return key;
338
+ }
339
+ return { kind: 'primitive', name: 'string' };
340
+ }
341
+
342
+ private hasPreset(name: TypePreset): boolean {
343
+ return this.presets.has(name);
344
+ }
345
+
346
+ private normalizeCustomType(type: { name: string; module?: string }): {
347
+ name: string;
348
+ module?: string;
349
+ rawName: string;
350
+ } {
351
+ const rawName = type.name;
352
+ if (type.module) {
353
+ return { name: type.name, module: type.module, rawName };
354
+ }
355
+ if (rawName.includes('.')) {
356
+ const parts = rawName.split('.');
357
+ return {
358
+ name: parts[parts.length - 1] ?? rawName,
359
+ module: parts.slice(0, -1).join('.'),
360
+ rawName,
361
+ };
362
+ }
363
+ return { name: rawName, module: undefined, rawName };
364
+ }
365
+
366
+ private mapPresetType(type: { name: string; module?: string }): TypescriptType | undefined {
367
+ const normalized = this.normalizeCustomType(type);
368
+ const name = normalized.name;
369
+ const moduleName = normalized.module;
370
+ const stringType: TSPrimitiveType = { kind: 'primitive', name: 'string' };
371
+ const numberType: TSPrimitiveType = { kind: 'primitive', name: 'number' };
372
+ const unknownType: TSPrimitiveType = { kind: 'primitive', name: 'unknown' };
373
+ const numberArray: TSArrayType = { kind: 'array', elementType: numberType };
374
+ const unknownArray: TSArrayType = { kind: 'array', elementType: unknownType };
375
+ const recordObject: TSObjectType = {
376
+ kind: 'object',
377
+ properties: [],
378
+ indexSignature: {
379
+ keyType: stringType,
380
+ valueType: unknownType,
381
+ },
382
+ };
383
+ const prop = (
384
+ propName: string,
385
+ typeValue: TypescriptType,
386
+ optional = false
387
+ ): TSObjectType['properties'][number] => ({
388
+ name: propName,
389
+ type: typeValue,
390
+ optional,
391
+ readonly: false,
392
+ });
393
+
394
+ if (this.hasPreset('stdlib')) {
395
+ const stdlibModule = moduleName ?? '';
396
+ const allowModule =
397
+ !moduleName ||
398
+ stdlibModule === 'datetime' ||
399
+ stdlibModule === 'decimal' ||
400
+ stdlibModule === 'uuid' ||
401
+ stdlibModule === 'pathlib';
402
+ if (allowModule) {
403
+ if (name === 'datetime' || name === 'date' || name === 'time') {
404
+ return { kind: 'primitive', name: 'string' };
405
+ }
406
+ if (name === 'timedelta') {
407
+ return { kind: 'primitive', name: 'number' };
408
+ }
409
+ if (name === 'Decimal' || name === 'UUID') {
410
+ return { kind: 'primitive', name: 'string' };
411
+ }
412
+ if (
413
+ name === 'Path' ||
414
+ name === 'PurePath' ||
415
+ name === 'PosixPath' ||
416
+ name === 'WindowsPath'
417
+ ) {
418
+ return { kind: 'primitive', name: 'string' };
419
+ }
420
+ }
421
+ }
422
+
423
+ if (this.hasPreset('pandas')) {
424
+ const allowModule = !moduleName || moduleName.startsWith('pandas');
425
+ if (allowModule) {
426
+ if (name === 'DataFrame') {
427
+ const recordsArray: TSArrayType = { kind: 'array', elementType: recordObject };
428
+ return { kind: 'union', types: [recordObject, recordsArray] };
429
+ }
430
+ if (name === 'Series') {
431
+ const valuesArray: TSArrayType = {
432
+ kind: 'array',
433
+ elementType: { kind: 'primitive', name: 'unknown' },
434
+ };
435
+ return { kind: 'union', types: [valuesArray, recordObject] };
436
+ }
437
+ }
438
+ }
439
+
440
+ if (this.hasPreset('scipy')) {
441
+ const allowModule = !moduleName || moduleName.startsWith('scipy');
442
+ if (allowModule) {
443
+ const baseProps = [prop('shape', numberArray), prop('dtype', stringType, true)];
444
+ const buildSparse = (
445
+ format: 'csr' | 'csc' | 'coo'
446
+ ): TSObjectType => ({
447
+ kind: 'object',
448
+ properties: [
449
+ prop('format', { kind: 'literal', value: format }),
450
+ ...baseProps,
451
+ prop('data', unknownArray),
452
+ ...(format === 'coo'
453
+ ? [prop('row', numberArray), prop('col', numberArray)]
454
+ : [prop('indices', numberArray), prop('indptr', numberArray)]),
455
+ ],
456
+ });
457
+ if (name === 'csr_matrix') {
458
+ return buildSparse('csr');
459
+ }
460
+ if (name === 'csc_matrix') {
461
+ return buildSparse('csc');
462
+ }
463
+ if (name === 'coo_matrix') {
464
+ return buildSparse('coo');
465
+ }
466
+ if (name === 'spmatrix') {
467
+ return { kind: 'union', types: [buildSparse('csr'), buildSparse('csc'), buildSparse('coo')] };
468
+ }
469
+ }
470
+ }
471
+
472
+ if (this.hasPreset('torch')) {
473
+ const allowModule = !moduleName || moduleName.startsWith('torch');
474
+ if (allowModule && name === 'Tensor') {
475
+ return {
476
+ kind: 'object',
477
+ properties: [
478
+ prop('data', unknownType),
479
+ prop('shape', numberArray),
480
+ prop('dtype', stringType, true),
481
+ prop('device', stringType, true),
482
+ ],
483
+ };
484
+ }
485
+ }
486
+
487
+ if (this.hasPreset('sklearn')) {
488
+ const allowModule = !moduleName || moduleName.startsWith('sklearn');
489
+ if (allowModule && name === 'BaseEstimator') {
490
+ return {
491
+ kind: 'object',
492
+ properties: [
493
+ prop('className', stringType),
494
+ prop('module', stringType),
495
+ prop('version', stringType, true),
496
+ prop('params', recordObject),
497
+ ],
498
+ };
499
+ }
500
+ }
501
+
502
+ return undefined;
503
+ }
504
+ }