mirror of https://github.com/pyodide/pyodide.git
Merge pull request #215 from mdboom/fix-hiwire-iterator
Fix iterators passed from Javascript to Python
This commit is contained in:
commit
01256b5832
22
src/hiwire.c
22
src/hiwire.c
|
@ -249,16 +249,32 @@ MAKE_OPERATOR(greater_than, >);
|
|||
MAKE_OPERATOR(greater_than_equal, >=);
|
||||
|
||||
EM_JS(int, hiwire_next, (int idobj), {
|
||||
var jsobj = Module.hiwire_get_value(idobj);
|
||||
// clang-format off
|
||||
if (jsobj.next === undefined) {
|
||||
if (idobj === -2) {
|
||||
// clang-format on
|
||||
return HW_ERROR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
var jsobj = Module.hiwire_get_value(idobj);
|
||||
return Module.hiwire_new_value(jsobj.next());
|
||||
});
|
||||
|
||||
EM_JS(int, hiwire_get_iterator, (int idobj), {
|
||||
// clang-format off
|
||||
if (idobj === -2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
var jsobj = Module.hiwire_get_value(idobj);
|
||||
if (typeof jsobj.next === 'function') {
|
||||
return Module.hiwire_new_value(jsobj);
|
||||
} else if (typeof jsobj[Symbol.iterator] === 'function') {
|
||||
return Module.hiwire_new_value(jsobj[Symbol.iterator]())
|
||||
}
|
||||
return -1;
|
||||
// clang-format on
|
||||
})
|
||||
|
||||
EM_JS(int, hiwire_nonzero, (int idobj), {
|
||||
var jsobj = Module.hiwire_get_value(idobj);
|
||||
return (jsobj != 0) ? 1 : 0;
|
||||
|
|
|
@ -366,6 +366,12 @@ hiwire_greater_than_equal(int ida, int idb);
|
|||
int
|
||||
hiwire_next(int idobj);
|
||||
|
||||
/**
|
||||
* Returns the iterator associated with the given object, if any.
|
||||
*/
|
||||
int
|
||||
hiwire_get_iterator(int idobj);
|
||||
|
||||
/**
|
||||
* Returns 1 if the value is non-zero.
|
||||
*
|
||||
|
|
|
@ -169,8 +169,16 @@ JsProxy_RichCompare(PyObject* a, PyObject* b, int op)
|
|||
static PyObject*
|
||||
JsProxy_GetIter(PyObject* o)
|
||||
{
|
||||
Py_INCREF(o);
|
||||
return o;
|
||||
JsProxy* self = (JsProxy*)o;
|
||||
|
||||
int iditer = hiwire_get_iterator(self->js);
|
||||
|
||||
if (iditer == HW_ERROR) {
|
||||
PyErr_SetString(PyExc_TypeError, "Object is not iterable");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return js2python(iditer);
|
||||
}
|
||||
|
||||
static PyObject*
|
||||
|
@ -375,6 +383,10 @@ static PyMethodDef JsProxy_Methods[] = {
|
|||
(PyCFunction)JsProxy_New,
|
||||
METH_VARARGS | METH_KEYWORDS,
|
||||
"Construct a new instance" },
|
||||
{ "__iter__",
|
||||
(PyCFunction)JsProxy_GetIter,
|
||||
METH_NOARGS,
|
||||
"Get an iterator over the object" },
|
||||
{ "_has_bytes",
|
||||
(PyCFunction)JsProxy_HasBytes,
|
||||
METH_NOARGS,
|
||||
|
|
|
@ -325,8 +325,14 @@ def test_jsproxy_implicit_iter(selenium):
|
|||
"""
|
||||
window.ITER = [1, 2, 3];""")
|
||||
assert selenium.run(
|
||||
"from js import ITER\n"
|
||||
"from js import ITER, Object\n"
|
||||
"list(ITER)") == [1, 2, 3]
|
||||
assert selenium.run(
|
||||
"from js import ITER, Object\n"
|
||||
"list(ITER.values())") == [1, 2, 3]
|
||||
assert selenium.run(
|
||||
"from js import ITER, Object\n"
|
||||
"list(Object.values(ITER))") == [1, 2, 3]
|
||||
|
||||
|
||||
def test_open_url(selenium):
|
||||
|
|
Loading…
Reference in New Issue