Skip to content

Commit 30cd06c

Browse files
committed
Add pyproxy Reflect.ownKeys handler
1 parent 9cbe7df commit 30cd06c

3 files changed

Lines changed: 53 additions & 0 deletions

File tree

Lib/test/test_pyodide.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,14 @@ class T:
385385
run_js("(o) => {o.a = 72}")(T)
386386
self.assertTrue(T.a == 72)
387387

388+
def test_pyproxy_ownkeys(self):
389+
class T:
390+
a = 7
391+
b = "zz"
392+
393+
l = set(x for x in run_js("(o) => Reflect.ownKeys(o)")(T) if isinstance(x, str))
394+
self.assertGreaterEqual(l, {"a", "b"})
395+
388396
def test_pyproxy_call_simple(self):
389397
def f(x):
390398
return x * x + 7

Modules/_pyodide_core/pyproxy.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,34 @@ _pyproxy_delattr(PyObject* pyobj, JsVal idkey)
237237
return success ? 0 : -1;
238238
}
239239

240+
EMSCRIPTEN_KEEPALIVE JsVal
241+
_pyproxy_ownKeys(PyObject* pyobj)
242+
{
243+
bool success = false;
244+
PyObject* pydir = NULL;
245+
246+
pydir = PyObject_Dir(pyobj);
247+
FAIL_IF_NULL(pydir);
248+
249+
JsVal dir = JsvArray_New();
250+
Py_ssize_t n = PyList_Size(pydir);
251+
FAIL_IF_MINUS_ONE(n);
252+
for (Py_ssize_t i = 0; i < n; ++i) {
253+
PyObject* pyentry = PyList_GetItem(pydir, i); /* borrowed */
254+
JsVal entry = python2js(pyentry);
255+
FAIL_IF_JS_ERROR(entry);
256+
JsvArray_Push(dir, entry);
257+
}
258+
259+
success = true;
260+
finally:
261+
Py_CLEAR(pydir);
262+
if (!success) {
263+
return JS_ERROR;
264+
}
265+
return dir;
266+
}
267+
240268
EMSCRIPTEN_KEEPALIVE int
241269
_pyproxy_contains(PyObject* pyobj, JsVal idkey)
242270
{

Modules/_pyodide_core/pyproxy.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ declare function __pyproxy_hasattr(ptr: number, key: any): number;
2121
declare function __pyproxy_getattr(ptr: number, key: any, cache: Map<string, any>): any;
2222
declare function __pyproxy_setattr(ptr: number, key: any, val: any): number;
2323
declare function __pyproxy_delattr(ptr: number, key: any): number;
24+
declare function __pyproxy_ownKeys(ptr: number): (string | symbol)[];
2425

2526
declare function __pyproxy_contains(ptr: number, key: any): number;
2627
declare function __pyproxy_getitem(ptr: number, key: any): any;
@@ -556,6 +557,22 @@ const PyProxyHandlers = {
556557
python_delattr(jsobj, jskey);
557558
return true;
558559
},
560+
ownKeys(jsobj: PyProxy): (string | symbol)[] {
561+
let ptrobj = _getPtr(jsobj);
562+
let result;
563+
try {
564+
Py_ENTER();
565+
result = __pyproxy_ownKeys(ptrobj);
566+
Py_EXIT();
567+
} catch (e) {
568+
API.fatal_error(e);
569+
}
570+
if (result === Module.error) {
571+
_pythonexc2js();
572+
}
573+
result.push(...Reflect.ownKeys(jsobj));
574+
return result;
575+
},
559576
apply(jsobj: PyProxy & Function, jsthis: any, jsargs: any): any {
560577
return jsobj.apply(jsthis, jsargs);
561578
},

0 commit comments

Comments
 (0)