@@ -183,7 +183,7 @@ def __post_init__(self) -> None:
183183 _invalid ("Recode source and target names must be non-empty." )
184184 if self .op != "recode" :
185185 _invalid ("Recode operation discriminator is invalid." )
186- if self .target_mode not in {"create" , "replace" }:
186+ if not isinstance ( self . target_mode , str ) or self .target_mode not in {"create" , "replace" }:
187187 _invalid ("Recode target_mode must be create or replace." )
188188 if not isinstance (self .rules , tuple ) or not self .rules :
189189 _invalid ("Recode requires at least one non-ELSE rule." )
@@ -304,7 +304,7 @@ def __post_init__(self) -> None:
304304 _invalid ("Comparison expression discriminator is invalid." )
305305 if not isinstance (self .left , Operand ) or not isinstance (self .right , Operand ):
306306 _invalid ("A comparison requires two typed operands." )
307- if self .operator not in {"=" , "<" , "<=" , ">" , ">=" }:
307+ if not isinstance ( self . operator , str ) or self .operator not in {"=" , "<" , "<=" , ">" , ">=" }:
308308 _invalid ("Comparison operator is outside the bounded expression profile." )
309309
310310 def as_dict (self ) -> dict [str , Any ]:
@@ -323,7 +323,7 @@ class BooleanExpression:
323323 def __post_init__ (self ) -> None :
324324 if self .expression != "boolean" :
325325 _invalid ("Boolean expression discriminator is invalid." )
326- if self .operator not in {"and" , "or" }:
326+ if not isinstance ( self . operator , str ) or self .operator not in {"and" , "or" }:
327327 _invalid ("Boolean operator must be and or or." )
328328 if not isinstance (self .operands , tuple ) or len (self .operands ) < 2 :
329329 _invalid ("A boolean expression requires at least two operands." )
@@ -352,7 +352,7 @@ def __post_init__(self) -> None:
352352 _invalid ("Assign operation discriminator is invalid." )
353353 if not isinstance (self .target , str ) or not self .target :
354354 _invalid ("Assign target must be non-empty text." )
355- if self .target_mode not in {"create" , "replace" }:
355+ if not isinstance ( self . target_mode , str ) or self .target_mode not in {"create" , "replace" }:
356356 _invalid ("Assign target_mode must be create or replace." )
357357 if not isinstance (self .value , Operand ):
358358 _invalid ("Assign value must be a typed operand." )
@@ -435,7 +435,7 @@ def __post_init__(self) -> None:
435435 _invalid ("Measurement-level operation discriminator is invalid." )
436436 if not isinstance (self .variable , str ) or not self .variable :
437437 _invalid ("Measurement-level operation requires a variable." )
438- if self .level not in {"nominal" , "ordinal" , "scale" }:
438+ if not isinstance ( self . level , str ) or self .level not in {"nominal" , "ordinal" , "scale" }:
439439 _invalid ("Measurement level must be nominal, ordinal, or scale." )
440440
441441 def as_dict (self ) -> dict [str , Any ]:
@@ -470,7 +470,7 @@ class TransformationPlan:
470470 input_alias : str = "parent"
471471
472472 def __post_init__ (self ) -> None :
473- if self .contract not in _TRANSFORMATION_PLAN_CONTRACTS :
473+ if not isinstance ( self . contract , str ) or self .contract not in _TRANSFORMATION_PLAN_CONTRACTS :
474474 _invalid ("Plan contract is not a supported transformation-plan contract." )
475475 if self .contract == TRANSFORMATION_PLAN_V1_CONTRACT and any (
476476 isinstance (operation , (
0 commit comments