23 if not (
is_string(string)
and '{' in string):
35 return match.is_variable()
50 def is_assign(string, identifiers='$@&', allow_assign_mark=False):
52 return match.is_assign(allow_assign_mark)
56 return is_assign(string,
'$', allow_assign_mark)
60 return is_assign(string,
'@', allow_assign_mark)
64 return is_assign(string,
'&', allow_assign_mark)
69 def __init__(self, string, identifier=None, base=None, items=(), start=-1, end=-1):
80 self.
basebase = variables.replace_string(
82 custom_unescaper=unescape_variable_syntax,
83 ignore_errors=ignore_errors,
90 return '%s{%s}' % (self.
identifieridentifier, self.
basebase)
if self
else None
113 and self.
startstart == 0
114 and self.
endend == len(self.
stringstring))
126 if allow_assign_mark
and self.
stringstring.endswith(
'='):
128 return match.is_assign()
131 and not self.
itemsitems
149 items =
''.join(
'[%s]' % i
for i
in self.
itemsitems)
if self.
itemsitems
else ''
150 return '%s{%s}%s' % (self.
identifieridentifier, self.
basebase, items)
158 match =
VariableMatch(string, identifier=string[start], start=start)
159 left_brace, right_brace =
'{',
'}'
163 indices_and_chars = enumerate(string[start+2:], start=start+2)
165 for index, char
in indices_and_chars:
166 if char == left_brace
and not escaped:
169 elif char == right_brace
and not escaped:
173 next_char = string[index+1]
if index+1 < len(string)
else None
175 if left_brace ==
'{':
176 match.base = string[start+2:index]
177 if match.identifier
not in '$@&' or next_char !=
'[':
178 match.end = index + 1
180 left_brace, right_brace =
'[',
']'
183 items.append(string[start+1:index])
185 match.end = index + 1
186 match.items = tuple(items)
189 next(indices_and_chars)
194 escaped =
False if char !=
'\\' else not escaped
199 incomplete = string[match.start:]
200 if left_brace ==
'{':
201 raise VariableError(f
"Variable '{incomplete}' was not closed properly.")
202 raise VariableError(f
"Variable item '{incomplete}' was not closed properly.")
210 index = string.find(
'{', index) - 1
213 if string[index]
in identifiers
and _not_escaped(string, index):
220 while index > 0
and string[index-1] ==
'\\':
222 escaped =
not escaped
228 def handle_escapes(match):
229 escapes, text = match.groups()
230 if len(escapes) % 2 == 1
and starts_with_variable_or_curly(text):
234 def starts_with_variable_or_curly(text):
238 return match
and match.start == 0
240 return re.sub(
r'(\\+)(?=(.+))', handle_escapes, item)
245 def __init__(self, string, identifiers='$@&%', ignore_errors=False):
251 remaining = self.
stringstring
256 remaining = match.after
257 yield match.before, match.match, remaining
260 return sum(1
for _
in self)
265 except StopIteration:
Used when variable does not exist.
def __init__(self, string, identifiers='$@&%', ignore_errors=False)
def is_assign(self, allow_assign_mark=False)
def resolve_base(self, variables, ignore_errors=False)
def is_list_assign(self, allow_assign_mark=False)
def __init__(self, string, identifier=None, base=None, items=(), start=-1, end=-1)
def is_scalar_variable(self)
def is_dict_variable(self)
def is_dict_assign(self, allow_assign_mark=False)
def is_list_variable(self)
def is_scalar_assign(self, allow_assign_mark=False)
def is_scalar_variable(string)
def is_list_variable(string)
def contains_variable(string, identifiers='$@&')
def _search_variable(string, identifiers, ignore_errors=False)
def unescape_variable_syntax(item)
def is_dict_assign(string, allow_assign_mark=False)
def _find_variable_start(string, identifiers)
def _not_escaped(string, index)
def search_variable(string, identifiers='$@&% *', ignore_errors=False)
def is_dict_variable(string)
def is_scalar_assign(string, allow_assign_mark=False)
def is_list_assign(string, allow_assign_mark=False)
def is_variable(string, identifiers='$@&')
def is_assign(string, identifiers='$@&', allow_assign_mark=False)