From: Christian Heller Date: Thu, 14 Aug 2025 14:53:56 +0000 (+0200) Subject: Refactor ClientDb type safety, disallow direct attribut setting. X-Git-Url: https://plomlompom.com/repos/booking/templates?a=commitdiff_plain;h=64481add71acd115612b31d87d6f0ea11d51d059;p=ircplom Refactor ClientDb type safety, disallow direct attribut setting. --- diff --git a/ircplom/client.py b/ircplom/client.py index 563c69e..1cd66ac 100644 --- a/ircplom/client.py +++ b/ircplom/client.py @@ -192,13 +192,20 @@ class ClientDbBase: return value return None + def __setattr__(self, key: str, value) -> None: + raise CrashingException('no direct attribute setting, use .set() etc.') + @classmethod - def _typecheck(cls, key: str, value: ClientDbType) -> None: + def _type_for(cls, key): candidates = [c.__annotations__[key] for c in cls.__mro__ if c is not object and key in c.__annotations__] if not candidates: raise CrashingException(f'{cls} lacks annotation for {key}') - type_ = candidates[0] + return candidates[0] + + @classmethod + def _typecheck(cls, key: str, value: ClientDbType) -> None: + type_ = cls._type_for(key) fail = True type_found = str(type(value)) if not isinstance(type_, type): # gotta be GenericAlias, … @@ -275,14 +282,13 @@ class _ClientDb(ClientDbBase): def conn_setup(self) -> IrcConnSetup: 'Constructed out of stored entries *including* unconfirmed ones.' kwargs: dict[str, ClientDbType] = {} - for field_name in IrcConnSetup._fields: - val = self._dict.get(field_name, None) + for name in IrcConnSetup._fields: + val = self._dict.get(name, None) if val is None: - raise CrashingException(f'field not set: {field_name}') - if not isinstance(val, IrcConnSetup.__annotations__[field_name]): - raise CrashingException( - f'wrong type for {field_name}: {type(val)} (value: {val})') - kwargs[field_name] = val + raise CrashingException(f'field not set: {name}') + assert self._type_for(name) == IrcConnSetup.__annotations__[name] + self._typecheck(name, val) + kwargs[name] = val return IrcConnSetup(**kwargs) # type: ignore # enough tests above @property diff --git a/ircplom/client_tui.py b/ircplom/client_tui.py index 0a639cd..b7541fe 100644 --- a/ircplom/client_tui.py +++ b/ircplom/client_tui.py @@ -105,7 +105,6 @@ class _ChatWindow(_ClientWindow): def set_prompt_prefix(self) -> None: 'Look up relevant DB data to update prompt prefix.' retrieval = self._get_nick_data() - assert isinstance(retrieval[0], str) self.prompt.set_prefix_data(*retrieval) def cmd__chat(self, msg: str) -> None: