diff --git a/src/core/pyproxy.c b/src/core/pyproxy.c index fb92b96d3..d12c82e5f 100644 --- a/src/core/pyproxy.c +++ b/src/core/pyproxy.c @@ -69,10 +69,9 @@ _pyproxy_set(PyObject* pyobj, JsRef idkey, JsRef idval) Py_DECREF(pyval); if (result) { - pythonexc2js(); return NULL; } - return idval; + return hiwire_incref(idval); } JsRef @@ -89,7 +88,6 @@ _pyproxy_deleteProperty(PyObject* pyobj, JsRef idkey) Py_DECREF(pykey); if (ret) { - pythonexc2js(); return NULL; } @@ -102,7 +100,6 @@ _pyproxy_ownKeys(PyObject* pyobj) PyObject* pydir = PyObject_Dir(pyobj); if (pydir == NULL) { - pythonexc2js(); return NULL; } @@ -133,7 +130,6 @@ _pyproxy_apply(PyObject* pyobj, JsRef idargs) PyObject* pyresult = PyObject_Call(pyobj, pyargs, NULL); if (pyresult == NULL) { Py_DECREF(pyargs); - pythonexc2js(); return NULL; } JsRef idresult = python2js(pyresult); @@ -191,7 +187,15 @@ EM_JS(int, pyproxy_init, (), { Module.PyProxyPublicMethods = { toString : function() { let ptrobj = _getPtr(this); - let jsref_repr = __pyproxy_repr(ptrobj); + let jsref_repr; + try { + jsref_repr = __pyproxy_repr(ptrobj); + } catch(e){ + Module.fatal_error(e); + } + if(jsref_repr === 0){ + _pythonexc2js(); + } let repr = Module.hiwire.get_value(jsref_repr); Module.hiwire.decref(jsref_repr); return repr; @@ -204,10 +208,19 @@ EM_JS(int, pyproxy_init, (), { apply : function(jsthis, jsargs) { let ptrobj = _getPtr(this); let idargs = Module.hiwire.new_value(jsargs); - let idresult = __pyproxy_apply(ptrobj, idargs); + let idresult; + try { + idresult = __pyproxy_apply(ptrobj, idargs); + } catch(e){ + Module.fatal_error(e); + } finally { + Module.hiwire.decref(idargs); + } + if(idresult === 0){ + _pythonexc2js(); + } let jsresult = Module.hiwire.get_value(idresult); Module.hiwire.decref(idresult); - Module.hiwire.decref(idargs); return jsresult; }, }; @@ -224,9 +237,18 @@ EM_JS(int, pyproxy_init, (), { } let ptrobj = _getPtr(jsobj); let idkey = Module.hiwire.new_value(jskey); - let result = __pyproxy_has(ptrobj, idkey) !== 0; - Module.hiwire.decref(idkey); - return result; + let result; + try { + result = __pyproxy_has(ptrobj, idkey); + } catch(e){ + Module.fatal_error(e); + } finally { + Module.hiwire.decref(idkey); + } + if(result === -1){ + _pythonexc2js(); + } + return result !== 0; }, get: function (jsobj, jskey) { if(Reflect.has(jsobj, jskey) && !ignoredTargetFields.includes(jskey)){ @@ -234,9 +256,18 @@ EM_JS(int, pyproxy_init, (), { } let ptrobj = _getPtr(jsobj); let idkey = Module.hiwire.new_value(jskey); - let idresult = __pyproxy_get(ptrobj, idkey); + let idresult; + try { + idresult = __pyproxy_get(ptrobj, idkey); + } catch(e) { + Module.fatal_error(e); + } finally { + Module.hiwire.decref(idkey); + } + if(idresult === 0){ + _pythonexc2js(); + } let jsresult = Module.hiwire.get_value(idresult); - Module.hiwire.decref(idkey); Module.hiwire.decref(idresult); return jsresult; }, @@ -247,10 +278,19 @@ EM_JS(int, pyproxy_init, (), { let ptrobj = _getPtr(jsobj); let idkey = Module.hiwire.new_value(jskey); let idval = Module.hiwire.new_value(jsval); - let idresult = __pyproxy_set(ptrobj, idkey, idval); + let idresult; + try { + idresult = __pyproxy_set(ptrobj, idkey, idval); + } catch(e) { + Module.fatal_error(e); + } finally { + Module.hiwire.decref(idkey); + Module.hiwire.decref(idval); + } + if(idresult === 0){ + _pythonexc2js(); + } let jsresult = Module.hiwire.get_value(idresult); - Module.hiwire.decref(idkey); - Module.hiwire.decref(idval); Module.hiwire.decref(idresult); return jsresult; }, @@ -260,10 +300,19 @@ EM_JS(int, pyproxy_init, (), { } let ptrobj = _getPtr(jsobj); let idkey = Module.hiwire.new_value(jskey); - let idresult = __pyproxy_deleteProperty(ptrobj, idkey); + let idresult; + try { + idresult = __pyproxy_deleteProperty(ptrobj, idkey); + } catch(e) { + Module.fatal_error(e); + } finally { + Module.hiwire.decref(idkey); + } + if(idresult === 0){ + _pythonexc2js(); + } let jsresult = Module.hiwire.get_value(idresult); Module.hiwire.decref(idresult); - Module.hiwire.decref(idkey); return jsresult; }, ownKeys: function (jsobj) { @@ -272,7 +321,12 @@ EM_JS(int, pyproxy_init, (), { result.delete(key); } let ptrobj = _getPtr(jsobj); - let idresult = __pyproxy_ownKeys(ptrobj); + let idresult; + try { + idresult = __pyproxy_ownKeys(ptrobj); + } catch(e) { + Module.fatal_error(e); + } let jsresult = Module.hiwire.get_value(idresult); Module.hiwire.decref(idresult); for(let key of jsresult){ diff --git a/src/core/python2js.c b/src/core/python2js.c index 47cabfa51..71b8d5388 100644 --- a/src/core/python2js.c +++ b/src/core/python2js.c @@ -358,11 +358,6 @@ python2js_with_depth(PyObject* x, int depth) PyObject* map = PyDict_New(); JsRef result = _python2js_cache(x, map, depth); Py_DECREF(map); - - if (result == NULL) { - pythonexc2js(); - } - return result; } diff --git a/src/pyodide.js b/src/pyodide.js index ea89a7ac8..32ae73630 100644 --- a/src/pyodide.js +++ b/src/pyodide.js @@ -319,6 +319,7 @@ globalThis.languagePluginLoader = new Promise((resolve, reject) => { function makePublicAPI(module, public_api) { let namespace = {_module : module}; + module.public_api = namespace; for (let name of public_api) { namespace[name] = module[name]; } @@ -336,6 +337,27 @@ globalThis.languagePluginLoader = new Promise((resolve, reject) => { Module.preloadedWasm = {}; let isFirefox = navigator.userAgent.toLowerCase().indexOf('firefox') > -1; + Module.fatal_error = function(e) { + for (let [key, value] of Object.entries(Module.public_api)) { + if (key.startsWith("_")) { + // delete Module.public_api[key]; + continue; + } + // Have to do this case first because typeof(some_pyproxy) === "function". + if (Module.PyProxy.isPyProxy(value)) { + value.destroy(); + continue; + } + if (typeof (value) === "function") { + Module.public_api[key] = function() { + throw Error("Pyodide has suffered a fatal error, refresh the page. " + + "Please report this to the Pyodide maintainers."); + } + } + } + throw e; + }; + Module.runPython = code => Module.pyodide_py.eval_code(code, Module.globals); // clang-format off diff --git a/src/tests/test_stdlib_fixes.py b/src/tests/test_stdlib_fixes.py index b29b668fe..07fb968e1 100644 --- a/src/tests/test_stdlib_fixes.py +++ b/src/tests/test_stdlib_fixes.py @@ -30,7 +30,7 @@ def test_threading_import(selenium): selenium.run( """ import threading - threading.local() + threading.local(); pass """ )