From 67ae415f0970a1031399114992248f64115e7a7c Mon Sep 17 00:00:00 2001 From: Michael Droettboom Date: Mon, 22 Apr 2019 14:08:29 -0400 Subject: [PATCH] Fix #388: Support dir(x) on JsProxies (#393) --- src/hiwire.c | 9 +++++++++ src/hiwire.h | 7 +++++++ src/jsproxy.c | 15 +++++++++++++++ test/test_python.py | 7 +++++++ 4 files changed, 38 insertions(+) diff --git a/src/hiwire.c b/src/hiwire.c index 728ea31b7..73ad7be2d 100644 --- a/src/hiwire.c +++ b/src/hiwire.c @@ -241,6 +241,15 @@ EM_JS(void, hiwire_delete_member_obj, (int idobj, int ididx), { delete jsobj[jsidx]; }); +EM_JS(int, hiwire_dir, (int idobj), { + var jsobj = Module.hiwire_get_value(idobj); + var result = []; + do { + result.push.apply(result, Object.getOwnPropertyNames(jsobj)); + } while ((jsobj = Object.getPrototypeOf(jsobj))); + return Module.hiwire_new_value(result); +}); + EM_JS(int, hiwire_call, (int idfunc, int idargs), { var jsfunc = Module.hiwire_get_value(idfunc); var jsargs = Module.hiwire_get_value(idargs); diff --git a/src/hiwire.h b/src/hiwire.h index df13fcf4a..861846735 100644 --- a/src/hiwire.h +++ b/src/hiwire.h @@ -346,6 +346,13 @@ hiwire_set_member_obj(int idobj, int ididx, int idval); void hiwire_delete_member_obj(int idobj, int ididx); +/** + * Get the methods on an object, both on itself and what it inherits. + * + */ +int +hiwire_dir(int idobj); + /** * Call a function * diff --git a/src/jsproxy.c b/src/jsproxy.c index e85115eee..ec818194d 100644 --- a/src/jsproxy.c +++ b/src/jsproxy.c @@ -383,6 +383,17 @@ JsProxy_HasBytes(PyObject* o) } } +static PyObject* +JsProxy_Dir(PyObject* o) +{ + JsProxy* self = (JsProxy*)o; + + int iddir = hiwire_dir(self->js); + PyObject* pydir = js2python(iddir); + hiwire_decref(iddir); + return pydir; +} + // clang-format off static PyMappingMethods JsProxy_MappingMethods = { JsProxy_length, @@ -408,6 +419,10 @@ static PyMethodDef JsProxy_Methods[] = { (PyCFunction)JsProxy_HasBytes, METH_NOARGS, "Returns true if instance has buffer memory. For testing only." }, + { "__dir__", + (PyCFunction)JsProxy_Dir, + METH_NOARGS, + "Returns a list of the members and methods on the object." }, { NULL } }; // clang-format on diff --git a/test/test_python.py b/test/test_python.py index b246002be..cf44484dc 100644 --- a/test/test_python.py +++ b/test/test_python.py @@ -443,6 +443,13 @@ def test_jsproxy(selenium): dict(TEST) == {'foo': 'bar', 'baz': 'bap'} """ ) is True + assert selenium.run( + """ + from js import document + el = document.createElement('div') + len(dir(el)) >= 200 and 'appendChild' in dir(el) + """ + ) is True def test_jsproxy_iter(selenium):