Restore output attribute of py-script tags, add py-script exec lifecycle hooks (#1063)

* Add beforePyScriptExec, afterPyScriptExec lifecycle hooks

* Add stdiodirector plugin for `output`, `stderr` attributes of py-script tag

* Add docs on `output` and `stderr` attributes of py-script tag

* Tests

* Removed output deprecation warning for `output` attribute

* Add createSingularWarning(), with createDeprecationWarning as alias
This commit is contained in:
Jeff Glass
2023-01-10 13:00:29 -06:00
committed by GitHub
parent e1b4415193
commit 470c3489dd
15 changed files with 748 additions and 33 deletions

View File

@@ -37,6 +37,14 @@ class TestLogger(Plugin):
def afterStartup(self, config):
console.log('afterStartup called')
def beforePyScriptExec(self, runtime, src, pyscript_tag):
console.log(f'beforePyScriptExec called')
console.log(f'before_src:{src}')
def afterPyScriptExec(self, runtime, src, pyscript_tag, result):
console.log(f'afterPyScriptExec called')
console.log(f'after_src:{src}')
def onUserError(self, config):
console.log('onUserError called')
@@ -44,6 +52,29 @@ class TestLogger(Plugin):
plugin = TestLogger()
"""
# Source of script that defines a plugin with only beforePyScriptExec and
# afterPyScriptExec methods
EXEC_HOOKS_PLUGIN_CODE = """
from pyscript import Plugin
from js import console
class ExecTestLogger(Plugin):
def beforePyScriptExec(self, runtime, src, pyscript_tag):
console.log(f'beforePyScriptExec called')
console.log(f'before_src:{src}')
console.log(f'before_id:{pyscript_tag.id}')
def afterPyScriptExec(self, runtime, src, pyscript_tag, result):
console.log(f'afterPyScriptExec called')
console.log(f'after_src:{src}')
console.log(f'after_id:{pyscript_tag.id}')
console.log(f'result:{result}')
plugin = ExecTestLogger()
"""
# Source of a script that doesn't call define a `plugin` attribute
NO_PLUGIN_CODE = """
from pyscript import Plugin
@@ -159,7 +190,12 @@ class TestPlugin(PyScriptTest):
for each one of them"""
# GIVEN a plugin that logs specific strings for each app execution event
hooks_available = ["afterSetup", "afterStartup"]
hooks_unavailable = ["configure", "beforeLaunch"]
hooks_unavailable = [
"configure",
"beforeLaunch",
"beforePyScriptExec",
"afterPyScriptExec",
]
# EXPECT it to log the correct logs for the events it intercepts
log_lines = self.console.log.lines
@@ -173,6 +209,28 @@ class TestPlugin(PyScriptTest):
# TODO: It'd be actually better to check that the events get called in order
@prepare_test(
"exec_test_logger",
EXEC_HOOKS_PLUGIN_CODE,
template=HTML_TEMPLATE_NO_TAG + "\n<py-script id='pyid'>x=2; x</py-script>",
)
def test_pyscript_exec_hooks(self):
"""Test that the beforePyScriptExec and afterPyScriptExec hooks work as intended"""
assert self.page.locator("py-script") is not None
log_lines: list[str] = self.console.log.lines
assert "beforePyScriptExec called" in log_lines
assert "afterPyScriptExec called" in log_lines
# These could be made better with a utility function that found log lines
# that match a filter function, or start with something
assert "before_src:x=2; x" in log_lines
assert "before_id:pyid" in log_lines
assert "after_src:x=2; x" in log_lines
assert "after_id:pyid" in log_lines
assert "result:2" in log_lines
@prepare_test("no_plugin", NO_PLUGIN_CODE)
def test_no_plugin_attribute_error(self):
"""