FIX to display function handling null element reference, and wrong target parameter values (#1784)

* blacked

* More robust code for display, with tests

Display now includes more robust controls when checking
the input target parameters, with appropriate exception raised
(i.e. ValueError or TypeError) whether target is either
an empty string, or a not-string, not-None type, respectively.

The TypeError aligns with other similar behaviour with other Pyton
functions (e.g. str.split with integer separator).

Also, now display raises a ValueError whether the target element
is not found or not existing.

All changes are supported by tests.

* traceback lines in check_py_error & removed clones

check_py_error function now automatically includes
check of the traceback in console errors.

This way tests in basic and display have been refactored,
and lots of duplicated code removed.

* removed useless console check lines.

If check_py_errors function is running, those
console log lines are useless to check.
This commit is contained in:
Valerio Maggio
2023-10-03 18:23:44 +01:00
committed by GitHub
parent a08f891b20
commit a00a6750b4
5 changed files with 91 additions and 15 deletions

View File

@@ -29,7 +29,14 @@
# pyscript.magic_js. This is the blessed way to access them from pyscript,
# as it works transparently in both the main thread and worker cases.
from pyscript.magic_js import RUNNING_IN_WORKER, PyWorker, window, document, sync, current_target
from pyscript.magic_js import (
RUNNING_IN_WORKER,
PyWorker,
window,
document,
sync,
current_target,
)
from pyscript.display import HTML, display
try:
@@ -38,6 +45,5 @@ except:
from pyscript.util import NotSupported
when = NotSupported(
"pyscript.when",
"pyscript.when currently not available with this interpreter"
"pyscript.when", "pyscript.when currently not available with this interpreter"
)

View File

@@ -148,9 +148,23 @@ def _write(element, value, append=False):
def display(*values, target=None, append=True):
if target is None:
target = current_target()
elif not isinstance(target, str):
raise TypeError(f"target must be str or None, not {target.__class__.__name__}")
elif target == "":
raise ValueError("Cannot have an empty target")
elif target.startswith("#"):
# note: here target is str and not None!
# align with @when behavior
target = target[1:]
element = document.getElementById(target)
# If target cannot be found on the page, a ValueError is raised
if element is None:
raise ValueError(
f"Invalid selector with id={target}. Cannot be found in the page."
)
# if element is a <script type="py">, it has a 'target' attribute which
# points to the visual element holding the displayed values. In that case,
# use that.

View File

@@ -7,8 +7,9 @@ if RUNNING_IN_WORKER:
import polyscript
PyWorker = NotSupported(
'pyscript.PyWorker',
'pyscript.PyWorker works only when running in the main thread')
"pyscript.PyWorker",
"pyscript.PyWorker works only when running in the main thread",
)
window = polyscript.xworker.window
document = window.document
sync = polyscript.xworker.sync
@@ -21,11 +22,12 @@ if RUNNING_IN_WORKER:
else:
import _pyscript
from _pyscript import PyWorker
window = globalThis
document = globalThis.document
sync = NotSupported(
'pyscript.sync',
'pyscript.sync works only when running in a worker')
"pyscript.sync", "pyscript.sync works only when running in a worker"
)
# in MAIN the current element target exist, just use it
def current_target():