@@ -763,13 +763,19 @@ def _check_style_compatibility(self, ctx: Context, style: str, value: t.Any) ->
763
763
def convert (self , ctx : Context ) -> t .Any :
764
764
datatype = ctx .datatype
765
765
union : t .Optional [Union ]
766
+ literal_types : list [TypeHint ] = []
767
+
766
768
if isinstance (datatype , UnionTypeHint ):
767
769
if datatype .has_none_type ():
768
770
raise NotImplementedError ("unable to handle Union type with None in it" )
769
- if not all (isinstance (a , ClassTypeHint ) for a in datatype ):
770
- raise NotImplementedError (f"members of plain Union must be concrete types: { datatype } " )
771
- members = {t .cast (ClassTypeHint , a ).type .__name__ : a for a in datatype }
772
- if len (members ) != len (datatype ):
771
+
772
+ literal_types = [a for a in datatype if isinstance (a , LiteralTypeHint )]
773
+ non_literal_types = [a for a in datatype if not isinstance (a , LiteralTypeHint )]
774
+ if not all (isinstance (a , ClassTypeHint ) for a in non_literal_types ):
775
+ raise NotImplementedError (f"members of plain Union must be concrete or Literal types: { datatype } " )
776
+
777
+ members = {t .cast (ClassTypeHint , a ).type .__name__ : a for a in non_literal_types }
778
+ if len (members ) != len (non_literal_types ):
773
779
raise NotImplementedError (f"members of plain Union cannot have overlapping type names: { datatype } " )
774
780
union = Union (members , Union .BEST_MATCH )
775
781
elif isinstance (datatype , (AnnotatedTypeHint , ClassTypeHint )):
@@ -788,6 +794,11 @@ def convert(self, ctx: Context) -> t.Any:
788
794
return ctx .spawn (ctx .value , member_type , None ).convert ()
789
795
except ConversionError as exc :
790
796
errors .append ((exc .origin , exc ))
797
+ for literal_type in literal_types :
798
+ try :
799
+ return ctx .spawn (ctx .value , literal_type , None ).convert ()
800
+ except ConversionError as exc :
801
+ errors .append ((exc .origin , exc ))
791
802
raise ConversionError (
792
803
self ,
793
804
ctx ,
0 commit comments