pyodide 0.19.0 → 0.19.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.
@@ -1,4 +1,4 @@
1
- // This file is generated by applying the C preprocessor to core/pyproxy.js
1
+ // This file is generated by applying the C preprocessor to core/pyproxy.ts
2
2
  // It uses the macros defined in core/pyproxy.c
3
3
  // Do not edit it directly!
4
4
 
@@ -21,112 +21,6 @@
21
21
 
22
22
 
23
23
 
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
85
-
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
-
94
-
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
-
124
-
125
-
126
-
127
-
128
-
129
-
130
24
  /**
131
25
  * Every public Python entrypoint goes through this file! The main entrypoint is
132
26
  * the callPyObject method, but of course one can also execute arbitrary code
@@ -140,33 +34,34 @@
140
34
  * any macros available in pyproxy.c are available here. We only need the flags
141
35
  * macros HAS_LENGTH, etc.
142
36
  *
143
- * See Makefile recipe for src/js/pyproxy.js
37
+ * See Makefile recipe for src/js/pyproxy.gen.ts
144
38
  */
145
-
146
- import { Module } from "./module.js";
147
-
39
+ import { Module, API, Hiwire } from "./module.js";
148
40
  /**
149
41
  * Is the argument a :any:`PyProxy`?
150
- * @param jsobj {any} Object to test.
151
- * @returns {jsobj is PyProxy} Is ``jsobj`` a :any:`PyProxy`?
42
+ * @param jsobj Object to test.
43
+ * @returns Is ``jsobj`` a :any:`PyProxy`?
152
44
  */
153
- export function isPyProxy(jsobj) {
45
+ export function isPyProxy(jsobj: any): jsobj is PyProxy {
154
46
  return !!jsobj && jsobj.$$ !== undefined && jsobj.$$.type === "PyProxy";
155
47
  }
156
- Module.isPyProxy = isPyProxy;
157
-
48
+ API.isPyProxy = isPyProxy;
49
+ declare var FinalizationRegistry: any;
50
+ declare var globalThis: any;
158
51
  if (globalThis.FinalizationRegistry) {
159
- Module.finalizationRegistry = new FinalizationRegistry(([ptr, cache]) => {
160
- cache.leaked = (!!1);
161
- pyproxy_decref_cache(cache);
162
- try {
163
- Module._Py_DecRef(ptr);
164
- } catch (e) {
165
- // I'm not really sure what happens if an error occurs inside of a
166
- // finalizer...
167
- Module.fatal_error(e);
52
+ Module.finalizationRegistry = new FinalizationRegistry(
53
+ ([ptr, cache]: [ptr: number, cache: PyProxyCache]) => {
54
+ cache.leaked = (!!1);
55
+ pyproxy_decref_cache(cache);
56
+ try {
57
+ Module._Py_DecRef(ptr);
58
+ } catch (e) {
59
+ // I'm not really sure what happens if an error occurs inside of a
60
+ // finalizer...
61
+ API.fatal_error(e);
62
+ }
168
63
  }
169
- });
64
+ );
170
65
  // For some unclear reason this code screws up selenium FirefoxDriver. Works
171
66
  // fine in chrome and when I test it in browser. It seems to be sensitive to
172
67
  // changes that don't make a difference to the semantics.
@@ -176,35 +71,33 @@ if (globalThis.FinalizationRegistry) {
176
71
  // Module._PyBuffer_Release(ptr);
177
72
  // Module._PyMem_Free(ptr);
178
73
  // } catch (e) {
179
- // Module.fatal_error(e);
74
+ // API.fatal_error(e);
180
75
  // }
181
76
  // });
182
77
  } else {
183
78
  Module.finalizationRegistry = { register() {}, unregister() {} };
184
79
  // Module.bufferFinalizationRegistry = finalizationRegistry;
185
80
  }
186
-
187
81
  let pyproxy_alloc_map = new Map();
188
82
  Module.pyproxy_alloc_map = pyproxy_alloc_map;
189
- let trace_pyproxy_alloc;
190
- let trace_pyproxy_dealloc;
191
-
83
+ let trace_pyproxy_alloc: (proxy: any) => void;
84
+ let trace_pyproxy_dealloc: (proxy: any) => void;
192
85
  Module.enable_pyproxy_allocation_tracing = function () {
193
- trace_pyproxy_alloc = function (proxy) {
86
+ trace_pyproxy_alloc = function (proxy: any) {
194
87
  pyproxy_alloc_map.set(proxy, Error().stack);
195
88
  };
196
- trace_pyproxy_dealloc = function (proxy) {
89
+ trace_pyproxy_dealloc = function (proxy: any) {
197
90
  pyproxy_alloc_map.delete(proxy);
198
91
  };
199
92
  };
200
93
  Module.disable_pyproxy_allocation_tracing = function () {
201
- trace_pyproxy_alloc = function (proxy) {};
202
- trace_pyproxy_dealloc = function (proxy) {};
94
+ trace_pyproxy_alloc = function (proxy: any) {};
95
+ trace_pyproxy_dealloc = function (proxy: any) {};
203
96
  };
204
97
  Module.disable_pyproxy_allocation_tracing();
205
-
98
+ type PyProxyCache = { cacheId: number; refcnt: number; leaked?: boolean };
206
99
  /**
207
- * Create a new PyProxy wraping ptrobj which is a PyObject*.
100
+ * Create a new PyProxy wrapping ptrobj which is a PyObject*.
208
101
  *
209
102
  * The argument cache is only needed to implement the PyProxy.copy API, it
210
103
  * allows the copy of the PyProxy to share its attribute cache with the original
@@ -216,7 +109,7 @@ Module.disable_pyproxy_allocation_tracing();
216
109
  * many as possible.
217
110
  * @private
218
111
  */
219
- Module.pyproxy_new = function (ptrobj, cache) {
112
+ Module.pyproxy_new = function (ptrobj: number, cache?: PyProxyCache) {
220
113
  let flags = Module._pyproxy_getflags(ptrobj);
221
114
  let cls = Module.getPyProxyClass(flags);
222
115
  // Reflect.construct calls the constructor of Module.PyProxyClass but sets
@@ -241,7 +134,7 @@ Module.pyproxy_new = function (ptrobj, cache) {
241
134
  if (!cache) {
242
135
  // The cache needs to be accessed primarily from the C function
243
136
  // _pyproxy_getattr so we make a hiwire id.
244
- let cacheId = Module.hiwire.new_value(new Map());
137
+ let cacheId = Hiwire.new_value(new Map());
245
138
  cache = { cacheId, refcnt: 0 };
246
139
  }
247
140
  cache.refcnt++;
@@ -254,33 +147,24 @@ Module.pyproxy_new = function (ptrobj, cache) {
254
147
  Module.finalizationRegistry.register(proxy, [ptrobj, cache], proxy);
255
148
  return proxy;
256
149
  };
257
-
258
- function _getPtr(jsobj) {
259
- let ptr = jsobj.$$.ptr;
260
- if (ptr === null) {
261
- throw new Error(
262
- jsobj.$$.destroyed_msg || "Object has already been destroyed"
263
- );
150
+ function _getPtr(jsobj: any) {
151
+ let ptr: number = jsobj.$$.ptr;
152
+ if (ptr === 0) {
153
+ throw new Error(jsobj.$$.destroyed_msg);
264
154
  }
265
155
  return ptr;
266
156
  }
267
-
268
157
  let pyproxyClassMap = new Map();
269
158
  /**
270
- * Retreive the appropriate mixins based on the features requested in flags.
159
+ * Retrieve the appropriate mixins based on the features requested in flags.
271
160
  * Used by pyproxy_new. The "flags" variable is produced by the C function
272
161
  * pyproxy_getflags. Multiple PyProxies with the same set of feature flags
273
162
  * will share the same prototype, so the memory footprint of each individual
274
163
  * PyProxy is minimal.
275
164
  * @private
276
165
  */
277
- Module.getPyProxyClass = function (flags) {
278
- let result = pyproxyClassMap.get(flags);
279
- if (result) {
280
- return result;
281
- }
282
- let descriptors = {};
283
- for (let [feature_flag, methods] of [
166
+ Module.getPyProxyClass = function (flags: number) {
167
+ const FLAG_TYPE_PAIRS: [number, any][] = [
284
168
  [(1 << 0), PyProxyLengthMethods],
285
169
  [(1 << 1), PyProxyGetItemMethods],
286
170
  [(1 << 2), PyProxySetItemMethods],
@@ -290,7 +174,13 @@ Module.getPyProxyClass = function (flags) {
290
174
  [(1 << 6), PyProxyAwaitableMethods],
291
175
  [(1 << 7), PyProxyBufferMethods],
292
176
  [(1 << 8), PyProxyCallableMethods],
293
- ]) {
177
+ ];
178
+ let result = pyproxyClassMap.get(flags);
179
+ if (result) {
180
+ return result;
181
+ }
182
+ let descriptors: any = {};
183
+ for (let [feature_flag, methods] of FLAG_TYPE_PAIRS) {
294
184
  if (flags & feature_flag) {
295
185
  Object.assign(
296
186
  descriptors,
@@ -313,54 +203,64 @@ Module.getPyProxyClass = function (flags) {
313
203
  pyproxyClassMap.set(flags, NewPyProxyClass);
314
204
  return NewPyProxyClass;
315
205
  };
316
-
317
206
  // Static methods
318
207
  Module.PyProxy_getPtr = _getPtr;
319
-
320
208
  const pyproxy_cache_destroyed_msg =
321
209
  "This borrowed attribute proxy was automatically destroyed in the " +
322
210
  "process of destroying the proxy it was borrowed from. Try using the 'copy' method.";
323
-
324
- function pyproxy_decref_cache(cache) {
211
+ function pyproxy_decref_cache(cache: PyProxyCache) {
325
212
  if (!cache) {
326
213
  return;
327
214
  }
328
215
  cache.refcnt--;
329
216
  if (cache.refcnt === 0) {
330
- let cache_map = Module.hiwire.pop_value(cache.cacheId);
217
+ let cache_map = Hiwire.pop_value(cache.cacheId);
331
218
  for (let proxy_id of cache_map.values()) {
332
- const cache_entry = Module.hiwire.pop_value(proxy_id);
219
+ const cache_entry = Hiwire.pop_value(proxy_id);
333
220
  if (!cache.leaked) {
334
221
  Module.pyproxy_destroy(cache_entry, pyproxy_cache_destroyed_msg);
335
222
  }
336
223
  }
337
224
  }
338
225
  }
339
-
340
- Module.pyproxy_destroy = function (proxy, destroyed_msg) {
341
- if (proxy.$$.ptr === null) {
226
+ Module.pyproxy_destroy = function (proxy: PyProxy, destroyed_msg: string) {
227
+ if (proxy.$$.ptr === 0) {
342
228
  return;
343
229
  }
344
230
  let ptrobj = _getPtr(proxy);
345
231
  Module.finalizationRegistry.unregister(proxy);
232
+ destroyed_msg = destroyed_msg || "Object has already been destroyed";
233
+ let proxy_type = proxy.type;
234
+ let proxy_repr;
235
+ try {
236
+ proxy_repr = proxy.toString();
237
+ } catch (e) {
238
+ if (e.pyodide_fatal_error) {
239
+ throw e;
240
+ }
241
+ }
346
242
  // Maybe the destructor will call JavaScript code that will somehow try
347
243
  // to use this proxy. Mark it deleted before decrementing reference count
348
244
  // just in case!
349
- proxy.$$.ptr = null;
245
+ proxy.$$.ptr = 0;
246
+ destroyed_msg += "\n" + `The object was of type "${proxy_type}" and `;
247
+ if (proxy_repr) {
248
+ destroyed_msg += `had repr "${proxy_repr}"`;
249
+ } else {
250
+ destroyed_msg += "an error was raised when trying to generate its repr";
251
+ }
350
252
  proxy.$$.destroyed_msg = destroyed_msg;
351
253
  pyproxy_decref_cache(proxy.$$.cache);
352
254
  try {
353
255
  Module._Py_DecRef(ptrobj);
354
256
  trace_pyproxy_dealloc(proxy);
355
257
  } catch (e) {
356
- Module.fatal_error(e);
258
+ API.fatal_error(e);
357
259
  }
358
260
  };
359
-
360
261
  // Now a lot of boilerplate to wrap the abstract Object protocol wrappers
361
262
  // defined in pyproxy.c in JavaScript functions.
362
-
363
- Module.callPyObjectKwargs = function (ptrobj, ...jsargs) {
263
+ Module.callPyObjectKwargs = function (ptrobj: number, ...jsargs: any) {
364
264
  // We don't do any checking for kwargs, checks are in PyProxy.callKwargs
365
265
  // which only is used when the keyword arguments come from the user.
366
266
  let kwargs = jsargs.pop();
@@ -369,9 +269,8 @@ Module.callPyObjectKwargs = function (ptrobj, ...jsargs) {
369
269
  let kwargs_values = Object.values(kwargs);
370
270
  let num_kwargs = kwargs_names.length;
371
271
  jsargs.push(...kwargs_values);
372
-
373
- let idargs = Module.hiwire.new_value(jsargs);
374
- let idkwnames = Module.hiwire.new_value(kwargs_names);
272
+ let idargs = Hiwire.new_value(jsargs);
273
+ let idkwnames = Hiwire.new_value(kwargs_names);
375
274
  let idresult;
376
275
  try {
377
276
  idresult = Module.__pyproxy_apply(
@@ -382,30 +281,27 @@ Module.callPyObjectKwargs = function (ptrobj, ...jsargs) {
382
281
  num_kwargs
383
282
  );
384
283
  } catch (e) {
385
- Module.fatal_error(e);
284
+ API.fatal_error(e);
386
285
  } finally {
387
- Module.hiwire.decref(idargs);
388
- Module.hiwire.decref(idkwnames);
286
+ Hiwire.decref(idargs);
287
+ Hiwire.decref(idkwnames);
389
288
  }
390
289
  if (idresult === 0) {
391
290
  Module._pythonexc2js();
392
291
  }
393
- return Module.hiwire.pop_value(idresult);
292
+ return Hiwire.pop_value(idresult);
394
293
  };
395
-
396
- Module.callPyObject = function (ptrobj, ...jsargs) {
294
+ Module.callPyObject = function (ptrobj: number, ...jsargs: any) {
397
295
  return Module.callPyObjectKwargs(ptrobj, ...jsargs, {});
398
296
  };
399
-
400
- /**
401
- * @typedef {(PyProxyClass & {[x : string] : Py2JsResult})} PyProxy
402
- * @typedef { PyProxy | number | bigint | string | boolean | undefined } Py2JsResult
403
- */
404
- class PyProxyClass {
297
+ export type PyProxy = PyProxyClass & { [x: string]: any };
298
+ export class PyProxyClass {
299
+ $$: { ptr: number; cache: PyProxyCache; destroyed_msg?: string };
300
+ $$flags: number;
301
+ /** @private */
405
302
  constructor() {
406
303
  throw new TypeError("PyProxy is not a constructor");
407
304
  }
408
-
409
305
  get [Symbol.toStringTag]() {
410
306
  return "PyProxy";
411
307
  }
@@ -423,51 +319,45 @@ class PyProxyClass {
423
319
  * else:
424
320
  * ty.__module__ + "." + ty.__name__
425
321
  *
426
- * @type {string}
427
322
  */
428
- get type() {
323
+ get type(): string {
429
324
  let ptrobj = _getPtr(this);
430
- return Module.hiwire.pop_value(Module.__pyproxy_type(ptrobj));
325
+ return Hiwire.pop_value(Module.__pyproxy_type(ptrobj));
431
326
  }
432
- /**
433
- * @returns {string}
434
- */
435
- toString() {
327
+ toString(): string {
436
328
  let ptrobj = _getPtr(this);
437
329
  let jsref_repr;
438
330
  try {
439
331
  jsref_repr = Module.__pyproxy_repr(ptrobj);
440
332
  } catch (e) {
441
- Module.fatal_error(e);
333
+ API.fatal_error(e);
442
334
  }
443
335
  if (jsref_repr === 0) {
444
336
  Module._pythonexc2js();
445
337
  }
446
- return Module.hiwire.pop_value(jsref_repr);
338
+ return Hiwire.pop_value(jsref_repr);
447
339
  }
448
340
  /**
449
- * Destroy the ``PyProxy``. This will release the memory. Any further
450
- * attempt to use the object will raise an error.
341
+ * Destroy the ``PyProxy``. This will release the memory. Any further attempt
342
+ * to use the object will raise an error.
451
343
  *
452
344
  * In a browser supporting `FinalizationRegistry
453
345
  * <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/FinalizationRegistry>`_
454
346
  * Pyodide will automatically destroy the ``PyProxy`` when it is garbage
455
- * collected, however there is no guarantee that the finalizer will be run
456
- * in a timely manner so it is better to ``destroy`` the proxy explicitly.
347
+ * collected, however there is no guarantee that the finalizer will be run in
348
+ * a timely manner so it is better to ``destroy`` the proxy explicitly.
457
349
  *
458
- * @param {string} [destroyed_msg] The error message to print if use is
459
- * attempted after destroying. Defaults to "Object has already been
460
- * destroyed".
350
+ * @param destroyed_msg The error message to print if use is attempted after
351
+ * destroying. Defaults to "Object has already been destroyed".
461
352
  */
462
- destroy(destroyed_msg) {
353
+ destroy(destroyed_msg?: string) {
463
354
  Module.pyproxy_destroy(this, destroyed_msg);
464
355
  }
465
356
  /**
466
357
  * Make a new PyProxy pointing to the same Python object.
467
358
  * Useful if the PyProxy is destroyed somewhere else.
468
- * @returns {PyProxy}
469
359
  */
470
- copy() {
360
+ copy(): PyProxy {
471
361
  let ptrobj = _getPtr(this);
472
362
  return Module.pyproxy_new(ptrobj, this.$$.cache);
473
363
  }
@@ -476,125 +366,141 @@ class PyProxyClass {
476
366
  * default does a deep conversion, if a shallow conversion is desired, you can
477
367
  * use ``proxy.toJs({depth : 1})``. See :ref:`Explicit Conversion of PyProxy
478
368
  * <type-translations-pyproxy-to-js>` for more info.
479
- *
480
- * @param {object} options
481
- * @param {number} [options.depth] How many layers deep to perform the
482
- * conversion. Defaults to infinite.
483
- * @param {array} [options.pyproxies] If provided, ``toJs`` will store all
484
- * PyProxies created in this list. This allows you to easily destroy all the
485
- * PyProxies by iterating the list without having to recurse over the
486
- * generated structure. The most common use case is to create a new empty
487
- * list, pass the list as `pyproxies`, and then later iterate over `pyproxies`
488
- * to destroy all of created proxies.
489
- * @param {boolean} [options.create_pyproxies] If false, ``toJs`` will throw a
490
- * ``ConversionError`` rather than producing a ``PyProxy``.
491
- * @param {boolean} [options.dict_converter] A function to be called on an
492
- * iterable of pairs ``[key, value]``. Convert this iterable of pairs to the
493
- * desired output. For instance, ``Object.fromEntries`` would convert the dict
494
- * to an object, ``Array.from`` converts it to an array of entries, and ``(it) =>
495
- * new Map(it)`` converts it to a ``Map`` (which is the default behavior).
496
- * @return {any} The JavaScript object resulting from the conversion.
369
+ * @param options
370
+ * @return The JavaScript object resulting from the conversion.
497
371
  */
498
372
  toJs({
499
373
  depth = -1,
500
- pyproxies,
374
+ pyproxies = undefined,
501
375
  create_pyproxies = (!!1),
502
- dict_converter,
503
- } = {}) {
376
+ dict_converter = undefined,
377
+ default_converter = undefined,
378
+ }: {
379
+ /** How many layers deep to perform the conversion. Defaults to infinite */
380
+ depth?: number;
381
+ /**
382
+ * If provided, ``toJs`` will store all PyProxies created in this list. This
383
+ * allows you to easily destroy all the PyProxies by iterating the list
384
+ * without having to recurse over the generated structure. The most common
385
+ * use case is to create a new empty list, pass the list as `pyproxies`, and
386
+ * then later iterate over `pyproxies` to destroy all of created proxies.
387
+ */
388
+ pyproxies?: PyProxy[];
389
+ /**
390
+ * If false, ``toJs`` will throw a ``ConversionError`` rather than
391
+ * producing a ``PyProxy``.
392
+ */
393
+ create_pyproxies?: boolean;
394
+ /**
395
+ * A function to be called on an iterable of pairs ``[key, value]``. Convert
396
+ * this iterable of pairs to the desired output. For instance,
397
+ * ``Object.fromEntries`` would convert the dict to an object, ``Array.from``
398
+ * converts it to an array of entries, and ``(it) => new Map(it)`` converts
399
+ * it to a ``Map`` (which is the default behavior).
400
+ */
401
+ dict_converter?: (array: Iterable<[key: string, value: any]>) => any;
402
+ /**
403
+ * Optional argument to convert objects with no default conversion. See the
404
+ * documentation of :any:`pyodide.to_js`.
405
+ */
406
+ default_converter?: (
407
+ obj: PyProxy,
408
+ convert: (obj: PyProxy) => any,
409
+ cacheConversion: (obj: PyProxy, result: any) => void
410
+ ) => any;
411
+ } = {}): any {
504
412
  let ptrobj = _getPtr(this);
505
413
  let idresult;
506
414
  let proxies_id;
507
415
  let dict_converter_id = 0;
416
+ let default_converter_id = 0;
508
417
  if (!create_pyproxies) {
509
418
  proxies_id = 0;
510
419
  } else if (pyproxies) {
511
- proxies_id = Module.hiwire.new_value(pyproxies);
420
+ proxies_id = Hiwire.new_value(pyproxies);
512
421
  } else {
513
- proxies_id = Module.hiwire.new_value([]);
422
+ proxies_id = Hiwire.new_value([]);
514
423
  }
515
424
  if (dict_converter) {
516
- dict_converter_id = Module.hiwire.new_value(dict_converter);
425
+ dict_converter_id = Hiwire.new_value(dict_converter);
426
+ }
427
+ if (default_converter) {
428
+ default_converter_id = Hiwire.new_value(default_converter);
517
429
  }
518
430
  try {
519
- idresult = Module._python2js_custom_dict_converter(
431
+ idresult = Module._python2js_custom(
520
432
  ptrobj,
521
433
  depth,
522
434
  proxies_id,
523
- dict_converter_id
435
+ dict_converter_id,
436
+ default_converter_id
524
437
  );
525
438
  } catch (e) {
526
- Module.fatal_error(e);
439
+ API.fatal_error(e);
527
440
  } finally {
528
- Module.hiwire.decref(proxies_id);
529
- Module.hiwire.decref(dict_converter_id);
441
+ Hiwire.decref(proxies_id);
442
+ Hiwire.decref(dict_converter_id);
443
+ Hiwire.decref(default_converter_id);
530
444
  }
531
445
  if (idresult === 0) {
532
446
  Module._pythonexc2js();
533
447
  }
534
- return Module.hiwire.pop_value(idresult);
448
+ return Hiwire.pop_value(idresult);
535
449
  }
536
450
  /**
537
451
  * Check whether the :any:`PyProxy.length` getter is available on this PyProxy. A
538
452
  * Typescript type guard.
539
- * @returns {this is PyProxyWithLength}
540
453
  */
541
- supportsLength() {
454
+ supportsLength(): this is PyProxyWithLength {
542
455
  return !!(this.$$flags & (1 << 0));
543
456
  }
544
457
  /**
545
458
  * Check whether the :any:`PyProxy.get` method is available on this PyProxy. A
546
459
  * Typescript type guard.
547
- * @returns {this is PyProxyWithGet}
548
460
  */
549
- supportsGet() {
461
+ supportsGet(): this is PyProxyWithGet {
550
462
  return !!(this.$$flags & (1 << 1));
551
463
  }
552
464
  /**
553
465
  * Check whether the :any:`PyProxy.set` method is available on this PyProxy. A
554
466
  * Typescript type guard.
555
- * @returns {this is PyProxyWithSet}
556
467
  */
557
- supportsSet() {
468
+ supportsSet(): this is PyProxyWithSet {
558
469
  return !!(this.$$flags & (1 << 2));
559
470
  }
560
471
  /**
561
472
  * Check whether the :any:`PyProxy.has` method is available on this PyProxy. A
562
473
  * Typescript type guard.
563
- * @returns {this is PyProxyWithHas}
564
474
  */
565
- supportsHas() {
475
+ supportsHas(): this is PyProxyWithHas {
566
476
  return !!(this.$$flags & (1 << 3));
567
477
  }
568
478
  /**
569
479
  * Check whether the PyProxy is iterable. A Typescript type guard for
570
- * :any:`PyProxy.[Symbol.iterator]`.
571
- * @returns {this is PyProxyIterable}
480
+ * :any:`PyProxy.[iterator]`.
572
481
  */
573
- isIterable() {
482
+ isIterable(): this is PyProxyIterable {
574
483
  return !!(this.$$flags & ((1 << 4) | (1 << 5)));
575
484
  }
576
485
  /**
577
486
  * Check whether the PyProxy is iterable. A Typescript type guard for
578
487
  * :any:`PyProxy.next`.
579
- * @returns {this is PyProxyIterator}
580
488
  */
581
- isIterator() {
489
+ isIterator(): this is PyProxyIterator {
582
490
  return !!(this.$$flags & (1 << 5));
583
491
  }
584
492
  /**
585
493
  * Check whether the PyProxy is awaitable. A Typescript type guard, if this
586
494
  * function returns true Typescript considers the PyProxy to be a ``Promise``.
587
- * @returns {this is PyProxyAwaitable}
588
495
  */
589
- isAwaitable() {
496
+ isAwaitable(): this is PyProxyAwaitable {
590
497
  return !!(this.$$flags & (1 << 6));
591
498
  }
592
499
  /**
593
500
  * Check whether the PyProxy is a buffer. A Typescript type guard for
594
501
  * :any:`PyProxy.getBuffer`.
595
- * @returns {this is PyProxyBuffer}
596
502
  */
597
- isBuffer() {
503
+ isBuffer(): this is PyProxyBuffer {
598
504
  return !!(this.$$flags & (1 << 7));
599
505
  }
600
506
  /**
@@ -602,32 +508,27 @@ class PyProxyClass {
602
508
  * returns true then Typescript considers the Proxy to be callable of
603
509
  * signature ``(args... : any[]) => PyProxy | number | bigint | string |
604
510
  * boolean | undefined``.
605
- * @returns {this is PyProxyCallable}
606
511
  */
607
- isCallable() {
512
+ isCallable(): this is PyProxyCallable {
608
513
  return !!(this.$$flags & (1 << 8));
609
514
  }
610
515
  }
611
-
612
- /**
613
- * @typedef { PyProxy & PyProxyLengthMethods } PyProxyWithLength
614
- */
516
+ export type PyProxyWithLength = PyProxy & PyProxyLengthMethods;
615
517
  // Controlled by HAS_LENGTH, appears for any object with __len__ or sq_length
616
518
  // or mp_length methods
617
- class PyProxyLengthMethods {
519
+ export class PyProxyLengthMethods {
618
520
  /**
619
521
  * The length of the object.
620
522
  *
621
523
  * Present only if the proxied Python object has a ``__len__`` method.
622
- * @returns {number}
623
524
  */
624
- get length() {
525
+ get length(): number {
625
526
  let ptrobj = _getPtr(this);
626
527
  let length;
627
528
  try {
628
529
  length = Module._PyObject_Size(ptrobj);
629
530
  } catch (e) {
630
- Module.fatal_error(e);
531
+ API.fatal_error(e);
631
532
  }
632
533
  if (length === -1) {
633
534
  Module._pythonexc2js();
@@ -635,35 +536,28 @@ class PyProxyLengthMethods {
635
536
  return length;
636
537
  }
637
538
  }
638
-
639
- /**
640
- * @typedef {PyProxy & PyProxyGetItemMethods} PyProxyWithGet
641
- */
642
-
539
+ export type PyProxyWithGet = PyProxy & PyProxyGetItemMethods;
643
540
  // Controlled by HAS_GET, appears for any class with __getitem__,
644
541
  // mp_subscript, or sq_item methods
645
- /**
646
- * @interface
647
- */
648
- class PyProxyGetItemMethods {
542
+ export class PyProxyGetItemMethods {
649
543
  /**
650
544
  * This translates to the Python code ``obj[key]``.
651
545
  *
652
546
  * Present only if the proxied Python object has a ``__getitem__`` method.
653
547
  *
654
- * @param {any} key The key to look up.
655
- * @returns {Py2JsResult} The corresponding value.
548
+ * @param key The key to look up.
549
+ * @returns The corresponding value.
656
550
  */
657
- get(key) {
551
+ get(key: any): any {
658
552
  let ptrobj = _getPtr(this);
659
- let idkey = Module.hiwire.new_value(key);
553
+ let idkey = Hiwire.new_value(key);
660
554
  let idresult;
661
555
  try {
662
556
  idresult = Module.__pyproxy_getitem(ptrobj, idkey);
663
557
  } catch (e) {
664
- Module.fatal_error(e);
558
+ API.fatal_error(e);
665
559
  } finally {
666
- Module.hiwire.decref(idkey);
560
+ Hiwire.decref(idkey);
667
561
  }
668
562
  if (idresult === 0) {
669
563
  if (Module._PyErr_Occurred()) {
@@ -672,36 +566,33 @@ class PyProxyGetItemMethods {
672
566
  return undefined;
673
567
  }
674
568
  }
675
- return Module.hiwire.pop_value(idresult);
569
+ return Hiwire.pop_value(idresult);
676
570
  }
677
571
  }
678
-
679
- /**
680
- * @typedef {PyProxy & PyProxySetItemMethods} PyProxyWithSet
681
- */
572
+ export type PyProxyWithSet = PyProxy & PyProxySetItemMethods;
682
573
  // Controlled by HAS_SET, appears for any class with __setitem__, __delitem__,
683
574
  // mp_ass_subscript, or sq_ass_item.
684
- class PyProxySetItemMethods {
575
+ export class PyProxySetItemMethods {
685
576
  /**
686
577
  * This translates to the Python code ``obj[key] = value``.
687
578
  *
688
579
  * Present only if the proxied Python object has a ``__setitem__`` method.
689
580
  *
690
- * @param {any} key The key to set.
691
- * @param {any} value The value to set it to.
581
+ * @param key The key to set.
582
+ * @param value The value to set it to.
692
583
  */
693
- set(key, value) {
584
+ set(key: any, value: any) {
694
585
  let ptrobj = _getPtr(this);
695
- let idkey = Module.hiwire.new_value(key);
696
- let idval = Module.hiwire.new_value(value);
586
+ let idkey = Hiwire.new_value(key);
587
+ let idval = Hiwire.new_value(value);
697
588
  let errcode;
698
589
  try {
699
590
  errcode = Module.__pyproxy_setitem(ptrobj, idkey, idval);
700
591
  } catch (e) {
701
- Module.fatal_error(e);
592
+ API.fatal_error(e);
702
593
  } finally {
703
- Module.hiwire.decref(idkey);
704
- Module.hiwire.decref(idval);
594
+ Hiwire.decref(idkey);
595
+ Hiwire.decref(idval);
705
596
  }
706
597
  if (errcode === -1) {
707
598
  Module._pythonexc2js();
@@ -712,50 +603,46 @@ class PyProxySetItemMethods {
712
603
  *
713
604
  * Present only if the proxied Python object has a ``__delitem__`` method.
714
605
  *
715
- * @param {any} key The key to delete.
606
+ * @param key The key to delete.
716
607
  */
717
- delete(key) {
608
+ delete(key: any) {
718
609
  let ptrobj = _getPtr(this);
719
- let idkey = Module.hiwire.new_value(key);
610
+ let idkey = Hiwire.new_value(key);
720
611
  let errcode;
721
612
  try {
722
613
  errcode = Module.__pyproxy_delitem(ptrobj, idkey);
723
614
  } catch (e) {
724
- Module.fatal_error(e);
615
+ API.fatal_error(e);
725
616
  } finally {
726
- Module.hiwire.decref(idkey);
617
+ Hiwire.decref(idkey);
727
618
  }
728
619
  if (errcode === -1) {
729
620
  Module._pythonexc2js();
730
621
  }
731
622
  }
732
623
  }
733
-
734
- /**
735
- * @typedef {PyProxy & PyProxyContainsMethods} PyProxyWithHas
736
- */
737
-
624
+ export type PyProxyWithHas = PyProxy & PyProxyContainsMethods;
738
625
  // Controlled by HAS_CONTAINS flag, appears for any class with __contains__ or
739
626
  // sq_contains
740
- class PyProxyContainsMethods {
627
+ export class PyProxyContainsMethods {
741
628
  /**
742
629
  * This translates to the Python code ``key in obj``.
743
630
  *
744
631
  * Present only if the proxied Python object has a ``__contains__`` method.
745
632
  *
746
- * @param {*} key The key to check for.
747
- * @returns {boolean} Is ``key`` present?
633
+ * @param key The key to check for.
634
+ * @returns Is ``key`` present?
748
635
  */
749
- has(key) {
636
+ has(key: any): boolean {
750
637
  let ptrobj = _getPtr(this);
751
- let idkey = Module.hiwire.new_value(key);
638
+ let idkey = Hiwire.new_value(key);
752
639
  let result;
753
640
  try {
754
641
  result = Module.__pyproxy_contains(ptrobj, idkey);
755
642
  } catch (e) {
756
- Module.fatal_error(e);
643
+ API.fatal_error(e);
757
644
  } finally {
758
- Module.hiwire.decref(idkey);
645
+ Hiwire.decref(idkey);
759
646
  }
760
647
  if (result === -1) {
761
648
  Module._pythonexc2js();
@@ -763,7 +650,6 @@ class PyProxyContainsMethods {
763
650
  return result === 1;
764
651
  }
765
652
  }
766
-
767
653
  /**
768
654
  * A helper for [Symbol.iterator].
769
655
  *
@@ -780,14 +666,14 @@ class PyProxyContainsMethods {
780
666
  *
781
667
  * @private
782
668
  */
783
- function* iter_helper(iterptr, token) {
669
+ function* iter_helper(iterptr: number, token: {}): Generator<any> {
784
670
  try {
785
671
  let item;
786
672
  while ((item = Module.__pyproxy_iter_next(iterptr))) {
787
- yield Module.hiwire.pop_value(item);
673
+ yield Hiwire.pop_value(item);
788
674
  }
789
675
  } catch (e) {
790
- Module.fatal_error(e);
676
+ API.fatal_error(e);
791
677
  } finally {
792
678
  Module.finalizationRegistry.unregister(token);
793
679
  Module._Py_DecRef(iterptr);
@@ -796,16 +682,12 @@ function* iter_helper(iterptr, token) {
796
682
  Module._pythonexc2js();
797
683
  }
798
684
  }
799
-
800
- /**
801
- * @typedef {PyProxy & PyProxyIterableMethods} PyProxyIterable
802
- */
803
-
685
+ export type PyProxyIterable = PyProxy & PyProxyIterableMethods;
804
686
  // Controlled by IS_ITERABLE, appears for any object with __iter__ or tp_iter,
805
687
  // unless they are iterators. See: https://docs.python.org/3/c-api/iter.html
806
688
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols
807
689
  // This avoids allocating a PyProxy wrapper for the temporary iterator.
808
- class PyProxyIterableMethods {
690
+ export class PyProxyIterableMethods {
809
691
  /**
810
692
  * This translates to the Python code ``iter(obj)``. Return an iterator
811
693
  * associated to the proxy. See the documentation for `Symbol.iterator
@@ -815,117 +697,110 @@ class PyProxyIterableMethods {
815
697
  * ``__iter__`` method).
816
698
  *
817
699
  * This will be used implicitly by ``for(let x of proxy){}``.
818
- *
819
- * @returns {Iterator<Py2JsResult, Py2JsResult, any>} An iterator for the proxied Python object.
820
700
  */
821
- [Symbol.iterator]() {
701
+ [Symbol.iterator](): Iterator<any, any, any> {
822
702
  let ptrobj = _getPtr(this);
823
703
  let token = {};
824
704
  let iterptr;
825
705
  try {
826
706
  iterptr = Module._PyObject_GetIter(ptrobj);
827
707
  } catch (e) {
828
- Module.fatal_error(e);
708
+ API.fatal_error(e);
829
709
  }
830
710
  if (iterptr === 0) {
831
711
  Module._pythonexc2js();
832
712
  }
833
-
834
713
  let result = iter_helper(iterptr, token);
835
714
  Module.finalizationRegistry.register(result, [iterptr, undefined], token);
836
715
  return result;
837
716
  }
838
717
  }
839
-
840
- /**
841
- * @typedef {PyProxy & PyProxyIteratorMethods} PyProxyIterator
842
- */
843
-
718
+ export type PyProxyIterator = PyProxy & PyProxyIteratorMethods;
844
719
  // Controlled by IS_ITERATOR, appears for any object with a __next__ or
845
720
  // tp_iternext method.
846
- class PyProxyIteratorMethods {
721
+ export class PyProxyIteratorMethods {
722
+ /** @private */
847
723
  [Symbol.iterator]() {
848
724
  return this;
849
725
  }
850
726
  /**
851
- * This translates to the Python code ``next(obj)``. Returns the next value
852
- * of the generator. See the documentation for `Generator.prototype.next
727
+ * This translates to the Python code ``next(obj)``. Returns the next value of
728
+ * the generator. See the documentation for `Generator.prototype.next
853
729
  * <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next>`_.
854
730
  * The argument will be sent to the Python generator.
855
731
  *
856
732
  * This will be used implicitly by ``for(let x of proxy){}``.
857
733
  *
858
- * Present only if the proxied Python object is a generator or iterator
859
- * (i.e., has a ``send`` or ``__next__`` method).
734
+ * Present only if the proxied Python object is a generator or iterator (i.e.,
735
+ * has a ``send`` or ``__next__`` method).
860
736
  *
861
- * @param {any=} [value] The value to send to the generator. The value will be
862
- * assigned as a result of a yield expression.
863
- * @returns {IteratorResult<Py2JsResult, Py2JsResult>} An Object with two properties: ``done`` and ``value``.
864
- * When the generator yields ``some_value``, ``next`` returns ``{done :
865
- * false, value : some_value}``. When the generator raises a
866
- * ``StopIteration(result_value)`` exception, ``next`` returns ``{done :
867
- * true, value : result_value}``.
737
+ * @param any The value to send to the generator. The value will be assigned
738
+ * as a result of a yield expression.
739
+ * @returns An Object with two properties: ``done`` and ``value``. When the
740
+ * generator yields ``some_value``, ``next`` returns ``{done : false, value :
741
+ * some_value}``. When the generator raises a ``StopIteration(result_value)``
742
+ * exception, ``next`` returns ``{done : true, value : result_value}``.
868
743
  */
869
- next(arg = undefined) {
870
- let idresult;
744
+ next(arg: any = undefined): IteratorResult<any, any> {
871
745
  // Note: arg is optional, if arg is not supplied, it will be undefined
872
746
  // which gets converted to "Py_None". This is as intended.
873
- let idarg = Module.hiwire.new_value(arg);
747
+ let idarg = Hiwire.new_value(arg);
748
+ let status;
874
749
  let done;
750
+ let stackTop = Module.stackSave();
751
+ let res_ptr = Module.stackAlloc(4);
875
752
  try {
876
- idresult = Module.__pyproxyGen_Send(_getPtr(this), idarg);
877
- done = idresult === 0;
878
- if (done) {
879
- idresult = Module.__pyproxyGen_FetchStopIterationValue();
880
- }
753
+ status = Module.__pyproxyGen_Send(_getPtr(this), idarg, res_ptr);
881
754
  } catch (e) {
882
- Module.fatal_error(e);
755
+ API.fatal_error(e);
883
756
  } finally {
884
- Module.hiwire.decref(idarg);
757
+ Hiwire.decref(idarg);
885
758
  }
886
- if (done && idresult === 0) {
759
+ let HEAPU32 = Module.HEAPU32;
760
+ let idresult = HEAPU32[(res_ptr >> 2) + 0];
761
+ Module.stackRestore(stackTop);
762
+ if (status === -1) {
887
763
  Module._pythonexc2js();
888
764
  }
889
- let value = Module.hiwire.pop_value(idresult);
765
+ let value = Hiwire.pop_value(idresult);
766
+ done = status === 0;
890
767
  return { done, value };
891
768
  }
892
769
  }
893
-
894
770
  // Another layer of boilerplate. The PyProxyHandlers have some annoying logic
895
771
  // to deal with straining out the spurious "Function" properties "prototype",
896
772
  // "arguments", and "length", to deal with correctly satisfying the Proxy
897
773
  // invariants, and to deal with the mro
898
- function python_hasattr(jsobj, jskey) {
774
+ function python_hasattr(jsobj: PyProxyClass, jskey: any) {
899
775
  let ptrobj = _getPtr(jsobj);
900
- let idkey = Module.hiwire.new_value(jskey);
776
+ let idkey = Hiwire.new_value(jskey);
901
777
  let result;
902
778
  try {
903
779
  result = Module.__pyproxy_hasattr(ptrobj, idkey);
904
780
  } catch (e) {
905
- Module.fatal_error(e);
781
+ API.fatal_error(e);
906
782
  } finally {
907
- Module.hiwire.decref(idkey);
783
+ Hiwire.decref(idkey);
908
784
  }
909
785
  if (result === -1) {
910
786
  Module._pythonexc2js();
911
787
  }
912
788
  return result !== 0;
913
789
  }
914
-
915
790
  // Returns a JsRef in order to allow us to differentiate between "not found"
916
791
  // (in which case we return 0) and "found 'None'" (in which case we return
917
792
  // Js_undefined).
918
- function python_getattr(jsobj, jskey) {
793
+ function python_getattr(jsobj: PyProxyClass, jskey: any) {
919
794
  let ptrobj = _getPtr(jsobj);
920
- let idkey = Module.hiwire.new_value(jskey);
795
+ let idkey = Hiwire.new_value(jskey);
921
796
  let idresult;
922
797
  let cacheId = jsobj.$$.cache.cacheId;
923
798
  try {
924
799
  idresult = Module.__pyproxy_getattr(ptrobj, idkey, cacheId);
925
800
  } catch (e) {
926
- Module.fatal_error(e);
801
+ API.fatal_error(e);
927
802
  } finally {
928
- Module.hiwire.decref(idkey);
803
+ Hiwire.decref(idkey);
929
804
  }
930
805
  if (idresult === 0) {
931
806
  if (Module._PyErr_Occurred()) {
@@ -934,41 +809,38 @@ function python_getattr(jsobj, jskey) {
934
809
  }
935
810
  return idresult;
936
811
  }
937
-
938
- function python_setattr(jsobj, jskey, jsval) {
812
+ function python_setattr(jsobj: PyProxyClass, jskey: any, jsval: any) {
939
813
  let ptrobj = _getPtr(jsobj);
940
- let idkey = Module.hiwire.new_value(jskey);
941
- let idval = Module.hiwire.new_value(jsval);
814
+ let idkey = Hiwire.new_value(jskey);
815
+ let idval = Hiwire.new_value(jsval);
942
816
  let errcode;
943
817
  try {
944
818
  errcode = Module.__pyproxy_setattr(ptrobj, idkey, idval);
945
819
  } catch (e) {
946
- Module.fatal_error(e);
820
+ API.fatal_error(e);
947
821
  } finally {
948
- Module.hiwire.decref(idkey);
949
- Module.hiwire.decref(idval);
822
+ Hiwire.decref(idkey);
823
+ Hiwire.decref(idval);
950
824
  }
951
825
  if (errcode === -1) {
952
826
  Module._pythonexc2js();
953
827
  }
954
828
  }
955
-
956
- function python_delattr(jsobj, jskey) {
829
+ function python_delattr(jsobj: PyProxyClass, jskey: any) {
957
830
  let ptrobj = _getPtr(jsobj);
958
- let idkey = Module.hiwire.new_value(jskey);
831
+ let idkey = Hiwire.new_value(jskey);
959
832
  let errcode;
960
833
  try {
961
834
  errcode = Module.__pyproxy_delattr(ptrobj, idkey);
962
835
  } catch (e) {
963
- Module.fatal_error(e);
836
+ API.fatal_error(e);
964
837
  } finally {
965
- Module.hiwire.decref(idkey);
838
+ Hiwire.decref(idkey);
966
839
  }
967
840
  if (errcode === -1) {
968
841
  Module._pythonexc2js();
969
842
  }
970
843
  }
971
-
972
844
  // See explanation of which methods should be defined here and what they do
973
845
  // here:
974
846
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
@@ -976,7 +848,7 @@ let PyProxyHandlers = {
976
848
  isExtensible() {
977
849
  return (!!1);
978
850
  },
979
- has(jsobj, jskey) {
851
+ has(jsobj: PyProxyClass, jskey: any) {
980
852
  // Note: must report "prototype" in proxy when we are callable.
981
853
  // (We can return the wrong value from "get" handler though.)
982
854
  let objHasKey = Reflect.has(jsobj, jskey);
@@ -992,11 +864,10 @@ let PyProxyHandlers = {
992
864
  }
993
865
  return python_hasattr(jsobj, jskey);
994
866
  },
995
- get(jsobj, jskey) {
867
+ get(jsobj: PyProxyClass, jskey: any) {
996
868
  // Preference order:
997
869
  // 1. stuff from JavaScript
998
870
  // 2. the result of Python getattr
999
-
1000
871
  // python_getattr will crash if given a Symbol.
1001
872
  if (jskey in jsobj || typeof jskey === "symbol") {
1002
873
  return Reflect.get(jsobj, jskey);
@@ -1009,10 +880,10 @@ let PyProxyHandlers = {
1009
880
  // 2. The result of getattr
1010
881
  let idresult = python_getattr(jsobj, jskey);
1011
882
  if (idresult !== 0) {
1012
- return Module.hiwire.pop_value(idresult);
883
+ return Hiwire.pop_value(idresult);
1013
884
  }
1014
885
  },
1015
- set(jsobj, jskey, jsval) {
886
+ set(jsobj: PyProxyClass, jskey: any, jsval: any) {
1016
887
  let descr = Object.getOwnPropertyDescriptor(jsobj, jskey);
1017
888
  if (descr && !descr.writable) {
1018
889
  throw new TypeError(`Cannot set read only field '${jskey}'`);
@@ -1027,7 +898,7 @@ let PyProxyHandlers = {
1027
898
  python_setattr(jsobj, jskey, jsval);
1028
899
  return (!!1);
1029
900
  },
1030
- deleteProperty(jsobj, jskey) {
901
+ deleteProperty(jsobj: PyProxyClass, jskey: any): boolean {
1031
902
  let descr = Object.getOwnPropertyDescriptor(jsobj, jskey);
1032
903
  if (descr && !descr.writable) {
1033
904
  throw new TypeError(`Cannot delete read only field '${jskey}'`);
@@ -1041,44 +912,41 @@ let PyProxyHandlers = {
1041
912
  python_delattr(jsobj, jskey);
1042
913
  // Must return "false" if "jskey" is a nonconfigurable own property.
1043
914
  // Otherwise JavaScript will throw a TypeError.
1044
- return !descr || descr.configurable;
915
+ return !descr || !!descr.configurable;
1045
916
  },
1046
- ownKeys(jsobj) {
917
+ ownKeys(jsobj: PyProxyClass) {
1047
918
  let ptrobj = _getPtr(jsobj);
1048
919
  let idresult;
1049
920
  try {
1050
921
  idresult = Module.__pyproxy_ownKeys(ptrobj);
1051
922
  } catch (e) {
1052
- Module.fatal_error(e);
923
+ API.fatal_error(e);
1053
924
  }
1054
925
  if (idresult === 0) {
1055
926
  Module._pythonexc2js();
1056
927
  }
1057
- let result = Module.hiwire.pop_value(idresult);
928
+ let result = Hiwire.pop_value(idresult);
1058
929
  result.push(...Reflect.ownKeys(jsobj));
1059
930
  return result;
1060
931
  },
1061
- apply(jsobj, jsthis, jsargs) {
932
+ apply(jsobj: PyProxyClass & Function, jsthis: any, jsargs: any) {
1062
933
  return jsobj.apply(jsthis, jsargs);
1063
934
  },
1064
935
  };
1065
-
1066
- /**
1067
- * @typedef {PyProxy & Promise<Py2JsResult>} PyProxyAwaitable
1068
- */
1069
-
936
+ export type PyProxyAwaitable = PyProxy & Promise<any>;
1070
937
  /**
1071
938
  * The Promise / JavaScript awaitable API.
1072
939
  * @private
1073
940
  */
1074
- class PyProxyAwaitableMethods {
941
+ export class PyProxyAwaitableMethods {
942
+ $$: any;
1075
943
  /**
1076
944
  * This wraps __pyproxy_ensure_future and makes a function that converts a
1077
945
  * Python awaitable to a promise, scheduling the awaitable on the Python
1078
946
  * event loop if necessary.
1079
947
  * @private
1080
948
  */
1081
- _ensure_future() {
949
+ _ensure_future(): Promise<any> {
1082
950
  if (this.$$.promise) {
1083
951
  return this.$$.promise;
1084
952
  }
@@ -1089,8 +957,8 @@ class PyProxyAwaitableMethods {
1089
957
  resolveHandle = resolve;
1090
958
  rejectHandle = reject;
1091
959
  });
1092
- let resolve_handle_id = Module.hiwire.new_value(resolveHandle);
1093
- let reject_handle_id = Module.hiwire.new_value(rejectHandle);
960
+ let resolve_handle_id = Hiwire.new_value(resolveHandle);
961
+ let reject_handle_id = Hiwire.new_value(rejectHandle);
1094
962
  let errcode;
1095
963
  try {
1096
964
  errcode = Module.__pyproxy_ensure_future(
@@ -1099,15 +967,16 @@ class PyProxyAwaitableMethods {
1099
967
  reject_handle_id
1100
968
  );
1101
969
  } catch (e) {
1102
- Module.fatal_error(e);
970
+ API.fatal_error(e);
1103
971
  } finally {
1104
- Module.hiwire.decref(reject_handle_id);
1105
- Module.hiwire.decref(resolve_handle_id);
972
+ Hiwire.decref(reject_handle_id);
973
+ Hiwire.decref(resolve_handle_id);
1106
974
  }
1107
975
  if (errcode === -1) {
1108
976
  Module._pythonexc2js();
1109
977
  }
1110
978
  this.$$.promise = promise;
979
+ // @ts-ignore
1111
980
  this.destroy();
1112
981
  return promise;
1113
982
  }
@@ -1115,7 +984,7 @@ class PyProxyAwaitableMethods {
1115
984
  * Runs ``asyncio.ensure_future(awaitable)``, executes
1116
985
  * ``onFulfilled(result)`` when the ``Future`` resolves successfully,
1117
986
  * executes ``onRejected(error)`` when the ``Future`` fails. Will be used
1118
- * implictly by ``await obj``.
987
+ * implicitly by ``await obj``.
1119
988
  *
1120
989
  * See the documentation for
1121
990
  * `Promise.then
@@ -1124,13 +993,16 @@ class PyProxyAwaitableMethods {
1124
993
  * Present only if the proxied Python object is `awaitable
1125
994
  * <https://docs.python.org/3/library/asyncio-task.html?highlight=awaitable#awaitables>`_.
1126
995
  *
1127
- * @param {Function} onFulfilled A handler called with the result as an
996
+ * @param onFulfilled A handler called with the result as an
1128
997
  * argument if the awaitable succeeds.
1129
- * @param {Function} onRejected A handler called with the error as an
998
+ * @param onRejected A handler called with the error as an
1130
999
  * argument if the awaitable fails.
1131
- * @returns {Promise} The resulting Promise.
1000
+ * @returns The resulting Promise.
1132
1001
  */
1133
- then(onFulfilled, onRejected) {
1002
+ then(
1003
+ onFulfilled: (value: any) => any,
1004
+ onRejected: (reason: any) => any
1005
+ ): Promise<any> {
1134
1006
  let promise = this._ensure_future();
1135
1007
  return promise.then(onFulfilled, onRejected);
1136
1008
  }
@@ -1145,11 +1017,11 @@ class PyProxyAwaitableMethods {
1145
1017
  * Present only if the proxied Python object is `awaitable
1146
1018
  * <https://docs.python.org/3/library/asyncio-task.html?highlight=awaitable#awaitables>`_.
1147
1019
  *
1148
- * @param {Function} onRejected A handler called with the error as an
1020
+ * @param onRejected A handler called with the error as an
1149
1021
  * argument if the awaitable fails.
1150
- * @returns {Promise} The resulting Promise.
1022
+ * @returns The resulting Promise.
1151
1023
  */
1152
- catch(onRejected) {
1024
+ catch(onRejected: (reason: any) => any) {
1153
1025
  let promise = this._ensure_future();
1154
1026
  return promise.catch(onRejected);
1155
1027
  }
@@ -1165,33 +1037,32 @@ class PyProxyAwaitableMethods {
1165
1037
  * <https://docs.python.org/3/library/asyncio-task.html?highlight=awaitable#awaitables>`_.
1166
1038
  *
1167
1039
  *
1168
- * @param {Function} onFinally A handler that is called with zero arguments
1040
+ * @param onFinally A handler that is called with zero arguments
1169
1041
  * when the awaitable resolves.
1170
- * @returns {Promise} A Promise that resolves or rejects with the same
1042
+ * @returns A Promise that resolves or rejects with the same
1171
1043
  * result as the original Promise, but only after executing the
1172
1044
  * ``onFinally`` handler.
1173
1045
  */
1174
- finally(onFinally) {
1046
+ finally(onFinally: () => void) {
1175
1047
  let promise = this._ensure_future();
1176
1048
  return promise.finally(onFinally);
1177
1049
  }
1178
1050
  }
1179
-
1180
- /**
1181
- * @typedef { PyProxy & PyProxyCallableMethods & ((...args : any[]) => Py2JsResult) } PyProxyCallable
1182
- */
1183
- class PyProxyCallableMethods {
1184
- apply(jsthis, jsargs) {
1051
+ export type PyProxyCallable = PyProxy &
1052
+ PyProxyCallableMethods &
1053
+ ((...args: any[]) => any);
1054
+ export class PyProxyCallableMethods {
1055
+ apply(jsthis: PyProxyClass, jsargs: any) {
1185
1056
  return Module.callPyObject(_getPtr(this), ...jsargs);
1186
1057
  }
1187
- call(jsthis, ...jsargs) {
1058
+ call(jsthis: PyProxyClass, ...jsargs: any) {
1188
1059
  return Module.callPyObject(_getPtr(this), ...jsargs);
1189
1060
  }
1190
1061
  /**
1191
1062
  * Call the function with key word arguments.
1192
1063
  * The last argument must be an object with the keyword arguments.
1193
1064
  */
1194
- callKwargs(...jsargs) {
1065
+ callKwargs(...jsargs: any) {
1195
1066
  if (jsargs.length === 0) {
1196
1067
  throw new TypeError(
1197
1068
  "callKwargs requires at least one argument (the key word argument object)"
@@ -1207,9 +1078,10 @@ class PyProxyCallableMethods {
1207
1078
  return Module.callPyObjectKwargs(_getPtr(this), ...jsargs);
1208
1079
  }
1209
1080
  }
1081
+ // @ts-ignore
1210
1082
  PyProxyCallableMethods.prototype.prototype = Function.prototype;
1211
-
1212
- let type_to_array_map = new Map([
1083
+ // @ts-ignore
1084
+ let type_to_array_map: Map<string, any> = new Map([
1213
1085
  ["i8", Int8Array],
1214
1086
  ["u8", Uint8Array],
1215
1087
  ["u8clamped", Uint8ClampedArray],
@@ -1227,11 +1099,8 @@ let type_to_array_map = new Map([
1227
1099
  ["f64", Float64Array],
1228
1100
  ["dataview", DataView],
1229
1101
  ]);
1230
-
1231
- /**
1232
- * @typedef {PyProxy & PyProxyBufferMethods} PyProxyBuffer
1233
- */
1234
- class PyProxyBufferMethods {
1102
+ export type PyProxyBuffer = PyProxy & PyProxyBufferMethods;
1103
+ export class PyProxyBufferMethods {
1235
1104
  /**
1236
1105
  * Get a view of the buffer data which is usable from JavaScript. No copy is
1237
1106
  * ever performed.
@@ -1253,16 +1122,16 @@ class PyProxyBufferMethods {
1253
1122
  * have support for big endian data, so you might want to pass
1254
1123
  * ``'dataview'`` as the type argument in that case.
1255
1124
  *
1256
- * @param {string=} [type] The type of the :any:`PyBuffer.data <pyodide.PyBuffer.data>` field in the
1125
+ * @param type The type of the :any:`PyBuffer.data <pyodide.PyBuffer.data>` field in the
1257
1126
  * output. Should be one of: ``"i8"``, ``"u8"``, ``"u8clamped"``, ``"i16"``,
1258
1127
  * ``"u16"``, ``"i32"``, ``"u32"``, ``"i32"``, ``"u32"``, ``"i64"``,
1259
1128
  * ``"u64"``, ``"f32"``, ``"f64``, or ``"dataview"``. This argument is
1260
1129
  * optional, if absent ``getBuffer`` will try to determine the appropriate
1261
1130
  * output type based on the buffer `format string
1262
1131
  * <https://docs.python.org/3/library/struct.html#format-strings>`_.
1263
- * @returns {PyBuffer} :any:`PyBuffer <pyodide.PyBuffer>`
1132
+ * @returns :any:`PyBuffer <pyodide.PyBuffer>`
1264
1133
  */
1265
- getBuffer(type) {
1134
+ getBuffer(type?: string): PyBuffer {
1266
1135
  let ArrayType = undefined;
1267
1136
  if (type) {
1268
1137
  ArrayType = type_to_array_map.get(type);
@@ -1280,30 +1149,25 @@ class PyProxyBufferMethods {
1280
1149
  try {
1281
1150
  errcode = Module.__pyproxy_get_buffer(buffer_struct_ptr, this_ptr);
1282
1151
  } catch (e) {
1283
- Module.fatal_error(e);
1152
+ API.fatal_error(e);
1284
1153
  }
1285
1154
  if (errcode === -1) {
1286
1155
  Module._pythonexc2js();
1287
1156
  }
1288
-
1289
1157
  // This has to match the fields in buffer_struct
1290
1158
  let startByteOffset = HEAPU32[(buffer_struct_ptr >> 2) + 0];
1291
1159
  let minByteOffset = HEAPU32[(buffer_struct_ptr >> 2) + 1];
1292
1160
  let maxByteOffset = HEAPU32[(buffer_struct_ptr >> 2) + 2];
1293
-
1294
1161
  let readonly = !!HEAPU32[(buffer_struct_ptr >> 2) + 3];
1295
1162
  let format_ptr = HEAPU32[(buffer_struct_ptr >> 2) + 4];
1296
1163
  let itemsize = HEAPU32[(buffer_struct_ptr >> 2) + 5];
1297
- let shape = Module.hiwire.pop_value(HEAPU32[(buffer_struct_ptr >> 2) + 6]);
1298
- let strides = Module.hiwire.pop_value(HEAPU32[(buffer_struct_ptr >> 2) + 7]);
1299
-
1164
+ let shape = Hiwire.pop_value(HEAPU32[(buffer_struct_ptr >> 2) + 6]);
1165
+ let strides = Hiwire.pop_value(HEAPU32[(buffer_struct_ptr >> 2) + 7]);
1300
1166
  let view_ptr = HEAPU32[(buffer_struct_ptr >> 2) + 8];
1301
1167
  let c_contiguous = !!HEAPU32[(buffer_struct_ptr >> 2) + 9];
1302
1168
  let f_contiguous = !!HEAPU32[(buffer_struct_ptr >> 2) + 10];
1303
-
1304
1169
  let format = Module.UTF8ToString(format_ptr);
1305
1170
  Module.stackRestore(orig_stack_ptr);
1306
-
1307
1171
  let success = (!!0);
1308
1172
  try {
1309
1173
  let bigEndian = (!!0);
@@ -1346,7 +1210,6 @@ class PyProxyBufferMethods {
1346
1210
  for (let i of strides.keys()) {
1347
1211
  strides[i] /= alignment;
1348
1212
  }
1349
-
1350
1213
  success = (!!1);
1351
1214
  let result = Object.create(
1352
1215
  PyBuffer.prototype,
@@ -1374,17 +1237,23 @@ class PyProxyBufferMethods {
1374
1237
  Module._PyBuffer_Release(view_ptr);
1375
1238
  Module._PyMem_Free(view_ptr);
1376
1239
  } catch (e) {
1377
- Module.fatal_error(e);
1240
+ API.fatal_error(e);
1378
1241
  }
1379
1242
  }
1380
1243
  }
1381
1244
  }
1382
1245
  }
1383
-
1384
- /**
1385
- * @typedef {Int8Array | Uint8Array | Int16Array | Uint16Array | Int32Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array} TypedArray;
1386
- */
1387
-
1246
+ export type TypedArray =
1247
+ | Int8Array
1248
+ | Uint8Array
1249
+ | Int16Array
1250
+ | Uint16Array
1251
+ | Int32Array
1252
+ | Uint32Array
1253
+ | Uint8ClampedArray
1254
+ | Float32Array
1255
+ | Float64Array;
1256
+ export type PyProxyDict = PyProxyWithGet & PyProxyWithSet & PyProxyWithHas;
1388
1257
  /**
1389
1258
  * A class to allow access to a Python data buffers from JavaScript. These are
1390
1259
  * produced by :any:`PyProxy.getBuffer` and cannot be constructed directly.
@@ -1452,93 +1321,82 @@ class PyProxyBufferMethods {
1452
1321
  * );
1453
1322
  */
1454
1323
  export class PyBuffer {
1324
+ /**
1325
+ * The offset of the first entry of the array. For instance if our array
1326
+ * is 3d, then you will find ``array[0,0,0]`` at
1327
+ * ``pybuf.data[pybuf.offset]``
1328
+ */
1329
+ offset: number;
1330
+ /**
1331
+ * If the data is readonly, you should not modify it. There is no way
1332
+ * for us to enforce this, but it may cause very weird behavior.
1333
+ */
1334
+ readonly: boolean;
1335
+ /**
1336
+ * The format string for the buffer. See `the Python documentation on
1337
+ * format strings
1338
+ * <https://docs.python.org/3/library/struct.html#format-strings>`_.
1339
+ */
1340
+ format: string;
1341
+ /**
1342
+ * How large is each entry (in bytes)?
1343
+ */
1344
+ itemsize: number;
1345
+ /**
1346
+ * The number of dimensions of the buffer. If ``ndim`` is 0, the buffer
1347
+ * represents a single scalar or struct. Otherwise, it represents an
1348
+ * array.
1349
+ */
1350
+ ndim: number;
1351
+ /**
1352
+ * The total number of bytes the buffer takes up. This is equal to
1353
+ * ``buff.data.byteLength``.
1354
+ */
1355
+ nbytes: number;
1356
+ /**
1357
+ * The shape of the buffer, that is how long it is in each dimension.
1358
+ * The length will be equal to ``ndim``. For instance, a 2x3x4 array
1359
+ * would have shape ``[2, 3, 4]``.
1360
+ */
1361
+ shape: number[];
1362
+ /**
1363
+ * An array of of length ``ndim`` giving the number of elements to skip
1364
+ * to get to a new element in each dimension. See the example definition
1365
+ * of a ``multiIndexToIndex`` function above.
1366
+ */
1367
+ strides: number[];
1368
+ /**
1369
+ * The actual data. A typed array of an appropriate size backed by a
1370
+ * segment of the WASM memory.
1371
+ *
1372
+ * The ``type`` argument of :any:`PyProxy.getBuffer`
1373
+ * determines which sort of ``TypedArray`` this is. By default
1374
+ * :any:`PyProxy.getBuffer` will look at the format string to determine the most
1375
+ * appropriate option.
1376
+ */
1377
+ data: TypedArray;
1378
+ /**
1379
+ * Is it C contiguous?
1380
+ */
1381
+ c_contiguous: boolean;
1382
+ /**
1383
+ * Is it Fortran contiguous?
1384
+ */
1385
+ f_contiguous: boolean;
1386
+ /**
1387
+ * @private
1388
+ */
1389
+ _released: boolean;
1390
+ /**
1391
+ * @private
1392
+ */
1393
+ _view_ptr: number;
1394
+ /**
1395
+ * @private
1396
+ */
1455
1397
  constructor() {
1456
- /**
1457
- * The offset of the first entry of the array. For instance if our array
1458
- * is 3d, then you will find ``array[0,0,0]`` at
1459
- * ``pybuf.data[pybuf.offset]``
1460
- * @type {number}
1461
- */
1462
- this.offset;
1463
-
1464
- /**
1465
- * If the data is readonly, you should not modify it. There is no way
1466
- * for us to enforce this, but it may cause very weird behavior.
1467
- * @type {boolean}
1468
- */
1469
- this.readonly;
1470
-
1471
- /**
1472
- * The format string for the buffer. See `the Python documentation on
1473
- * format strings
1474
- * <https://docs.python.org/3/library/struct.html#format-strings>`_.
1475
- * @type {string}
1476
- */
1477
- this.format;
1478
-
1479
- /**
1480
- * How large is each entry (in bytes)?
1481
- * @type {number}
1482
- */
1483
- this.itemsize;
1484
-
1485
- /**
1486
- * The number of dimensions of the buffer. If ``ndim`` is 0, the buffer
1487
- * represents a single scalar or struct. Otherwise, it represents an
1488
- * array.
1489
- * @type {number}
1490
- */
1491
- this.ndim;
1492
-
1493
- /**
1494
- * The total number of bytes the buffer takes up. This is equal to
1495
- * ``buff.data.byteLength``.
1496
- * @type {number}
1497
- */
1498
- this.nbytes;
1499
-
1500
- /**
1501
- * The shape of the buffer, that is how long it is in each dimension.
1502
- * The length will be equal to ``ndim``. For instance, a 2x3x4 array
1503
- * would have shape ``[2, 3, 4]``.
1504
- * @type {number[]}
1505
- */
1506
- this.shape;
1507
-
1508
- /**
1509
- * An array of of length ``ndim`` giving the number of elements to skip
1510
- * to get to a new element in each dimension. See the example definition
1511
- * of a ``multiIndexToIndex`` function above.
1512
- * @type {number[]}
1513
- */
1514
- this.strides;
1515
-
1516
- /**
1517
- * The actual data. A typed array of an appropriate size backed by a
1518
- * segment of the WASM memory.
1519
- *
1520
- * The ``type`` argument of :any:`PyProxy.getBuffer`
1521
- * determines which sort of ``TypedArray`` this is. By default
1522
- * :any:`PyProxy.getBuffer` will look at the format string to determine the most
1523
- * appropriate option.
1524
- * @type {TypedArray}
1525
- */
1526
- this.data;
1527
-
1528
- /**
1529
- * Is it C contiguous?
1530
- * @type {boolean}
1531
- */
1532
- this.c_contiguous;
1533
-
1534
- /**
1535
- * Is it Fortran contiguous?
1536
- * @type {boolean}
1537
- */
1538
- this.f_contiguous;
1539
1398
  throw new TypeError("PyBuffer is not a constructor");
1540
1399
  }
1541
-
1542
1400
  /**
1543
1401
  * Release the buffer. This allows the memory to be reclaimed.
1544
1402
  */
@@ -1551,9 +1409,10 @@ export class PyBuffer {
1551
1409
  Module._PyBuffer_Release(this._view_ptr);
1552
1410
  Module._PyMem_Free(this._view_ptr);
1553
1411
  } catch (e) {
1554
- Module.fatal_error(e);
1412
+ API.fatal_error(e);
1555
1413
  }
1556
1414
  this._released = (!!1);
1415
+ // @ts-ignore
1557
1416
  this.data = null;
1558
1417
  }
1559
1418
  }