Commit 01256b58 authored by Michael Droettboom's avatar Michael Droettboom Committed by GitHub

Merge pull request #215 from mdboom/fix-hiwire-iterator

Fix iterators passed from Javascript to Python
parents 6d76f25b 911fe832
...@@ -249,16 +249,32 @@ MAKE_OPERATOR(greater_than, >); ...@@ -249,16 +249,32 @@ MAKE_OPERATOR(greater_than, >);
MAKE_OPERATOR(greater_than_equal, >=); MAKE_OPERATOR(greater_than_equal, >=);
EM_JS(int, hiwire_next, (int idobj), { EM_JS(int, hiwire_next, (int idobj), {
var jsobj = Module.hiwire_get_value(idobj);
// clang-format off // clang-format off
if (jsobj.next === undefined) { if (idobj === -2) {
// clang-format on // clang-format on
return HW_ERROR; return -1;
} }
var jsobj = Module.hiwire_get_value(idobj);
return Module.hiwire_new_value(jsobj.next()); 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), { EM_JS(int, hiwire_nonzero, (int idobj), {
var jsobj = Module.hiwire_get_value(idobj); var jsobj = Module.hiwire_get_value(idobj);
return (jsobj != 0) ? 1 : 0; return (jsobj != 0) ? 1 : 0;
......
...@@ -366,6 +366,12 @@ hiwire_greater_than_equal(int ida, int idb); ...@@ -366,6 +366,12 @@ hiwire_greater_than_equal(int ida, int idb);
int int
hiwire_next(int idobj); 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. * Returns 1 if the value is non-zero.
* *
......
...@@ -169,8 +169,16 @@ JsProxy_RichCompare(PyObject* a, PyObject* b, int op) ...@@ -169,8 +169,16 @@ JsProxy_RichCompare(PyObject* a, PyObject* b, int op)
static PyObject* static PyObject*
JsProxy_GetIter(PyObject* o) JsProxy_GetIter(PyObject* o)
{ {
Py_INCREF(o); JsProxy* self = (JsProxy*)o;
return 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* static PyObject*
...@@ -375,6 +383,10 @@ static PyMethodDef JsProxy_Methods[] = { ...@@ -375,6 +383,10 @@ static PyMethodDef JsProxy_Methods[] = {
(PyCFunction)JsProxy_New, (PyCFunction)JsProxy_New,
METH_VARARGS | METH_KEYWORDS, METH_VARARGS | METH_KEYWORDS,
"Construct a new instance" }, "Construct a new instance" },
{ "__iter__",
(PyCFunction)JsProxy_GetIter,
METH_NOARGS,
"Get an iterator over the object" },
{ "_has_bytes", { "_has_bytes",
(PyCFunction)JsProxy_HasBytes, (PyCFunction)JsProxy_HasBytes,
METH_NOARGS, METH_NOARGS,
......
...@@ -325,8 +325,14 @@ def test_jsproxy_implicit_iter(selenium): ...@@ -325,8 +325,14 @@ def test_jsproxy_implicit_iter(selenium):
""" """
window.ITER = [1, 2, 3];""") window.ITER = [1, 2, 3];""")
assert selenium.run( 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] "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): def test_open_url(selenium):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment