diff --git a/tierkreis/tierkreis/builder.py b/tierkreis/tierkreis/builder.py index 7d3c7398..d3a377f6 100644 --- a/tierkreis/tierkreis/builder.py +++ b/tierkreis/tierkreis/builder.py @@ -15,7 +15,7 @@ runtime_checkable, ) -from tierkreis.controller.data.core import EmptyModel +from tierkreis.controller.data.core import EmptyModel, RestrictedNamedTuple from tierkreis.controller.data.graph import GraphData, ValueRef, reindex_inputs from tierkreis.controller.data.models import ( TKR, @@ -441,7 +441,7 @@ def map( if not isclass(body.outputs_type) or not issubclass( body.outputs_type, - TNamedModel, + RestrictedNamedTuple, # Cannot check TNamedModel ): out = self._fold_list(out) diff --git a/tierkreis/tierkreis/controller/data/models.py b/tierkreis/tierkreis/controller/data/models.py index df117053..571c78e5 100644 --- a/tierkreis/tierkreis/controller/data/models.py +++ b/tierkreis/tierkreis/controller/data/models.py @@ -13,7 +13,6 @@ get_args, get_origin, overload, - runtime_checkable, ) from typing_extensions import TypeIs @@ -29,7 +28,7 @@ TKR_PORTMAPPING_FLAG = "__tkr_portmapping__" -@runtime_checkable +# @runtime_checkable # ALAN no, as we cannot distinguish between this and TNamedModel class PNamedModel(RestrictedNamedTuple[PType], Protocol): """A struct whose members are restricted to being PTypes. @@ -56,7 +55,7 @@ def value_ref(self) -> ValueRef: return (self.node_index, self.port_id) -@runtime_checkable +# @runtime_checkable # ALAN no, as we cannot distinguish between this and PNamedModel class TNamedModel(RestrictedNamedTuple[TKR[PType] | None], Protocol): """A struct whose members are restricted to being references to PTypes. @@ -93,7 +92,9 @@ def is_tnamedmodel(o) -> TypeIs[type[TNamedModel]]: # noqa: ANN001 inherited fr origin = get_origin(o) if origin is not None: return is_tnamedmodel(origin) - return isclass(o) and issubclass(o, TNamedModel) + # We cannot check whether fields are TNamedModel-compliant at runtime. + # So this overapproximates. + return isclass(o) and issubclass(o, RestrictedNamedTuple) def dict_from_pmodel(pmodel: PModel) -> dict[PortID, PType]: @@ -112,7 +113,8 @@ def annotations_from_pmodel(pmodel: type) -> dict[PortID, Any]: def dict_from_tmodel(tmodel: TModel) -> dict[PortID, ValueRef]: - if isinstance(tmodel, TNamedModel): + # We can't do the ideal: if isinstance(tmodel, TNamedModel): + if not isinstance(tmodel, TKR): return {k: (v.node_index, v.port_id) for k, v in tmodel._asdict().items() if v} return {"value": (tmodel.node_index, tmodel.port_id)} diff --git a/tierkreis/tierkreis/controller/data/types.py b/tierkreis/tierkreis/controller/data/types.py index 33ff544f..19563e61 100644 --- a/tierkreis/tierkreis/controller/data/types.py +++ b/tierkreis/tierkreis/controller/data/types.py @@ -111,7 +111,7 @@ def from_list(cls, arg: list, /) -> "Self": logger = logging.getLogger(__name__) -@runtime_checkable +# @runtime_checkable # ALAN no, as we cannot distinguish between this and TNamedModel class Struct(RestrictedNamedTuple[JsonType], Protocol): """Supertype for structs, which are named tuples with JSON-serialisable fields."""