-
Notifications
You must be signed in to change notification settings - Fork 17
Open
Labels
featureNew functionality added to the project.New functionality added to the project.
Description
🤔 Problem Description
After merging PR #143, we will have Beartype on every method, but nothing automatically verifies that each concrete class still honors the abstract class’s type hints.
A small drift—e.g. changing an add(...) signature—can silently break downstream code or introduce subtle variance bugs that only fail at runtime.
💡 Proposed Solution
- Add a new metaclass (e.g.
InterfaceMeta) in a util module (saymesa_frames.utils.interface_meta) that, in its__init__, walks everyABCbase and uses Beartype’sis_subhintto compare each abstract method’s type hints against the override in the subclass—raising aTypeErrorat class‐definition time on mismatch. - Switch our ABCs (like
AgentContainer) to usemetaclass=InterfaceMetainstead of plainABCMeta. Any drop-in mismatch inAgentSetPolars(or any other subclass) will now fail immediately when Python imports the module, giving a clear error message.
Example in mesa-frames
# mesa_frames/abstract/agents.py
from abc import abstractmethod
from typing import get_type_hints
from typing_extensions import Self
from mesa_frames.types_ import DataFrameInput
from collections.abc import Collection
…
class AgentSetDF(AgentContainer, DataFrameMixin):
@abstractmethod
def add(
self,
agents: DataFrameInput,
inplace: bool = True,
) -> Self:
"""Add agents to the container."""
…# mesa_frames/concrete/agentset.py
import polars as pl
from typing import Sequence, Any
from mesa_frames.abstract.agents import AgentSetDF
from mesa_frames.utils.interface_meta import InterfaceMeta
class AgentSetPolars(AgentSetDF, PolarsMixin, metaclass=InterfaceMeta):
def add(
self,
agents: pl.DataFrame | Sequence[Any] | dict[str, Any],
inplace: bool = True,
) -> Self:
"""Polars-backed add implementation."""
…Here, the metaclass check would ensure that the concrete add’s agents: hint (pl.DataFrame | Sequence[Any] | dict[str,Any]) is a valid superhint of the abstract DataFrameInput alias (dict[str, Any] | Sequence[Sequence] | pl.DataFrame), and would error out at class‐definition time if someone ever drifted one side out of alignment.
🔄 Alternatives Considered
- Decorator (opt-in per class), but easy to forget.
- CI test to compare signatures, but that only catches errors later in testing.
➕ Additional Context
- Abstract:
mesa_frames/abstract/agents.py - Concrete:
mesa_frames/concrete/agentset.py
Metadata
Metadata
Assignees
Labels
featureNew functionality added to the project.New functionality added to the project.