feat: more safety in BaseBindable, AsyncBindable, Bindable

This commit is contained in:
rus07tam 2025-11-23 10:47:37 +00:00
parent 7f83370873
commit c7cd08b7e0
3 changed files with 47 additions and 6 deletions

View file

@ -1,4 +1,12 @@
from typing import Any, Awaitable, Callable, Generic, Literal, TypeVar, overload
from typing import (
Any,
Awaitable,
Callable,
Generic,
Literal,
TypeVar,
overload,
)
from .base_bindable import BaseBindable, BindableSubscriber, ValueChanged
@ -23,6 +31,9 @@ class AsyncBindable(BaseBindable[T], Generic[T]):
async def set(self, value: T) -> None:
"""Set the value."""
if not (self.has_default_value or self.has_value):
self.set_silent(value)
return
e = ValueChanged(self.value, value)
self.set_silent(value)
for subscriber in self.__subscribers:
@ -55,19 +66,25 @@ class AsyncBindable(BaseBindable[T], Generic[T]):
if run_now:
async def _run() -> None:
await subscriber(ValueChanged(self.__default_value, self.value))
await subscriber(
ValueChanged(self.__default_value, self.value)
)
return _run()
return None
def unsubscribe(self, subscriber: BindableSubscriber[T, Awaitable[Any]]) -> None:
def unsubscribe(
self, subscriber: BindableSubscriber[T, Awaitable[Any]]
) -> None:
"""Unsubscribe from an value."""
self.__subscribers.remove(subscriber)
@overload
def on(
self, run_now: Literal[True]
) -> Callable[[BindableSubscriber[T, Awaitable[Any]]], Awaitable[None]]: ...
) -> Callable[
[BindableSubscriber[T, Awaitable[Any]]], Awaitable[None]
]: ...
@overload
def on(
@ -87,7 +104,9 @@ class AsyncBindable(BaseBindable[T], Generic[T]):
if run_now:
async def _run() -> None:
await subscriber(ValueChanged(self.__default_value, self.value))
await subscriber(
ValueChanged(self.__default_value, self.value)
)
return _run()
return None

View file

@ -27,7 +27,26 @@ class BaseBindable(Generic[T]):
@property
def value(self) -> T:
if self.has_value:
return self.__value
else:
return self.default_value
@property
def has_value(self) -> bool:
try:
_ = self.__value
return True
except AttributeError:
return False
@property
def has_default_value(self) -> bool:
try:
_ = self.__default_value
return True
except AttributeError:
return False
def set_silent(self, value: T) -> None:
self.__value = value

View file

@ -21,6 +21,9 @@ class Bindable(BaseBindable[T], Generic[T]):
def set(self, value: T) -> None:
"""Set the value."""
if not (self.has_default_value or self.has_value):
self.set_silent(value)
return
e = ValueChanged(self.value, value)
self.set_silent(value)
for subscriber in self.__subscribers: