slint
slint copied to clipboard
Python: Make `__str__` work for `CompileError`'s `diagnostics` field
As seen in #5469, when printing the CompileError struct, the diagnostics are not correctly transformed to a readable representation. While __str__ is implemented on PyDiagnostics, somehow it doesn't transcend into the list that's created from it.
Fixing this would make it easier to quickly discover the root cause for a run-time generated Slint compile error.
The Demo works, but when packaged with pyinstaller, it doesn't
python 3.10 slint 1.6.0a8 package command : pyinstaller -FD main.py --add-data "appwindow.slint:./"
Traceback (most recent call last):
File "main.py", line 5, in <module>
File "slint/__init__.py", line 182, in load_file
slint.CompileError: ('Could not compile appwindow.slint', [<builtins.PyDiagnostic object at 0x109ff1ac0>])
[53112] Failed to execute script 'main' due to unhandled exception!
import slint
components = slint.load_file("appwindow.slint")
main_window = components.MainWindow()
main_window.run()
I think that may be because when passing a relative path to load_file() will it be resolved against the process' working directory. You could try something like this instead: slint.load_file(os.path.join(os.path.dirname(__file__), "appwindow.slint"))
I worked around this issue by just calling the slint class twice, but it would be nice if I didn't have to do this workaround
try:
slint.loader.ui.alarm_list_window.AlarmListWindow
except slint.CompileError as e:
print(e.message)
for diagnostic in e.diagnostics:
print(diagnostic)
sys.exit(1)
class AlarmListWindow(slint.loader.ui.alarm_list_window.AlarmListWindow):
Might be worth using PEP 678 for this: https://peps.python.org/pep-0678/
In addition, I think the line number and column number fields are interchanged when initialising the object.
Sample slint file:
import {
Button, StandardTableView, ProgressIndicator, ListView,
VerticalBox, HorizontalBox,
} from "std-widgets.slint"; // deliberate error in next line
j
Python:
import slint
try:
slint_gui = slint.load_file(pathlib.Path(__file__).parents[0]/"app-window.slint")
except slint.CompileError as e:
for i in e.diagnostics:
e.add_note(f"{i.column_number = }, {i.line_number = }, {i.message = }")
raise
Traceback:
...
slint.CompileError: ('Could not compile /home/isoraqathedh/Documents/Programming/GitHub/autowordle/autowordle/app-window.slint', [<builtins.PyDiagnostic object at 0x7f68bdd62240>])
i.column_number = 5, i.line_number = 1, i.message = 'Parse error: expected a top-level item such as a component, a struct, or a global'
Note the column number is 5 and the line number is 1 but it should be the other way around.
Oh gosh, you're right - they're swapped.
Thanks for the suggestions! ❤️ I agree, PEP 678 seems like a nice feature to use for this.