mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 10:50:00 +00:00
Python: Fix mypy also on the Slint module implementation
This commit is contained in:
parent
607d70b3fa
commit
9001966dc9
6 changed files with 113 additions and 83 deletions
|
@ -199,7 +199,7 @@ impl CompilationResult {
|
|||
|
||||
#[gen_stub_pyclass]
|
||||
#[pyclass(unsendable)]
|
||||
struct ComponentDefinition {
|
||||
pub struct ComponentDefinition {
|
||||
definition: slint_interpreter::ComponentDefinition,
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ use pyo3_stub_gen::{define_stub_info_gatherer, derive::gen_stub_pyfunction};
|
|||
mod image;
|
||||
mod interpreter;
|
||||
use interpreter::{
|
||||
CompilationResult, Compiler, ComponentInstance, PyDiagnostic, PyDiagnosticLevel, PyValueType,
|
||||
CompilationResult, Compiler, ComponentDefinition, ComponentInstance, PyDiagnostic,
|
||||
PyDiagnosticLevel, PyValueType,
|
||||
};
|
||||
mod brush;
|
||||
mod errors;
|
||||
|
@ -45,6 +46,7 @@ fn slint(_py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|||
m.add_class::<Compiler>()?;
|
||||
m.add_class::<CompilationResult>()?;
|
||||
m.add_class::<ComponentInstance>()?;
|
||||
m.add_class::<ComponentDefinition>()?;
|
||||
m.add_class::<image::PyImage>()?;
|
||||
m.add_class::<PyValueType>()?;
|
||||
m.add_class::<PyDiagnosticLevel>()?;
|
||||
|
|
|
@ -14,7 +14,7 @@ import logging
|
|||
import importlib
|
||||
import copy
|
||||
import typing
|
||||
import builtins
|
||||
from typing import Any
|
||||
import pathlib
|
||||
from .models import ListModel, Model
|
||||
from .slint import Image, Color, Brush, Timer, TimerMode
|
||||
|
@ -22,27 +22,29 @@ from .slint import Image, Color, Brush, Timer, TimerMode
|
|||
Struct = native.PyStruct
|
||||
|
||||
class CompileError(Exception):
|
||||
def __init__(self, message, diagnostics):
|
||||
def __init__(self, message: str, diagnostics: list[native.PyDiagnostic]):
|
||||
self.message = message
|
||||
self.diagnostics = diagnostics
|
||||
|
||||
|
||||
class Component:
|
||||
def show(self):
|
||||
__instance__: native.ComponentInstance
|
||||
|
||||
def show(self) -> None:
|
||||
self.__instance__.show()
|
||||
|
||||
def hide(self):
|
||||
def hide(self) -> None:
|
||||
self.__instance__.hide()
|
||||
|
||||
def run(self):
|
||||
def run(self) -> None:
|
||||
self.__instance__.run()
|
||||
|
||||
|
||||
def _normalize_prop(name):
|
||||
def _normalize_prop(name: str) -> str:
|
||||
return name.replace("-", "_")
|
||||
|
||||
|
||||
def _build_global_class(compdef, global_name):
|
||||
def _build_global_class(compdef: native.ComponentDefinition, global_name: str) -> Any:
|
||||
properties_and_callbacks = {}
|
||||
|
||||
for prop_name in compdef.global_properties(global_name).keys():
|
||||
|
@ -51,12 +53,12 @@ def _build_global_class(compdef, global_name):
|
|||
logging.warning(f"Duplicated property {prop_name}")
|
||||
continue
|
||||
|
||||
def mk_setter_getter(prop_name):
|
||||
def getter(self):
|
||||
def mk_setter_getter(prop_name: str): # type: ignore
|
||||
def getter(self): # type: ignore
|
||||
return self.__instance__.get_global_property(
|
||||
global_name, prop_name)
|
||||
|
||||
def setter(self, value):
|
||||
def setter(self, value): # type: ignore
|
||||
return self.__instance__.set_global_property(
|
||||
global_name, prop_name, value)
|
||||
|
||||
|
@ -70,13 +72,13 @@ def _build_global_class(compdef, global_name):
|
|||
logging.warning(f"Duplicated property {prop_name}")
|
||||
continue
|
||||
|
||||
def mk_setter_getter(callback_name):
|
||||
def getter(self):
|
||||
def call(*args):
|
||||
def mk_setter_getter(callback_name: str): # type: ignore
|
||||
def getter(self): # type: ignore
|
||||
def call(*args: Any) -> Any:
|
||||
return self.__instance__.invoke_global(global_name, callback_name, *args)
|
||||
return call
|
||||
|
||||
def setter(self, value):
|
||||
def setter(self, value): # type: ignore
|
||||
return self.__instance__.set_global_callback(
|
||||
global_name, callback_name, value)
|
||||
|
||||
|
@ -90,9 +92,9 @@ def _build_global_class(compdef, global_name):
|
|||
logging.warning(f"Duplicated function {prop_name}")
|
||||
continue
|
||||
|
||||
def mk_getter(function_name):
|
||||
def getter(self):
|
||||
def call(*args):
|
||||
def mk_getter(function_name: str): # type: ignore
|
||||
def getter(self): # type: ignore
|
||||
def call(*args: Any) -> Any:
|
||||
return self.__instance__.invoke_global(global_name, function_name, *args)
|
||||
return call
|
||||
|
||||
|
@ -103,17 +105,17 @@ def _build_global_class(compdef, global_name):
|
|||
return type("SlintGlobalClassWrapper", (), properties_and_callbacks)
|
||||
|
||||
|
||||
def _build_class(compdef):
|
||||
def _build_class(compdef: native.ComponentDefinition): # type: ignore
|
||||
|
||||
def cls_init(self, **kwargs):
|
||||
def cls_init(self: Any, **kwargs) -> Any: # type: ignore
|
||||
self.__instance__ = compdef.create()
|
||||
for name, value in self.__class__.__dict__.items():
|
||||
if hasattr(value, "slint.callback"):
|
||||
callback_info = getattr(value, "slint.callback")
|
||||
name = callback_info["name"]
|
||||
|
||||
def mk_callback(self, callback):
|
||||
def invoke(*args, **kwargs):
|
||||
def mk_callback(self: Any, callback: typing.Callable[..., Any]) -> typing.Callable[..., Any]:
|
||||
def invoke(*args: Any, **kwargs: Any) -> Any:
|
||||
return callback(self, *args, **kwargs)
|
||||
return invoke
|
||||
|
||||
|
@ -137,12 +139,12 @@ def _build_class(compdef):
|
|||
logging.warning(f"Duplicated property {prop_name}")
|
||||
continue
|
||||
|
||||
def mk_setter_getter(prop_name):
|
||||
def getter(self):
|
||||
def mk_setter_getter(prop_name: str) -> Any:
|
||||
def getter(self) -> Any: # type: ignore
|
||||
return self.__instance__.get_property(prop_name)
|
||||
|
||||
def setter(self, value):
|
||||
return self.__instance__.set_property(
|
||||
def setter(self, value: Any) -> None: # type: ignore
|
||||
self.__instance__.set_property(
|
||||
prop_name, value)
|
||||
|
||||
return property(getter, setter)
|
||||
|
@ -155,15 +157,14 @@ def _build_class(compdef):
|
|||
logging.warning(f"Duplicated property {prop_name}")
|
||||
continue
|
||||
|
||||
def mk_setter_getter(callback_name):
|
||||
def getter(self):
|
||||
def call(*args):
|
||||
def mk_setter_getter(callback_name: str) -> Any: # type: ignore
|
||||
def getter(self): # type: ignore
|
||||
def call(*args: Any) -> Any:
|
||||
return self.__instance__.invoke(callback_name, *args)
|
||||
return call
|
||||
|
||||
def setter(self, value):
|
||||
return self.__instance__.set_callback(
|
||||
callback_name, value)
|
||||
def setter(self, value: any): # type: ignore
|
||||
self.__instance__.set_callback(callback_name, value)
|
||||
|
||||
return property(getter, setter)
|
||||
|
||||
|
@ -175,9 +176,9 @@ def _build_class(compdef):
|
|||
logging.warning(f"Duplicated function {prop_name}")
|
||||
continue
|
||||
|
||||
def mk_getter(function_name):
|
||||
def getter(self):
|
||||
def call(*args):
|
||||
def mk_getter(function_name: str): # type: ignore
|
||||
def getter(self) -> Any: # type: ignore
|
||||
def call(*args: Any) -> Any:
|
||||
return self.__instance__.invoke(function_name, *args)
|
||||
return call
|
||||
|
||||
|
@ -188,8 +189,8 @@ def _build_class(compdef):
|
|||
for global_name in compdef.globals:
|
||||
global_class = _build_global_class(compdef, global_name)
|
||||
|
||||
def mk_global(global_class):
|
||||
def global_getter(self):
|
||||
def mk_global(global_class: typing.Callable[..., Any]): # type: ignore
|
||||
def global_getter(self) -> Any: # type: ignore
|
||||
wrapper = global_class()
|
||||
setattr(wrapper, "__instance__", self.__instance__)
|
||||
return wrapper
|
||||
|
@ -201,9 +202,9 @@ def _build_class(compdef):
|
|||
return type("SlintClassWrapper", (Component,), properties_and_callbacks)
|
||||
|
||||
|
||||
def _build_struct(name, struct_prototype):
|
||||
def _build_struct(name: str, struct_prototype: native.PyStruct) -> type:
|
||||
|
||||
def new_struct(cls, *args, **kwargs):
|
||||
def new_struct(cls: Any, *args: Any, **kwargs: Any) -> native.PyStruct:
|
||||
inst = copy.copy(struct_prototype)
|
||||
|
||||
for prop, val in kwargs.items():
|
||||
|
@ -218,7 +219,7 @@ def _build_struct(name, struct_prototype):
|
|||
return type(name, (), type_dict)
|
||||
|
||||
|
||||
def load_file(path: builtins.str | os.PathLike | pathlib.Path, quiet:bool=False, style:typing.Optional[str]=None, include_paths:typing.Optional[typing.List[builtins.str | os.PathLike | pathlib.Path]]=None, library_paths:typing.Optional[typing.List[builtins.str | os.PathLike | pathlib.Path]]=None, translation_domain:typing.Optional[str]=None):
|
||||
def load_file(path: str | os.PathLike[Any] | pathlib.Path, quiet:bool=False, style:typing.Optional[str]=None, include_paths:typing.Optional[typing.List[str | os.PathLike[Any] | pathlib.Path]]=None, library_paths:typing.Optional[typing.List[str | os.PathLike[Any] | pathlib.Path]]=None, translation_domain:typing.Optional[str]=None) -> Any:
|
||||
compiler = native.Compiler()
|
||||
|
||||
if style is not None:
|
||||
|
@ -264,13 +265,12 @@ def load_file(path: builtins.str | os.PathLike | pathlib.Path, quiet:bool=False,
|
|||
|
||||
|
||||
class SlintAutoLoader:
|
||||
def __init__(self, base_dir=None):
|
||||
def __init__(self, base_dir: str | None=None):
|
||||
self.local_dirs: typing.List[str] | None = None
|
||||
if base_dir:
|
||||
self.local_dirs = [base_dir]
|
||||
else:
|
||||
self.local_dirs = None
|
||||
|
||||
def __getattr__(self, name):
|
||||
|
||||
def __getattr__(self, name: str) -> Any:
|
||||
for path in self.local_dirs or sys.path:
|
||||
dir_candidate = os.path.join(path, name)
|
||||
if os.path.isdir(dir_candidate):
|
||||
|
@ -297,14 +297,14 @@ class SlintAutoLoader:
|
|||
loader = SlintAutoLoader()
|
||||
|
||||
|
||||
def _callback_decorator(callable, info):
|
||||
def _callback_decorator(callable: typing.Callable[..., Any], info: typing.Dict[str, Any]) -> typing.Callable[..., Any]:
|
||||
if "name" not in info:
|
||||
info["name"] = callable.__name__
|
||||
setattr(callable, "slint.callback", info)
|
||||
return callable
|
||||
|
||||
|
||||
def callback(global_name=None, name=None) -> typing.Callable[..., typing.Any]:
|
||||
def callback(global_name: str | None=None, name : str | None=None) -> typing.Callable[..., Any]:
|
||||
if callable(global_name):
|
||||
callback = global_name
|
||||
return _callback_decorator(callback, {})
|
||||
|
@ -316,7 +316,7 @@ def callback(global_name=None, name=None) -> typing.Callable[..., typing.Any]:
|
|||
info["global_name"] = global_name
|
||||
return lambda callback: _callback_decorator(callback, info)
|
||||
|
||||
def set_xdg_app_id(app_id: str):
|
||||
def set_xdg_app_id(app_id: str) -> None:
|
||||
native.set_xdg_app_id(app_id)
|
||||
|
||||
__all__ = ["CompileError", "Component", "load_file", "loader", "Image", "Color",
|
||||
|
|
|
@ -4,29 +4,41 @@
|
|||
from . import slint as native
|
||||
from collections.abc import Iterable
|
||||
import typing
|
||||
from typing import Any, cast, Iterator
|
||||
|
||||
|
||||
class Model[T](native.PyModelBase):
|
||||
def __new__(cls, *args):
|
||||
class Model[T](native.PyModelBase, Iterable[T]):
|
||||
def __new__(cls, *args: Any) -> "Model[T]":
|
||||
return super().__new__(cls)
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self) -> None:
|
||||
self.init_self(self)
|
||||
|
||||
def __len__(self):
|
||||
def __len__(self) -> int:
|
||||
return self.row_count()
|
||||
|
||||
def __getitem__(self, index):
|
||||
def __getitem__(self, index: int) -> typing.Optional[T]:
|
||||
return self.row_data(index)
|
||||
|
||||
def __setitem__(self, index, value):
|
||||
def __setitem__(self, index: int, value: T) -> None:
|
||||
self.set_row_data(index, value)
|
||||
|
||||
def __iter__(self):
|
||||
def __iter__(self) -> Iterator[T]:
|
||||
return ModelIterator(self)
|
||||
|
||||
def notify_row_changed(self, row: int) -> None:
|
||||
super().notify_row_changed(row)
|
||||
|
||||
def notify_row_removed(self, row: int, count: int) -> None:
|
||||
super().notify_row_removed(row, count)
|
||||
|
||||
class ListModel[T](Model):
|
||||
def notify_row_added(self, row: int, count: int) -> None:
|
||||
super().notify_row_added(row, count)
|
||||
|
||||
def row_data(self, row: int) -> typing.Optional[T]:
|
||||
return cast(T, super().row_data(row))
|
||||
|
||||
class ListModel[T](Model[T]):
|
||||
def __init__(self, iterable: typing.Optional[Iterable[T]]=None):
|
||||
super().__init__()
|
||||
if iterable is not None:
|
||||
|
@ -40,11 +52,11 @@ class ListModel[T](Model):
|
|||
def row_data(self, row:int ) -> typing.Optional[T]:
|
||||
return self.list[row]
|
||||
|
||||
def set_row_data(self, row: int, data: T):
|
||||
def set_row_data(self, row: int, data: T) -> None:
|
||||
self.list[row] = data
|
||||
super().notify_row_changed(row)
|
||||
|
||||
def __delitem__(self, key: int | slice):
|
||||
def __delitem__(self, key: int | slice) -> None:
|
||||
if isinstance(key, slice):
|
||||
start, stop, step = key.indices(len(self.list))
|
||||
del self.list[key]
|
||||
|
@ -54,23 +66,25 @@ class ListModel[T](Model):
|
|||
del self.list[key]
|
||||
super().notify_row_removed(key, 1)
|
||||
|
||||
def append(self, value: T):
|
||||
def append(self, value: T) -> None:
|
||||
index = len(self.list)
|
||||
self.list.append(value)
|
||||
super().notify_row_added(index, 1)
|
||||
|
||||
|
||||
class ModelIterator:
|
||||
def __init__(self, model):
|
||||
class ModelIterator[T](Iterator[T]):
|
||||
def __init__(self, model: Model[T]):
|
||||
self.model = model
|
||||
self.index = 0
|
||||
|
||||
def __iter__(self):
|
||||
def __iter__(self) -> "ModelIterator[T]":
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
def __next__(self) -> T:
|
||||
if self.index >= self.model.row_count():
|
||||
raise StopIteration()
|
||||
index = self.index
|
||||
self.index += 1
|
||||
return self.model.row_data(index)
|
||||
data = self.model.row_data(index)
|
||||
assert data is not None
|
||||
return data
|
||||
|
|
|
@ -31,7 +31,7 @@ class Color:
|
|||
green: builtins.int
|
||||
blue: builtins.int
|
||||
alpha: builtins.int
|
||||
def __new__(cls,maybe_value:typing.Optional[builtins.str | RgbaColor | RgbColor | typing.Dict[str, int]] = None): ...
|
||||
def __new__(cls,maybe_value:typing.Optional[builtins.str | RgbaColor | RgbColor | typing.Dict[str, int]] = None) -> "Color": ...
|
||||
def brighter(self, factor:builtins.float) -> "Color":
|
||||
...
|
||||
|
||||
|
@ -57,7 +57,7 @@ class Color:
|
|||
|
||||
class Brush:
|
||||
color: Color
|
||||
def __new__(cls,maybe_value:typing.Optional[Color]): ...
|
||||
def __new__(cls,maybe_value:typing.Optional[Color]) -> "Brush": ...
|
||||
def is_transparent(self) -> builtins.bool:
|
||||
...
|
||||
|
||||
|
@ -89,9 +89,9 @@ class Image:
|
|||
width: builtins.int
|
||||
height: builtins.int
|
||||
path: typing.Optional[builtins.str]
|
||||
def __new__(cls,): ...
|
||||
def __new__(cls,) -> "Image": ...
|
||||
@staticmethod
|
||||
def load_from_path(path:builtins.str | os.PathLike | pathlib.Path) -> "Image":
|
||||
def load_from_path(path:builtins.str | os.PathLike[Any] | pathlib.Path) -> "Image":
|
||||
r"""
|
||||
Loads the image from the specified path. Returns None if the image can't be loaded.
|
||||
"""
|
||||
|
@ -131,7 +131,7 @@ class Timer:
|
|||
def set_interval(self, interval:datetime.timedelta) -> None:
|
||||
...
|
||||
|
||||
def set_xdg_app_id(app_id: str):
|
||||
def set_xdg_app_id(app_id: str) -> None:
|
||||
...
|
||||
|
||||
def run_event_loop() -> None: ...
|
||||
|
@ -139,7 +139,13 @@ def run_event_loop() -> None: ...
|
|||
def quit_event_loop() -> None: ...
|
||||
|
||||
class PyModelBase:
|
||||
...
|
||||
def init_self(self, *args: Any) -> None: ...
|
||||
def row_count(self) -> int: ...
|
||||
def row_data(self, row: int) -> typing.Optional[Any]: ...
|
||||
def set_row_data(self, row: int, value: Any) -> None: ...
|
||||
def notify_row_changed(self, row: int) -> None: ...
|
||||
def notify_row_removed(self, row: int, count: int) -> None: ...
|
||||
def notify_row_added(self, row: int, count: int) -> None: ...
|
||||
|
||||
class PyStruct(Any):
|
||||
...
|
||||
|
@ -168,14 +174,17 @@ class PyDiagnostic:
|
|||
|
||||
|
||||
class ComponentInstance:
|
||||
def invoke(self, callback_name: str, *args): ...
|
||||
def invoke_global(self, global_name: str, callback_name: str, *args): ...
|
||||
def set_property(self, property_name: str, value: Any): ...
|
||||
def get_property(self, property_name: str): ...
|
||||
def set_callback(self, callback_name: str, callback: Callable[..., Any]): ...
|
||||
def set_global_callback(self, global_name: str, callback_name: str, callback: Callable[..., Any]): ...
|
||||
def set_global_property(self, global_name: str, property_name: str, value: Any): ...
|
||||
def get_global_property(self, global_name: str, property_name: str): ...
|
||||
def show(self) -> None: ...
|
||||
def hide(self) -> None: ...
|
||||
def run(self) -> None: ...
|
||||
def invoke(self, callback_name: str, *args: Any) -> Any: ...
|
||||
def invoke_global(self, global_name: str, callback_name: str, *args: Any) -> Any: ...
|
||||
def set_property(self, property_name: str, value: Any) -> None: ...
|
||||
def get_property(self, property_name: str) -> Any: ...
|
||||
def set_callback(self, callback_name: str, callback: Callable[..., Any]) -> None: ...
|
||||
def set_global_callback(self, global_name: str, callback_name: str, callback: Callable[..., Any]) -> None: ...
|
||||
def set_global_property(self, global_name: str, property_name: str, value: Any) -> None: ...
|
||||
def get_global_property(self, global_name: str, property_name: str) -> Any: ...
|
||||
|
||||
|
||||
class ComponentDefinition:
|
||||
|
@ -193,9 +202,14 @@ class ComponentDefinition:
|
|||
class CompilationResult:
|
||||
component_names: list[str]
|
||||
diagnostics: list[PyDiagnostic]
|
||||
named_exports: list[typing.Tuple[str, str]]
|
||||
structs_and_enums: typing.Dict[str, PyStruct]
|
||||
def component(self, name: str) -> ComponentDefinition: ...
|
||||
|
||||
class Compiler:
|
||||
include_paths: list[str]
|
||||
def build_from_path(self, path:str) -> CompilationResult: ...
|
||||
def build_from_source(self, source:str, path: str) -> CompilationResult: ...
|
||||
include_paths: list[str | os.PathLike[Any] | pathlib.Path]
|
||||
library_paths: list[str | os.PathLike[Any] | pathlib.Path]
|
||||
translation_domain: str
|
||||
style: str
|
||||
def build_from_path(self, path:str | os.PathLike[Any] | pathlib.Path) -> CompilationResult: ...
|
||||
def build_from_source(self, source:str, path: str | os.PathLike[Any] | pathlib.Path) -> CompilationResult: ...
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue