From 773b100e489140125068bfc26e3f7d521a73ad2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csaba=20Gy=C3=B6rgyi?= Date: Thu, 30 May 2024 19:18:34 +0200 Subject: [PATCH] Fix the type hints in base_store.py - Use the _Element class instead of the Element factory for typing. - Make BaseStore generic so that subclasses can have the precise return and parameter types instead of Any. - The stored objects are required to have certain fields. --- GTG/__init__.py | 2 +- GTG/core/base_store.py | 29 ++++++++++++++++++----------- GTG/core/tags.py | 2 +- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/GTG/__init__.py b/GTG/__init__.py index 44b2a5f76..96bbf690a 100644 --- a/GTG/__init__.py +++ b/GTG/__init__.py @@ -16,7 +16,7 @@ # this program. If not, see . # ----------------------------------------------------------------------------- -import gi +import gi # type: ignore[import-untyped] def gi_version_requires(): diff --git a/GTG/core/base_store.py b/GTG/core/base_store.py index faecc2898..fde2ef214 100644 --- a/GTG/core/base_store.py +++ b/GTG/core/base_store.py @@ -19,25 +19,32 @@ """Base for all store classes.""" -from gi.repository import GObject +from gi.repository import GObject # type: ignore[import-untyped] from uuid import UUID import logging -from lxml.etree import Element -from typing import Any, Dict, List, Optional +from lxml.etree import _Element +from typing import Any, Dict, List, Optional, TypeVar, Generic, Protocol, TypeAlias log = logging.getLogger(__name__) +S = TypeVar('S',bound='Storeable') -class BaseStore(GObject.Object): +class Storeable(Protocol[S]): + id: UUID + parent: Optional[S] + children: List[S] + + +class BaseStore(GObject.Object,Generic[S]): """Base class for data stores.""" def __init__(self) -> None: - self.lookup: Dict[UUID, Any] = {} - self.data: List[Any] = [] + self.lookup: Dict[UUID, S] = {} + self.data: List[S] = [] super().__init__() @@ -45,17 +52,17 @@ def __init__(self) -> None: # BASIC MANIPULATION # -------------------------------------------------------------------------- - def new(self) -> Any: + def new(self) -> S: raise NotImplementedError - def get(self, key: UUID) -> Any: + def get(self, key: UUID) -> S: """Get an item by id.""" return self.lookup[key] - def add(self, item: Any, parent_id: Optional[UUID] = None) -> None: + def add(self, item: S, parent_id: Optional[UUID] = None) -> None: """Add an existing item to the store.""" if item.id in self.lookup.keys(): @@ -169,11 +176,11 @@ def unparent(self, item_id: UUID, parent_id: UUID) -> None: # SERIALIZING # -------------------------------------------------------------------------- - def from_xml(self, xml: Element) -> Any: + def from_xml(self, xml: _Element) -> None: raise NotImplementedError - def to_xml(self) -> Element: + def to_xml(self) -> _Element: raise NotImplementedError diff --git a/GTG/core/tags.py b/GTG/core/tags.py index c4f9d82ac..b456fcc79 100644 --- a/GTG/core/tags.py +++ b/GTG/core/tags.py @@ -183,7 +183,7 @@ def __hash__(self): return id(self) -class TagStore(BaseStore): +class TagStore(BaseStore[Tag]): """A tree of tags.""" __gtype_name__ = 'gtg_TagStore'