Skip to content

Commit ace92f0

Browse files
authored
implicit / explicit conversion (#106)
* implicit / explicit conversion * implicit / explicit conversion
1 parent fa64593 commit ace92f0

File tree

4 files changed

+80
-1
lines changed

4 files changed

+80
-1
lines changed

module/pyjs/convert_py_to_js.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ def to_js(value, cache=None, depth=0, max_depth=None):
8282
elif isinstance(value, bytes):
8383
return internal.bytes_to_typed_array(value).buffer
8484

85+
elif hasattr(value, "explicit_to_js"):
86+
return value.explicit_to_js()
87+
88+
elif hasattr(value, "implicit_to_js"):
89+
return value.implicit_to_js()
8590

8691
else:
8792
raise RuntimeError(f"no registerd converted for {value} of type {type(value)}")

src/convert.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ namespace pyjs
1717
// py::module_ pyjs = py::module_::import("pyjs_utils");
1818
// const std::string info = pyjs.attr("implicit_convert_info")(py_ret).cast<std::string>();
1919

20+
2021
const std::string info = py_ret.get_type().attr("__name__").str();
2122

2223
if (info == "int")
@@ -47,6 +48,11 @@ namespace pyjs
4748
{
4849
return std::make_pair(em::val::module_property("_future_to_promise")(em::val(py_ret)),false);
4950
}
51+
else if(py::hasattr(py_ret,"implicit_to_js")){
52+
auto implicit_to_js = py_ret.attr("implicit_to_js");
53+
py::object py_js_ret = implicit_to_js();
54+
return std::make_pair(py_js_ret.cast<em::val>(),false);
55+
}
5056
else
5157
{
5258
return std::make_pair(em::val::module_property("make_proxy")(em::val(py_ret)),true);

src/js_timestamp.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
#define PYJS_JS_UTC_TIMESTAMP "2024-10-18 09:14:27.486802"
1+
#define PYJS_JS_UTC_TIMESTAMP "2025-07-03 10:11:09.123464"

tests/tests/test_pyjs.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,74 @@ def rectangle_converter(js_val, depth, cache, converter_options):
376376
assert r.width == 20
377377

378378

379+
def test_custom_implicit_converter():
380+
381+
class Foo(object):
382+
def __init__(self, value):
383+
384+
self.the_value = -1
385+
self.value = value
386+
387+
def implicit_to_js(self):
388+
obj = pyjs.js_object()
389+
obj["the_value"] = self.value
390+
return obj
391+
392+
class Bar(object):
393+
def __init__(self, value):
394+
self.value = value
395+
self.the_value = -1
396+
397+
def explicit_to_js(self):
398+
obj = pyjs.js_object()
399+
obj["the_value"] = self.value
400+
return obj
401+
402+
class FooBarInstance(object):
403+
def __init__(self, value):
404+
self.value = value
405+
self.the_explicit_value = -1
406+
self.the_implicit_value = -1
407+
408+
def explicit_to_js(self):
409+
obj = pyjs.js_object()
410+
obj["the_explicit_value"] = self.value
411+
return obj
412+
413+
def implicit_to_js(self):
414+
obj = pyjs.js_object()
415+
obj["the_implicit_value"] = self.value
416+
return obj
417+
418+
419+
420+
foo_instance = Foo(42)
421+
js_function = pyjs.js.Function("instance", """
422+
return instance.the_value === 42;
423+
""")
424+
assert js_function(foo_instance) is True
425+
assert js_function(pyjs.to_js(foo_instance)) is True
426+
427+
bar_instance = Bar(42)
428+
assert js_function(bar_instance) is False
429+
assert js_function(pyjs.to_js(bar_instance)) is True
430+
431+
foo_bar_instance = FooBarInstance(42)
432+
js_function = pyjs.js.Function("instance", """
433+
return instance.the_implicit_value === 42;
434+
""")
435+
assert js_function(foo_bar_instance) is True
436+
assert js_function(pyjs.to_js(foo_bar_instance)) is False
437+
438+
js_function = pyjs.js.Function("instance", """
439+
return instance.the_explicit_value === 42;
440+
""")
441+
assert js_function(foo_bar_instance) is False
442+
assert js_function(pyjs.to_js(foo_bar_instance)) is True
443+
444+
445+
446+
379447
def test_del_attr():
380448
obj = eval_jsfunc(
381449
"""{

0 commit comments

Comments
 (0)