44from ..helpers import raise_ , re_finditer
55from . import Resolver , ValueNotFound , ValueResolutionPostponed
66
7- REGEX = r"%(static|env|var)\((str:| int:| float:| bool:)? ([\w]+)(,\s{1}'.*?')?\)%"
7+ REGEX = r"%(static|env|var)\(([ str:int:float:bool:]*?) ([\w]+)(,\s{1}'.*?')?\)%"
88STATIC_TEMPLATE : str = "%static({0}:{1}, '{2}')%"
9+ _VAR_DEFAULTS = ...
910
1011
1112class VariableMetadata (NamedTuple ):
@@ -15,18 +16,24 @@ class VariableMetadata(NamedTuple):
1516
1617 class MatchMetadata (NamedTuple ): # type: ignore
1718 source_kind : str
18- type : Type [Any ]
19+ types : List [ Type [Any ] ]
1920 source_name : str
2021 default : Any
2122 match : Match
2223
2324 @classmethod
2425 def from_match (cls , match : Match ) -> 'VariableMetadata.MatchMetadata' :
26+ raw_types = (
27+ ['str' ]
28+ if match .groups ()[1 ] is None or len (str (match .groups ()[1 ])) == 0
29+ else [s for s in str (match .groups ()[1 ]).split (':' ) if s .strip () != '' ]
30+ )
31+ raw_default = _VAR_DEFAULTS if match .groups ()[3 ] is None else str (match .groups ()[3 ])[3 :- 1 ]
2532 return cls (
2633 source_kind = str (match .groups ()[0 ]),
27- type = str if match . groups ()[ 1 ] is None else globals ()['__builtins__' ][str ( match . groups ()[ 1 ])[: - 1 ] ],
34+ types = [ globals ()['__builtins__' ][raw_type ] for raw_type in raw_types ],
2835 source_name = str (match .groups ()[2 ]),
29- default = None if match . groups ()[ 3 ] is None else str ( match . groups ()[ 3 ])[ 3 : - 1 ] ,
36+ default = None if isinstance ( raw_default , str ) and raw_default == ' None' else raw_default ,
3037 match = match ,
3138 )
3239
@@ -36,6 +43,11 @@ def __init__(self, name: str) -> None:
3643 super ().__init__ (kind = 'Variable' , name = name )
3744
3845
46+ class EnvironmentVariableNotFound (ValueNotFound ):
47+ def __init__ (self , name : str ) -> None :
48+ super ().__init__ (kind = 'EnvironmentVariable' , name = name )
49+
50+
3951class VariableResolutionPostponed (ValueResolutionPostponed [VariableMetadata ]):
4052 pass
4153
@@ -77,7 +89,12 @@ def parse_value(
7789 if metadata_ .source_kind == 'static' :
7890 typ_val = metadata_ .default
7991 elif metadata_ .source_kind == 'env' :
80- typ_val = getenv (key = metadata_ .source_name , default = metadata_ .default or '' )
92+ typ_val = getenv (key = metadata_ .source_name , default = metadata_ .default )
93+ if typ_val is None :
94+ # can only concatenate str to str
95+ return typ_val
96+ if metadata_ .default is _VAR_DEFAULTS and typ_val == metadata_ .default :
97+ raise EnvironmentVariableNotFound (name = metadata_ .source_name )
8198 elif metadata_ .source_kind == 'var' :
8299 if metadata_ .source_name not in _variables :
83100 if retries != - 1 :
@@ -94,7 +111,9 @@ def parse_value(
94111 values += metadata .value [metadata_ .match .end () :]
95112 value : Any = '' .join (values )
96113 if len (metadata .matches ) == 1 :
97- value = metadata .matches [0 ].type (value )
114+ # multiple casting
115+ for type_ in reversed (metadata .matches [0 ].types ):
116+ value = type_ (value )
98117 return value
99118
100119
0 commit comments