Files
pyscript/pyscriptjs/tests/integration/test_03_async.py
Fabio Pliger 3e408b7baa Python Plugins (#961)
* add test and example files

* update config to include python plugins in build

* add markdown plugin

* remove full pyscript execution from pyodide

* move loading of pyscript.py from pyodide loagInterpreter to main setupVirtualEnv and add function to create python CE plugins

* add plugin class to pyscript.py

* add missing import

* fix plugin path

* add fetchPythonPlugins to PyScriptApp

* remove old comments

* fix test

* add support for python plugins beyond custom elements and add app to python namespace in main

* inject reference to PyScript app onto python plugins

* add example hook onto markdown plugin

* change plugin events logs

* remove unused PyPlugin

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* fix type import

* add docstring to fetchPythonPlugins

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* rename addPythonPlugin method

* address PR comment

* call python plugins on hooks after the interpreted is ready

* add test for event hooks and split the test in 2 separate plugins to isolte type of plugins tests

* change python plugins initialization and registration, to inject the app from app itself instead of on the plugins themselves

* handle case when plugin cannot load due to missing plugin attribute

* add test for fail scenario when a plugin module does not have a plugin attribute

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add deprecation warning for pyscript objects loaded in global namespace

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* remove all from global scope

* remove create_custom_element from global scope

* rename create_custom_element to define_custom_element

* rename attributes in define_custom_element and add docstrings

* better handle connect event output

* add warning to py_markdown plugin

* remove debugging logs

* improve tests

* remove debugging log

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* remove unused import

* add executable shebang

* add pyodide mock module

* fmt and lint

* Update to pyodide.ffi.create_proxy per pyodide v21 api change

* Mock pyodide as package instead of mdoule

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* add __init__ to pyodide package

* Update pyscriptjs/src/plugin.ts

fix logger name

Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>

* fix pyodide import but handling the diff in their API change

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* oops, conflict resolution blooper

* Fix failing integration tests

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Jeff Glass <glass.jeffrey@gmail.com>
Co-authored-by: Antonio Cuni <anto.cuni@gmail.com>
Co-authored-by: FabioRosado <fabiorosado@outlook.com>
2022-11-28 12:39:31 -06:00

152 lines
4.8 KiB
Python

from .support import PyScriptTest
class TestAsync(PyScriptTest):
# ensure_future() and create_task() should behave similarly;
# we'll use the same source code to test both
coroutine_script = """
<py-script>
import js
import asyncio
js.console.log("first")
async def main():
await asyncio.sleep(1)
js.console.log("third")
asyncio.{func}(main())
js.console.log("second")
</py-script>
"""
def test_asyncio_ensure_future(self):
self.pyscript_run(self.coroutine_script.format(func="ensure_future"))
self.wait_for_console("third")
assert self.console.log.lines[0] == self.PY_COMPLETE
assert self.console.log.lines[-3:] == ["first", "second", "third"]
def test_asyncio_create_task(self):
self.pyscript_run(self.coroutine_script.format(func="create_task"))
self.wait_for_console("third")
assert self.console.log.lines[0] == self.PY_COMPLETE
assert self.console.log.lines[-3:] == ["first", "second", "third"]
def test_asyncio_gather(self):
self.pyscript_run(
"""
<py-script id="pys">
import asyncio
import js
from pyodide.ffi import to_js
async def coro(delay):
await asyncio.sleep(delay)
return(delay)
async def get_results():
results = await asyncio.gather(*[coro(d) for d in range(3,0,-1)])
js.console.log(to_js(results))
js.console.log("DONE")
asyncio.ensure_future(get_results())
</py-script>
"""
)
self.wait_for_console("DONE")
assert self.console.log.lines[-2:] == ["[3,2,1]", "DONE"]
def test_multiple_async(self):
self.pyscript_run(
"""
<py-script>
import js
import asyncio
async def a_func():
for i in range(3):
js.console.log('A', i)
await asyncio.sleep(0.1)
asyncio.ensure_future(a_func())
</py-script>
<py-script>
import js
import asyncio
async def b_func():
for i in range(3):
js.console.log('B', i)
await asyncio.sleep(0.1)
js.console.log('b func done')
asyncio.ensure_future(b_func())
</py-script>
"""
)
self.wait_for_console("b func done")
assert self.console.log.lines[0] == self.PY_COMPLETE
# We are getting some deprecation warnings from pyodide, so we
# need to skip the first 2 lines
assert self.console.log.lines[3:] == [
"A 0",
"B 0",
"A 1",
"B 1",
"A 2",
"B 2",
"b func done",
]
def test_multiple_async_multiple_display_targetted(self):
self.pyscript_run(
"""
<py-script id='pyA'>
import js
import asyncio
async def a_func():
for i in range(2):
display(f'A{i}', target='pyA')
await asyncio.sleep(0.1)
asyncio.ensure_future(a_func())
</py-script>
<py-script id='pyB'>
import js
import asyncio
async def a_func():
for i in range(2):
display(f'B{i}', target='pyB')
await asyncio.sleep(0.1)
js.console.log("B DONE")
asyncio.ensure_future(a_func())
</py-script>
"""
)
self.wait_for_console("B DONE")
inner_text = self.page.inner_text("html")
assert "A0\nA1\nB0\nB1" in inner_text
def test_async_display_untargetted(self):
self.pyscript_run(
"""
<py-script id='pyA'>
import asyncio
import js
async def a_func():
try:
display('A')
await asyncio.sleep(0.1)
except Exception as err:
js.console.error(str(err))
await asyncio.sleep(1)
js.console.log("DONE")
asyncio.ensure_future(a_func())
</py-script>
"""
)
self.wait_for_console("DONE")
assert (
self.console.error.lines[-1]
== "Implicit target not allowed here. Please use display(..., target=...)"
)