]> Untitled Git - axy/ft/pacman.git/commitdiff
Mypy and flake8 cleanup
authorAxy <gilliardmarthey.axel@gmail.com>
Sun, 27 Sep 2026 21:02:20 +0000 (23:02 +0200)
committerAxy <gilliardmarthey.axel@gmail.com>
Sun, 27 Sep 2026 21:02:20 +0000 (23:02 +0200)
.flake8
src/pacman/ecs/__init__.py
src/pacman/ecs/hierarchy.py
src/pacman/ecs/world.py

diff --git a/.flake8 b/.flake8
index 0081794b583f6491693da254f7b27276c8ccbf74..2029706c9217fb8af535fff09198b2115dccac54 100644 (file)
--- a/.flake8
+++ b/.flake8
@@ -1,2 +1,2 @@
 [flake8]
-ignore = E203,W503
+ignore = E203,W503,E704
index f614e2819e03fe4ac3b1f046a4ec1f0800c5d32e..df086dd608e36e88172a5f862c3d40cbfa2c1a77 100644 (file)
@@ -1,4 +1,3 @@
-from collections.abc import Callable
 from dataclasses import dataclass
 from pathlib import Path
 
@@ -17,13 +16,9 @@ from pacman.ecs.schedule import (
     UpdateSchedule,
 )
 from pacman.ecs.world import (
-    CommandQueue,
     Component,
-    Entity,
     Not,
     Query,
-    RawComponentArg,
-    RawComponentHook,
     Resource,
     Systems,
     World,
index c9d98ddc22caed953ebbb5bd8cd53e2c972529f9..f0698d26dc63dc0cc942eb156ef5dccac3c8e023 100644 (file)
@@ -1,5 +1,5 @@
 from collections.abc import Callable, Generator, Iterable
-from typing import get_args, override
+from typing import cast, get_args, override
 
 from pacman.ecs.world import (
     CommandQueue,
@@ -114,11 +114,20 @@ class Hierarchy[Items, Filters = tuple[()]](FromWorld):
         cls, ty: type, world: "World"
     ) -> Callable[[], "Hierarchy[Items, Filters]"]:
         items, filters = get_args(ty)
-        roots_ty: type[RootsQuery[Items, Filters]] = resolve_type_aliases(
-            RootsQuery[items, filters]
+        type _Items = items  # type: ignore [valid-type]
+        type _Filters = filters  # type: ignore [valid-type]
+        roots_ty = cast(
+            type[RootsQuery[Items, Filters]],
+            resolve_type_aliases(
+                RootsQuery[
+                    _Items,
+                    _Filters,
+                ]
+            ),
         )
-        nodes_ty: type[NodesQuery[Items, Filters]] = resolve_type_aliases(
-            NodesQuery[items, filters]
+        nodes_ty = cast(
+            type[NodesQuery[Items, Filters]],
+            resolve_type_aliases(NodesQuery[_Items, _Filters]),
         )
         roots = roots_ty.extract_from_world(roots_ty, world)
         nodes = nodes_ty.extract_from_world(nodes_ty, world)
index 044382133d66352c0f22de7d70eebc8b0ebd221c..b173484df4ee0b0b946eb8afbf7ce4695373c2ba 100644 (file)
@@ -5,6 +5,7 @@ from dataclasses import dataclass
 from typing import (
     Any,
     Literal,
+    Never,
     NewType,
     Self,
     Union,
@@ -33,7 +34,7 @@ class Bundle(ABC):
     def components_iter(self) -> Iterator["Component"]: ...
     @classmethod
     @abstractmethod
-    def components_type_iter(cls) -> Iterator[type["Component"]]: ...
+    def components_type_iter(cls, ty: type) -> Iterator[type["Component"]]: ...
 
 
 type Components = RecursiveTuple["Component | Bundle"]
@@ -60,7 +61,9 @@ def components_type_iter(
     elif issubclass(components, Component):
         yield components
     else:
-        yield from cast(type[Bundle], components).components_type_iter()
+        yield from cast(type[Bundle], components).components_type_iter(
+            components
+        )
 
 
 ComponentID = NewType("ComponentID", int)
@@ -85,8 +88,8 @@ class Archetype:
         self._world._archetypes.append(self)
         self._world._archetypes_lookup[self._types] = self
 
-    def _compute_add(
-        self, ty: type[Components]
+    def _compute_add[T: Components](
+        self, ty: type[T]
     ) -> tuple["Archetype", list[ComponentID]]:
         ptr = id(ty)
         if res := self._add_cache.get(ptr):
@@ -106,8 +109,8 @@ class Archetype:
         self._add_cache[ptr] = (ty, res_arch, comps)
         return (res_arch, comps)
 
-    def _compute_remove(
-        self, ty: type[Components]
+    def _compute_remove[T: Components](
+        self, ty: type[T]
     ) -> tuple["Archetype", list[ComponentID]]:
         ptr = id(ty)
         if res := self._remove_cache.get(ptr):
@@ -197,7 +200,7 @@ class Archetype:
         for ent in entities:
             del self._world._entities[ent]
         for hook, comp in comps:
-            hook._remove(zip(entities, comp))
+            hook._remove(zip(entities, comp, strict=True))
 
     def _extend(
         self,
@@ -235,14 +238,14 @@ class Archetype:
             remove_idx(comp)
 
 
-type RawSystem[T] = Callable[[], T]
+type RawSystem[T = Any] = Callable[[], T]
 
-type System[T] = Callable[..., T]
+type System[T = Any] = Callable[..., T]
 
 type Plugin = RecursiveTuple[Callable[["World"], None]]
 
 type RawComponentArg[T] = Iterable[tuple["Entity", T]]
-type RawComponentHook[T] = Callable[[RawComponentArg], None]
+type RawComponentHook[T] = Callable[[RawComponentArg[T]], None]
 type ComponentHook[T] = System[RawComponentHook[T]]
 
 
@@ -254,7 +257,7 @@ class FromWorld(ABC):
     ) -> Callable[[], Self | None]: ...
 
     def cleanup(self) -> None:
-        pass
+        return None
 
 
 class QueryFilter(ABC):
@@ -290,6 +293,7 @@ class QueryItem(QueryFilter):
 
     @classmethod
     def fetch_prio(cls, ty: type) -> int:
+        del ty
         return 0
 
     @classmethod
@@ -331,6 +335,7 @@ class Entity(QueryItem):
     @override
     @classmethod
     def filter(cls, ty: type) -> Callable[[Archetype], bool]:
+        del ty
         return lambda _: True
 
     @override
@@ -338,6 +343,7 @@ class Entity(QueryItem):
     def filter_fetch(
         cls, ty: type
     ) -> Callable[[Archetype], None | Callable[[int], "Entity"]]:
+        del ty
         return lambda archetype: lambda i: archetype._entities[i]
 
 
@@ -346,14 +352,14 @@ class Not[T: FromWorld | Any](FromWorld, QueryItem):
     @classmethod
     def filter_fetch(
         cls, ty: type
-    ) -> Callable[[Archetype], None | Callable[[int], Self | _NoFetchCls]]:
+    ) -> Callable[[Archetype], None | Callable[[int], "Not[T] | _NoFetchCls"]]:
         preprocessed = cls.filter(ty)
         return lambda archetype: (
             (lambda _: Not())
-            if (filt := preprocessed(archetype)) == False
+            if (filt := preprocessed(archetype)) is False
             else (
                 None
-                if filt == True
+                if filt is True
                 else (lambda i: _NoFetch if filt(i) else Not())
             )
         )
@@ -376,8 +382,8 @@ class Not[T: FromWorld | Any](FromWorld, QueryItem):
     def extract_from_world(
         cls, ty: type, world: "World"
     ) -> Callable[[], "Not[T] | None"]:
-        inner = cast(type[FromWorld], get_args(ty)[0])
-        extractor = inner.extract_from_world(inner, world)
+        inner_ty = cast(type[FromWorld], get_args(ty)[0])
+        extractor = inner_ty.extract_from_world(inner_ty, world)
 
         def inner() -> Not[T] | None:
             if (res := extractor()) is None:
@@ -397,8 +403,8 @@ class Maybe[T: FromWorld](FromWorld):
     def extract_from_world(
         cls, ty: type, world: "World"
     ) -> Callable[[], "Maybe[T]"]:
-        inner = cast(type[T], get_args(ty)[0])
-        extractor = inner.extract_from_world(inner, world)
+        inner_ty = cast(type[T], get_args(ty)[0])
+        extractor = inner_ty.extract_from_world(inner_ty, world)
 
         def inner() -> Maybe[T]:
             return Maybe(extractor())
@@ -539,14 +545,12 @@ class Query[Items, Filters = tuple[()]](
         return cast(QueryFilter, filter).filter(filter)
 
     def add_archetype(self, archetype: Archetype) -> None:
-        cond: Callable[[int], bool]
-        match self._filters_raw(archetype):
-            case True:
-                cond = lambda _: True
-            case False:
-                return
-            case e:
-                cond = e
+        filt = self._filters_raw(archetype)
+        if filt is False:
+            return
+        cond: Callable[[int], bool] = (
+            (lambda _: True) if filt is True else filt
+        )
 
         fetcher = self._fetchers_raw(archetype)
         if fetcher is None:
@@ -582,7 +586,9 @@ class Query[Items, Filters = tuple[()]](
         )
 
     @override
-    def __contains__(self, entity: Entity) -> bool:
+    def __contains__(self, entity: object) -> bool:
+        if not isinstance(entity, Entity):
+            return False
         arch: Archetype | None = self._world._entities.get(entity)
         if arch is None:
             return False
@@ -635,8 +641,8 @@ class Resource(FromWorld, Component):
     ) -> Callable[[], Self | None]:
         _query = Query[ty]  # type: ignore
         query: Callable[[], Query[Self]] = cast(
-            type[Query[Self]], _query
-        ).extract_from_world(_query, world)
+            Callable[[], Query[Self]], _query.extract_from_world(_query, world)
+        )
         return lambda: query().single()
 
 
@@ -650,6 +656,7 @@ class CommandQueue(FromWorld):
     def extract_from_world(
         cls, ty: type, world: "World"
     ) -> Callable[[], Self]:
+        del ty
         return lambda: cls(world)
 
     @override
@@ -661,11 +668,11 @@ class CommandQueue(FromWorld):
         self._queue.append(sys)
 
 
-def _system_failed_va[T, *P = *tuple[()]](*_: *P) -> T:
+def _system_failed_va[*P = *tuple[()]](*_: *P) -> Never:
     raise ValueError("Failed to fetch arguments for system")
 
 
-def _system_failed[T]() -> T:
+def _system_failed() -> Never:
     raise ValueError("Failed to fetch arguments for system")
 
 
@@ -690,7 +697,7 @@ class World(FromWorld):
             tuple[type, ComponentHooks[Component]]
         ] = []
         self._components_lookup: dict[type, ComponentID] = {}
-        self._schedules: dict[ScheduleLabel, Schedule[RawSystem]] = {}
+        self._schedules: dict[ScheduleLabel, Schedule[RawSystem[Any]]] = {}
         self._base_archetype: Archetype = Archetype(self, ())
 
     def component_id(self, comp: type) -> ComponentID:
@@ -805,7 +812,7 @@ class World(FromWorld):
             for extract in extractors:
                 curr = extract()
                 if curr is None:
-                    return default()
+                    return default(*cb_args)
                 args.append(curr)
             res = system(*args)(*cb_args)
             for arg in args:
@@ -840,6 +847,7 @@ class World(FromWorld):
     def extract_from_world(
         cls, ty: type, world: "World"
     ) -> Callable[[], "World"]:
+        del ty
         return lambda: world
 
     def tick(self, schedule: ScheduleLabel) -> None:
@@ -876,13 +884,13 @@ class World(FromWorld):
         hook: ComponentHook[T],
     ) -> "World":
         comp_id = self.component_id(resolve_type_aliases(ty))
-        hooks = self._components_cache[comp_id][1]
+        hooks = cast(ComponentHooks[T], self._components_cache[comp_id][1])
         sys = self.add_system(hook, default=lambda _: None)
         match cycle:
             case "insert":
-                hooks.add_insert(lambda e: sys(e))
+                hooks.add_insert(sys)
             case "remove":
-                hooks.add_remove(lambda e: sys(e))
+                hooks.add_remove(sys)
         return self
 
     def with_plugins(self, *plugins: Plugin) -> "World":