pyodide 0.18.0 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/pyproxy.gen.js CHANGED
@@ -132,11 +132,8 @@
132
132
  * the callPyObject method, but of course one can also execute arbitrary code
133
133
  * via the various __dundermethods__ associated to classes.
134
134
  *
135
- * The only entrypoint into Python that avoids this file is our bootstrap method
136
- * runPythonSimple which is defined in main.c
137
- *
138
135
  * Any time we call into wasm, the call should be wrapped in a try catch block.
139
- * This way if a Javascript error emerges from the wasm, we can escalate it to a
136
+ * This way if a JavaScript error emerges from the wasm, we can escalate it to a
140
137
  * fatal error.
141
138
  *
142
139
  * This is file is preprocessed with -imacros "pyproxy.c". As a result of this,
@@ -160,6 +157,7 @@ Module.isPyProxy = isPyProxy;
160
157
 
161
158
  if (globalThis.FinalizationRegistry) {
162
159
  Module.finalizationRegistry = new FinalizationRegistry(([ptr, cache]) => {
160
+ cache.leaked = (!!1);
163
161
  pyproxy_decref_cache(cache);
164
162
  try {
165
163
  Module._Py_DecRef(ptr);
@@ -172,7 +170,7 @@ if (globalThis.FinalizationRegistry) {
172
170
  // For some unclear reason this code screws up selenium FirefoxDriver. Works
173
171
  // fine in chrome and when I test it in browser. It seems to be sensitive to
174
172
  // changes that don't make a difference to the semantics.
175
- // TODO: after v0.17.0 release, fix selenium issues with this code.
173
+ // TODO: after 0.18.0, fix selenium issues with this code.
176
174
  // Module.bufferFinalizationRegistry = new FinalizationRegistry((ptr) => {
177
175
  // try {
178
176
  // Module._PyBuffer_Release(ptr);
@@ -248,7 +246,7 @@ Module.pyproxy_new = function (ptrobj, cache) {
248
246
  }
249
247
  cache.refcnt++;
250
248
  Object.defineProperty(target, "$$", {
251
- value: { ptr: ptrobj, type: "PyProxy", borrowed: (!!0), cache },
249
+ value: { ptr: ptrobj, type: "PyProxy", cache },
252
250
  });
253
251
  Module._Py_IncRef(ptrobj);
254
252
  let proxy = new Proxy(target, PyProxyHandlers);
@@ -318,9 +316,6 @@ Module.getPyProxyClass = function (flags) {
318
316
 
319
317
  // Static methods
320
318
  Module.PyProxy_getPtr = _getPtr;
321
- Module.pyproxy_mark_borrowed = function (proxy) {
322
- proxy.$$.borrowed = (!!1);
323
- };
324
319
 
325
320
  const pyproxy_cache_destroyed_msg =
326
321
  "This borrowed attribute proxy was automatically destroyed in the " +
@@ -334,18 +329,21 @@ function pyproxy_decref_cache(cache) {
334
329
  if (cache.refcnt === 0) {
335
330
  let cache_map = Module.hiwire.pop_value(cache.cacheId);
336
331
  for (let proxy_id of cache_map.values()) {
337
- Module.pyproxy_destroy(
338
- Module.hiwire.pop_value(proxy_id),
339
- pyproxy_cache_destroyed_msg
340
- );
332
+ const cache_entry = Module.hiwire.pop_value(proxy_id);
333
+ if (!cache.leaked) {
334
+ Module.pyproxy_destroy(cache_entry, pyproxy_cache_destroyed_msg);
335
+ }
341
336
  }
342
337
  }
343
338
  }
344
339
 
345
340
  Module.pyproxy_destroy = function (proxy, destroyed_msg) {
341
+ if (proxy.$$.ptr === null) {
342
+ return;
343
+ }
346
344
  let ptrobj = _getPtr(proxy);
347
345
  Module.finalizationRegistry.unregister(proxy);
348
- // Maybe the destructor will call Javascript code that will somehow try
346
+ // Maybe the destructor will call JavaScript code that will somehow try
349
347
  // to use this proxy. Mark it deleted before decrementing reference count
350
348
  // just in case!
351
349
  proxy.$$.ptr = null;
@@ -360,7 +358,7 @@ Module.pyproxy_destroy = function (proxy, destroyed_msg) {
360
358
  };
361
359
 
362
360
  // Now a lot of boilerplate to wrap the abstract Object protocol wrappers
363
- // defined in pyproxy.c in Javascript functions.
361
+ // defined in pyproxy.c in JavaScript functions.
364
362
 
365
363
  Module.callPyObjectKwargs = function (ptrobj, ...jsargs) {
366
364
  // We don't do any checking for kwargs, checks are in PyProxy.callKwargs
@@ -462,9 +460,7 @@ class PyProxyClass {
462
460
  * destroyed".
463
461
  */
464
462
  destroy(destroyed_msg) {
465
- if (!this.$$.borrowed) {
466
- Module.pyproxy_destroy(this, destroyed_msg);
467
- }
463
+ Module.pyproxy_destroy(this, destroyed_msg);
468
464
  }
469
465
  /**
470
466
  * Make a new PyProxy pointing to the same Python object.
@@ -476,7 +472,7 @@ class PyProxyClass {
476
472
  return Module.pyproxy_new(ptrobj, this.$$.cache);
477
473
  }
478
474
  /**
479
- * Converts the ``PyProxy`` into a Javascript object as best as possible. By
475
+ * Converts the ``PyProxy`` into a JavaScript object as best as possible. By
480
476
  * default does a deep conversion, if a shallow conversion is desired, you can
481
477
  * use ``proxy.toJs({depth : 1})``. See :ref:`Explicit Conversion of PyProxy
482
478
  * <type-translations-pyproxy-to-js>` for more info.
@@ -490,14 +486,14 @@ class PyProxyClass {
490
486
  * generated structure. The most common use case is to create a new empty
491
487
  * list, pass the list as `pyproxies`, and then later iterate over `pyproxies`
492
488
  * to destroy all of created proxies.
493
- * @param {bool} [options.create_pyproxies] If false, ``toJs`` will throw a
489
+ * @param {boolean} [options.create_pyproxies] If false, ``toJs`` will throw a
494
490
  * ``ConversionError`` rather than producing a ``PyProxy``.
495
- * @param {bool} [options.dict_converter] A function to be called on an
491
+ * @param {boolean} [options.dict_converter] A function to be called on an
496
492
  * iterable of pairs ``[key, value]``. Convert this iterable of pairs to the
497
493
  * desired output. For instance, ``Object.fromEntries`` would convert the dict
498
494
  * to an object, ``Array.from`` converts it to an array of entries, and ``(it) =>
499
495
  * new Map(it)`` converts it to a ``Map`` (which is the default behavior).
500
- * @return {any} The Javascript object resulting from the conversion.
496
+ * @return {any} The JavaScript object resulting from the conversion.
501
497
  */
502
498
  toJs({
503
499
  depth = -1,
@@ -768,8 +764,6 @@ class PyProxyContainsMethods {
768
764
  }
769
765
  }
770
766
 
771
- class TempError extends Error {}
772
-
773
767
  /**
774
768
  * A helper for [Symbol.iterator].
775
769
  *
@@ -788,26 +782,19 @@ class TempError extends Error {}
788
782
  */
789
783
  function* iter_helper(iterptr, token) {
790
784
  try {
791
- if (iterptr === 0) {
792
- throw new TempError();
793
- }
794
785
  let item;
795
786
  while ((item = Module.__pyproxy_iter_next(iterptr))) {
796
787
  yield Module.hiwire.pop_value(item);
797
788
  }
798
- if (Module._PyErr_Occurred()) {
799
- throw new TempError();
800
- }
801
789
  } catch (e) {
802
- if (e instanceof TempError) {
803
- Module._pythonexc2js();
804
- } else {
805
- Module.fatal_error(e);
806
- }
790
+ Module.fatal_error(e);
807
791
  } finally {
808
792
  Module.finalizationRegistry.unregister(token);
809
793
  Module._Py_DecRef(iterptr);
810
794
  }
795
+ if (Module._PyErr_Occurred()) {
796
+ Module._pythonexc2js();
797
+ }
811
798
  }
812
799
 
813
800
  /**
@@ -840,6 +827,9 @@ class PyProxyIterableMethods {
840
827
  } catch (e) {
841
828
  Module.fatal_error(e);
842
829
  }
830
+ if (iterptr === 0) {
831
+ Module._pythonexc2js();
832
+ }
843
833
 
844
834
  let result = iter_helper(iterptr, token);
845
835
  Module.finalizationRegistry.register(result, [iterptr, undefined], token);
@@ -1004,7 +994,7 @@ let PyProxyHandlers = {
1004
994
  },
1005
995
  get(jsobj, jskey) {
1006
996
  // Preference order:
1007
- // 1. stuff from Javascript
997
+ // 1. stuff from JavaScript
1008
998
  // 2. the result of Python getattr
1009
999
 
1010
1000
  // python_getattr will crash if given a Symbol.
@@ -1050,7 +1040,7 @@ let PyProxyHandlers = {
1050
1040
  }
1051
1041
  python_delattr(jsobj, jskey);
1052
1042
  // Must return "false" if "jskey" is a nonconfigurable own property.
1053
- // Otherwise Javascript will throw a TypeError.
1043
+ // Otherwise JavaScript will throw a TypeError.
1054
1044
  return !descr || descr.configurable;
1055
1045
  },
1056
1046
  ownKeys(jsobj) {
@@ -1078,7 +1068,7 @@ let PyProxyHandlers = {
1078
1068
  */
1079
1069
 
1080
1070
  /**
1081
- * The Promise / javascript awaitable API.
1071
+ * The Promise / JavaScript awaitable API.
1082
1072
  * @private
1083
1073
  */
1084
1074
  class PyProxyAwaitableMethods {
@@ -1089,6 +1079,9 @@ class PyProxyAwaitableMethods {
1089
1079
  * @private
1090
1080
  */
1091
1081
  _ensure_future() {
1082
+ if (this.$$.promise) {
1083
+ return this.$$.promise;
1084
+ }
1092
1085
  let ptrobj = _getPtr(this);
1093
1086
  let resolveHandle;
1094
1087
  let rejectHandle;
@@ -1114,6 +1107,8 @@ class PyProxyAwaitableMethods {
1114
1107
  if (errcode === -1) {
1115
1108
  Module._pythonexc2js();
1116
1109
  }
1110
+ this.$$.promise = promise;
1111
+ this.destroy();
1117
1112
  return promise;
1118
1113
  }
1119
1114
  /**
@@ -1238,14 +1233,14 @@ let type_to_array_map = new Map([
1238
1233
  */
1239
1234
  class PyProxyBufferMethods {
1240
1235
  /**
1241
- * Get a view of the buffer data which is usable from Javascript. No copy is
1236
+ * Get a view of the buffer data which is usable from JavaScript. No copy is
1242
1237
  * ever performed.
1243
1238
  *
1244
1239
  * Present only if the proxied Python object supports the `Python Buffer
1245
1240
  * Protocol <https://docs.python.org/3/c-api/buffer.html>`_.
1246
1241
  *
1247
1242
  * We do not support suboffsets, if the buffer requires suboffsets we will
1248
- * throw an error. Javascript nd array libraries can't handle suboffsets
1243
+ * throw an error. JavaScript nd array libraries can't handle suboffsets
1249
1244
  * anyways. In this case, you should use the :any:`toJs` api or copy the
1250
1245
  * buffer to one that doesn't use suboffets (using e.g.,
1251
1246
  * `numpy.ascontiguousarray
@@ -1391,7 +1386,7 @@ class PyProxyBufferMethods {
1391
1386
  */
1392
1387
 
1393
1388
  /**
1394
- * A class to allow access to a Python data buffers from Javascript. These are
1389
+ * A class to allow access to a Python data buffers from JavaScript. These are
1395
1390
  * produced by :any:`PyProxy.getBuffer` and cannot be constructed directly.
1396
1391
  * When you are done, release it with the :any:`release <PyBuffer.release>`
1397
1392
  * method. See
@@ -1562,50 +1557,3 @@ export class PyBuffer {
1562
1557
  this.data = null;
1563
1558
  }
1564
1559
  }
1565
-
1566
- // A special proxy that we use to wrap pyodide.globals to allow property
1567
- // access like `pyodide.globals.x`.
1568
- let globalsPropertyAccessWarned = (!!0);
1569
- let globalsPropertyAccessWarningMsg =
1570
- "Access to pyodide.globals via pyodide.globals.key is deprecated and " +
1571
- "will be removed in version 0.18.0. Use pyodide.globals.get('key'), " +
1572
- "pyodide.globals.set('key', value), pyodide.globals.delete('key') instead.";
1573
- let NamespaceProxyHandlers = {
1574
- has(obj, key) {
1575
- return Reflect.has(obj, key) || obj.has(key);
1576
- },
1577
- get(obj, key) {
1578
- if (Reflect.has(obj, key)) {
1579
- return Reflect.get(obj, key);
1580
- }
1581
- let result = obj.get(key);
1582
- if (!globalsPropertyAccessWarned && result !== undefined) {
1583
- console.warn(globalsPropertyAccessWarningMsg);
1584
- globalsPropertyAccessWarned = (!!1);
1585
- }
1586
- return result;
1587
- },
1588
- set(obj, key, value) {
1589
- if (Reflect.has(obj, key)) {
1590
- throw new Error(`Cannot set read only field ${key}`);
1591
- }
1592
- if (!globalsPropertyAccessWarned) {
1593
- globalsPropertyAccessWarned = (!!1);
1594
- console.warn(globalsPropertyAccessWarningMsg);
1595
- }
1596
- obj.set(key, value);
1597
- },
1598
- ownKeys(obj) {
1599
- let result = new Set(Reflect.ownKeys(obj));
1600
- let iter = obj.keys();
1601
- for (let key of iter) {
1602
- result.add(key);
1603
- }
1604
- iter.destroy();
1605
- return Array.from(result);
1606
- },
1607
- };
1608
-
1609
- export function wrapNamespace(ns) {
1610
- return new Proxy(ns, NamespaceProxyHandlers);
1611
- }