Deal with errors inside Computed

This commit is contained in:
Jan Hamal Dvořák 2025-03-11 16:28:18 +01:00
parent 5503e48db8
commit 33ca05a3cb

View file

@ -1,19 +1,23 @@
from __future__ import annotations
import sys
import traceback
from contextvars import ContextVar
from typing import Any, Callable, ClassVar, Generic, Self, TypeVar
from weakref import WeakSet
__all__ = ["Ref", "Computed", "update_all_computed"]
__all__ = ["Ref", "Computed", "Watcher", "update_all_computed"]
T = TypeVar("T")
class Ref(Generic[T]):
_error: Exception | None
_users: WeakSet[Computed[Any]]
_value: T
def __init__(self, initial: T):
self._error = None
self._value = initial
self._users = WeakSet()
@ -24,6 +28,9 @@ class Ref(Generic[T]):
if computed is not None:
self._users.add(computed)
if self._error is not None:
raise self._error
return self._value
@value.setter
@ -47,6 +54,7 @@ class Computed(Ref[T]):
_update: Callable[[], T]
def __init__(self, update: Callable[[], T]):
self._error = None
self._update = update
self._users = WeakSet()
self.update()
@ -56,6 +64,10 @@ class Computed(Ref[T]):
try:
self.value = self._update()
self._error = None
except Exception as err:
self._error = err
traceback.print_exception(err, file=sys.stderr)
finally:
self._stack.reset(token)