1+ import enum
12from dataclasses import asdict
23from typing import Any
34
45from softioc import builder
56
67from fastcs .attributes import Attribute , AttrR , AttrRW , AttrW
7- from fastcs .datatypes import Bool , DataType , DType_T , Enum , Float , Int , String , Waveform
8+ from fastcs .datatypes import Bool , DType_T , Enum , Float , Int , String , Waveform
9+ from fastcs .datatypes .datatype import DataType
810from fastcs .exceptions import FastCSError
911
1012_MBB_FIELD_PREFIXES = (
3133MBB_MAX_CHOICES = len (_MBB_FIELD_PREFIXES )
3234
3335
34- EPICS_ALLOWED_DATATYPES = (Bool , DataType , Enum , Float , Int , String , Waveform )
36+ EPICS_ALLOWED_DATATYPES = (Bool , Enum , Float , Int , String , Waveform )
3537DEFAULT_STRING_WAVEFORM_LENGTH = 256
3638
3739DATATYPE_FIELD_TO_RECORD_FIELD = {
4446}
4547
4648
47- def record_metadata_from_attribute (
48- attribute : Attribute [DType_T ],
49- ) -> dict [str , Any ]:
49+ def record_metadata_from_attribute (attribute : Attribute [DType_T ]) -> dict [str , Any ]:
5050 """Converts attributes on the `Attribute` to the
5151 field name/value in the record metadata."""
5252 metadata : dict [str , Any ] = {"DESC" : attribute .description }
@@ -62,7 +62,7 @@ def record_metadata_from_attribute(
6262
6363
6464def record_metadata_from_datatype (
65- datatype : DataType [DType_T ], out_record : bool = False
65+ datatype : DataType [Any ], out_record : bool = False
6666) -> dict [str , str ]:
6767 """Converts attributes on the `DataType` to the
6868 field name/value in the record metadata."""
@@ -123,9 +123,14 @@ def cast_from_epics_type(datatype: DataType[DType_T], value: object) -> DType_T:
123123 raise ValueError (f"Invalid bool value from EPICS record { value } " )
124124 case Enum ():
125125 if len (datatype .members ) <= MBB_MAX_CHOICES :
126+ assert isinstance (value , int ), "Got non-integer value for Enum"
126127 return datatype .validate (datatype .members [value ])
127128 else : # enum backed by string record
128- return datatype .validate (datatype .enum_cls [value ])
129+ assert isinstance (value , str ), "Got non-string value for long Enum"
130+ # python typing can't narrow the nested generic enum_cls
131+ assert issubclass (datatype .enum_cls , enum .Enum ), "Invalid Enum.enum_cls"
132+ enum_member = datatype .enum_cls [value ]
133+ return datatype .validate (enum_member )
129134 case datatype if issubclass (type (datatype ), EPICS_ALLOWED_DATATYPES ):
130135 return datatype .validate (value ) # type: ignore
131136 case _:
0 commit comments