mirror of
https://github.com/tiqi-group/pydase.git
synced 2025-04-20 00:10:03 +02:00
adds warning message when super().__init__() is not called at the start of the constructor
This commit is contained in:
parent
e8a0a7c000
commit
a97a55712e
@ -22,10 +22,15 @@ class Observable(ObservableObject):
|
|||||||
self.__dict__[name] = self._initialise_new_objects(name, value)
|
self.__dict__[name] = self._initialise_new_objects(name, value)
|
||||||
|
|
||||||
def __setattr__(self, name: str, value: Any) -> None:
|
def __setattr__(self, name: str, value: Any) -> None:
|
||||||
if hasattr(self, "_observers"):
|
if not hasattr(self, "_observers") and name != "_observers":
|
||||||
self._remove_observer_if_observable(name)
|
logger.warning(
|
||||||
value = self._initialise_new_objects(name, value)
|
"Ensure that super().__init__() is called at the start of the '%s' "
|
||||||
self._notify_change_start(name)
|
"constructor! Failing to do so may lead to unexpected behavior.",
|
||||||
|
type(self).__name__,
|
||||||
|
)
|
||||||
|
self._observers = {}
|
||||||
|
|
||||||
|
value = self._handle_observable_setattr(name, value)
|
||||||
|
|
||||||
super().__setattr__(name, value)
|
super().__setattr__(name, value)
|
||||||
|
|
||||||
@ -42,6 +47,15 @@ class Observable(ObservableObject):
|
|||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
def _handle_observable_setattr(self, name: str, value: Any) -> Any:
|
||||||
|
if name == "_observers":
|
||||||
|
return value
|
||||||
|
|
||||||
|
self._remove_observer_if_observable(name)
|
||||||
|
value = self._initialise_new_objects(name, value)
|
||||||
|
self._notify_change_start(name)
|
||||||
|
return value
|
||||||
|
|
||||||
def _remove_observer_if_observable(self, name: str) -> None:
|
def _remove_observer_if_observable(self, name: str) -> None:
|
||||||
if not is_property_attribute(self, name):
|
if not is_property_attribute(self, name):
|
||||||
current_value = getattr(self, name, None)
|
current_value = getattr(self, name, None)
|
||||||
|
@ -13,7 +13,8 @@ class ObservableObject(ABC):
|
|||||||
_dict_mapping: ClassVar[dict[int, "_ObservableDict"]] = {}
|
_dict_mapping: ClassVar[dict[int, "_ObservableDict"]] = {}
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self._observers: dict[str, list["ObservableObject | Observer"]] = {}
|
if not hasattr(self, "_observers"):
|
||||||
|
self._observers: dict[str, list["ObservableObject | Observer"]] = {}
|
||||||
|
|
||||||
def add_observer(
|
def add_observer(
|
||||||
self, observer: "ObservableObject | Observer", attr_name: str = ""
|
self, observer: "ObservableObject | Observer", attr_name: str = ""
|
||||||
|
@ -13,6 +13,20 @@ class MyObserver(Observer):
|
|||||||
logger.info("'%s' changed to '%s'", full_access_path, value)
|
logger.info("'%s' changed to '%s'", full_access_path, value)
|
||||||
|
|
||||||
|
|
||||||
|
def test_constructor_error_message(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
|
class MyObservable(Observable):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self.attr = 1
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
MyObservable()
|
||||||
|
|
||||||
|
assert (
|
||||||
|
"Ensure that super().__init__() is called at the start of the 'MyObservable' "
|
||||||
|
"constructor! Failing to do so may lead to unexpected behavior." in caplog.text
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_simple_class_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
def test_simple_class_attribute(caplog: pytest.LogCaptureFixture) -> None:
|
||||||
class MyObservable(Observable):
|
class MyObservable(Observable):
|
||||||
int_attribute = 10
|
int_attribute = 10
|
||||||
|
Loading…
x
Reference in New Issue
Block a user