def test_to_js_default_converter2(selenium):
    import json

    import pytest

    from js import JSON, Array
    from pyodide import JsException, run_js, to_js

    class Pair:
        def __init__(self, first, second):
            self.first = first
            self.second = second

    p1 = Pair(1, 2)
    p2 = Pair(1, 2)
    p2.first = p2

    def default_converter(value, convert, cacheConversion):
        result = Array.new()
        cacheConversion(value, result)
        result.push(convert(value.first))
        result.push(convert(value.second))
        return result

    p1js = to_js(p1, default_converter=default_converter)
    p2js = to_js(p2, default_converter=default_converter)

    assert json.loads(JSON.stringify(p1js)) == [1, 2]

    with pytest.raises(JsException, match="TypeError"):
        JSON.stringify(p2js)

    assert run_js("(x) => x[0] === x")(p2js)
    assert run_js("(x) => x[1] === 2")(p2js)
def test_javascript_error_back_to_js(selenium):
    from pyodide import run_js

    err = run_js('self.err = new Error("This is a js error"); err')
    assert type(err).__name__ == "JsException"
    assert run_js("""
        (py_err) => py_err === err;
        """)(err)
def test_tojs1(selenium, ty):
    import json

    from pyodide import run_js

    l = [1, 2, 3]
    x = ty(l)
    assert run_js("x => Array.isArray(x.toJs())")(x)
    serialized = run_js("x => JSON.stringify(x.toJs())")(x)
    assert l == json.loads(serialized)
def test_python2js_long_ints2(selenium):
    from pyodide import run_js

    assert run_js("""
        (x) => x === 2n**64n;
        """)(2**64)

    assert run_js("""
        (x) => x === -(2n**64n);
        """)(-(2**64))
    def main(selenium, sbytes):
        from pyodide import run_js

        spy = bytes(sbytes).decode()
        sjs = run_js("""
            (sbytes) => {
                self.sjs = (new TextDecoder("utf8")).decode(new Uint8Array(sbytes));
                return sjs;
            }
            """)(sbytes)
        assert sjs == spy
        assert run_js("(spy) => spy === self.sjs")(spy)
def test_tojs2(selenium):
    import json

    from pyodide import run_js

    o = [(1, 2), (3, 4), [5, 6], {2: 3, 4: 9}]

    assert run_js("(o) => Array.isArray(o.toJs())")(o)
    serialized = run_js("(o) => JSON.stringify(o.toJs())")(o)
    assert json.loads(serialized) == [[1, 2], [3, 4], [5, 6], {}]
    serialized = run_js(
        "(o) => JSON.stringify(Array.from(o.toJs()[3].entries()))")(o)
    assert json.loads(serialized) == [[2, 3], [4, 9]]
def test_nan_conversions(selenium):
    from pyodide import run_js

    jsnan = run_js("NaN")
    from math import isnan

    assert isnan(jsnan)
    assert run_js("""
        let mathmod = pyodide.pyimport("math");
        const res = Number.isNaN(mathmod.nan);
        mathmod.destroy();
        res
        """)
def test_large_string_conversion(selenium):
    from pyodide import run_js

    longstr = run_js('"ab".repeat(200_000)')
    res = longstr.count("ab")
    assert res == 200_000
    run_js("""
        (s) => {
            assert(() => s.length === 40_000);
            for(let n = 0; n < 20_000; n++){
                assert(() => s.slice(2*n, 2*n+2) === "ab");
            }
        }
        """)("ab" * 20_000)
def test_string_conversion2(selenium, s):
    from pyodide import run_js

    s_encoded = s.encode()
    sjs = run_js("""
        (s_encoded) => {
            let buf = s_encoded.getBuffer();
            self.sjs = (new TextDecoder("utf8")).decode(buf.data);
            buf.release();
            return sjs
        }
        """)(s_encoded)
    assert sjs == s
    assert run_js("""(spy) => spy === self.sjs""")(s)
Exemplo n.º 10
0
def test_hyp_tojs_no_crash(selenium, obj):
    import __main__

    from pyodide import run_js

    __main__.x = obj
    try:
        run_js("""
            let x = pyodide.globals.get("x");
            if(x && x.toJs){
                x.toJs();
            }
            """)
    finally:
        del __main__.x
Exemplo n.º 11
0
def test_dict_converter1(selenium):
    import json

    from pyodide import run_js, to_js

    arrayFrom = run_js("Array.from")
    d = {x: x + 2 for x in range(5)}
    res = to_js(d, dict_converter=arrayFrom)
    constructor, serialized = run_js("""
        (res) => {
            return [res.constructor.name, JSON.stringify(res)];
        }
        """)(res)

    assert constructor == "Array"
    assert json.loads(serialized) == [list(x) for x in d.items()]
Exemplo n.º 12
0
def test_to_py_default_converter2(selenium):
    from typing import Any

    from pyodide import run_js

    [p1, p2] = run_js("""
        class Pair {
            constructor(first, second){
                this.first = first;
                this.second = second;
            }
        }
        const l = [1,2,3];
        const r1 = new Pair(l, [l]);
        const r2 = new Pair(l, [l]);
        r2.first = r2;
        [r1, r2]
        """)

    def default_converter(value, converter, cache):
        if value.constructor.name != "Pair":
            return value
        l: list[Any] = []
        cache(value, l)
        l.append(converter(value.first))
        l.append(converter(value.second))
        return l

    r1 = p1.to_py(default_converter=default_converter)
    assert isinstance(r1, list)
    assert r1[0] is r1[1][0]
    assert r1[0] == [1, 2, 3]

    r2 = p2.to_py(default_converter=default_converter)
    assert r2[0] is r2
Exemplo n.º 13
0
def test_object_with_null_constructor(selenium):
    from unittest import TestCase

    from pyodide import run_js

    o = run_js("Object.create(null)")
    with TestCase().assertRaises(TypeError):
        repr(o)
Exemplo n.º 14
0
def test_to_py4(selenium, obj, msg):
    import pytest

    from pyodide import ConversionError, JsException, run_js

    a = run_js(f"new {obj}")

    with pytest.raises((ConversionError, JsException), match=msg):
        a.to_py()
Exemplo n.º 15
0
def test_python2js5(selenium):
    from pyodide import run_js

    assert run_js("(x) => x.tell()")(open("/foo.txt", "wb")) == 0

    from tempfile import TemporaryFile

    with TemporaryFile(mode="w+") as f:
        contents = ["a\n", "b\n", "hello there!\n"]
        f.writelines(contents)
        assert run_js("(f) => f.tell()")(f) == 17

        assert (run_js("""
                (f) => {
                    f.seek(0);
                    return [f.readline(), f.readline(), f.readline()];
                }
                """)(f).to_py() == contents)
Exemplo n.º 16
0
def test_negative_length(selenium, n):
    from unittest import TestCase

    from pyodide import run_js

    raises = TestCase().assertRaises(ValueError,
                                     msg=f"length {n} of object is negative")

    o = run_js(f"({{length : {n}}})")
    with raises:
        len(o)

    # 1. Set toStringTag to NodeList to force JsProxy to feature detect this object
    # as an array
    # 2. Return a negative length
    # 3. JsProxy_subscript_array should successfully handle this and propagate the error.
    a = run_js(f"({{[Symbol.toStringTag] : 'NodeList', length: {n}}})")
    with raises:
        a[-1]
Exemplo n.º 17
0
def test_wrong_way_conversions2(selenium):
    from pyodide import run_js, to_js

    [astr, bstr] = run_js("""
        (a) => {
            b = [1,2,3];
            return [JSON.stringify(a), JSON.stringify(b)]
        }
        """)(to_js([1, 2, 3]))
    assert astr == bstr
Exemplo n.º 18
0
def test_hyp_py2js2py_2(selenium, obj):
    import __main__

    from pyodide import run_js

    __main__.o = obj
    try:
        assert obj == run_js("pyodide.globals.get('o')")
    finally:
        del __main__.o
Exemplo n.º 19
0
def test_typed_arrays(selenium, jstype, pytype):
    from pyodide import run_js

    array = run_js(f"new {jstype}([1, 2, 3, 4]);").to_py()
    print(array.format, array.tolist(), array.tobytes())
    assert array.format == pytype
    assert array.tolist() == [1, 2, 3, 4]
    import struct

    assert array.tobytes() == struct.pack(pytype * 4, 1, 2, 3, 4)
Exemplo n.º 20
0
def test_python2js2(selenium):
    from pyodide import run_js

    assert (list(
        run_js("""
                (x) => {
                    x = x.toJs();
                    return [x.constructor.name, x.length, x[0]];
                }
                """)(b"bytes")) == ["Uint8Array", 5, 98])
Exemplo n.º 21
0
def test_hyp_py2js2py(selenium, obj):
    import __main__

    from pyodide import run_js

    __main__.obj = obj

    try:
        run_js('self.obj2 = pyodide.globals.get("obj"); 0;')
        from js import obj2

        assert obj2 == obj
        run_js("""
            if(self.obj2 && self.obj2.destroy){
                self.obj2.destroy();
            }
            delete self.obj2
            """)
    finally:
        del __main__.obj
Exemplo n.º 22
0
def test_python2js3(selenium):
    from pyodide import run_js

    l = [7, 9, 13]
    result = run_js("""
        (proxy) => {
            x = proxy.toJs();
            return [proxy.type, x.constructor.name, x.length, x[0], x[1], x[2]]
        }
        """)(l)
    assert list(result) == ["list", "Array", 3, *l]
Exemplo n.º 23
0
def test_big_integer_py2js2py(selenium, a):
    import __main__

    from pyodide import run_js

    __main__.a = a
    try:
        b = run_js("pyodide.globals.get('a')")
        assert a == b
    finally:
        del __main__.a
Exemplo n.º 24
0
def test_wrong_way_conversions3(selenium):
    from pyodide import run_js, to_js

    class Test:
        pass

    t1 = Test()
    t2 = to_js(t1)
    t3 = run_js("(t2) => t2.copy()")(t2)

    assert t1 is t3
    t2.destroy()
Exemplo n.º 25
0
async def test_remove_event_listener_twice(selenium):
    from pyodide import run_js

    x = run_js("""
class MockObject {
    constructor() {
        this.listeners = {};
    }
    addEventListener(event, handler) {
        if (event in this.listeners) {
            this.listeners[event].push(handler);
        }
        else {
            this.listeners[event] = [handler];
        }
    }
    removeEventListener(event, handler) {
        if (event in this.listeners) {
            this.listeners[event] = this.listeners[event].filter(
                (existingHandler) => existingHandler !== handler
            )
        }
    }
    triggerEvent(event) {
        if (this.listeners[event]) {
            for (const handler of this.listeners[event]) {
                handler({});
            }
        }
    }
}
let x = new MockObject();
x;
    """)
    triggered = False
    error_raised = False

    def foo(obj):
        nonlocal triggered
        triggered = True

    from pyodide import add_event_listener, remove_event_listener

    add_event_listener(x, "click", foo)
    remove_event_listener(x, "click", foo)

    try:
        remove_event_listener(x, "click", foo)
    except KeyError:
        error_raised = True

    assert error_raised
Exemplo n.º 26
0
def test_to_py3(selenium):
    from pyodide import run_js

    a = run_js("""
        class Temp {
            constructor(){
                this.x = 2;
                this.y = 7;
            }
        }
        new Temp();
        """)
    assert repr(type(a.to_py())) == "<class 'pyodide.JsProxy'>"
Exemplo n.º 27
0
    def main(selenium, s):
        import json

        from pyodide import run_js

        x_py = json.loads(s)
        run_js(f"""
            self.x_js = eval('{s}n'); // JSON.parse apparently doesn't work
            """)
        [x1, x2] = run_js("""
            (x_py) => [x_py.toString(), x_js.toString()]
            """)(x_py)
        assert x1 == x2
        from js import x_js

        check = run_js("""
            (x) => {
                const [a, b] = x.toJs();
                return a === b;
            }
            """)([str(x_js), str(x_py)])
        assert check
Exemplo n.º 28
0
def test_python2js4(selenium):
    from pyodide import run_js

    assert (list(
        run_js("""
                (proxy) => {
                    let typename = proxy.type;
                    let x = proxy.toJs();
                    return [proxy.type, x.constructor.name, x.get(42)];
                }
                """)({
            42: 64
        })) == ["dict", "Map", 64])
Exemplo n.º 29
0
def test_dict_converter3(selenium):
    import json

    from js import Object
    from pyodide import run_js, to_js

    d = {x: x + 2 for x in range(5)}

    res = to_js(d, dict_converter=Object.fromEntries)
    constructor, serialized = run_js("""
        (res) => [res.constructor.name, JSON.stringify(res)]
        """)(res)

    assert constructor == "Object"
    assert json.loads(serialized) == {str(k): v for k, v in d.items()}
Exemplo n.º 30
0
def test_jsproxy_attribute_error(selenium):
    import pytest

    from pyodide import run_js

    point = run_js("""
        class Point {
            constructor(x, y) {
                this.x = x;
                this.y = y;
            }
        }
        new Point(42, 43);
        """)
    assert point.y == 43

    with pytest.raises(AttributeError, match="z"):
        point.z

    del point.y
    with pytest.raises(AttributeError, match="y"):
        point.y

    assert run_js("(point) => point.y;")(point) is None