import ast import re import pyparsing # TODO: There is a lot of work to be done here. # The current implementation is written in a way that _any_ input is valid, # which does not make sense once things get more complex. PartialQuotedString = pyparsing.Regex( re.compile( r''' (["']) # start quote (?: (?:\\.) # escape sequence | (?!\1). # unescaped character that is not our quote nor the begin of an escape sequence. We can't use \1 in [] )* (?:\1|$) # end quote ''', re.VERBOSE ) ) expr = pyparsing.ZeroOrMore( PartialQuotedString | pyparsing.Word(" \r\n\t") | pyparsing.CharsNotIn("""'" \r\n\t""") ).leaveWhitespace() def quote(val: str) -> str: if val and all(char not in val for char in "'\" \r\n\t"): return val return repr(val) # TODO: More of a hack. def unquote(x: str) -> str: quoted = ( (x.startswith('"') and x.endswith('"')) or (x.startswith("'") and x.endswith("'")) ) if quoted: try: x = ast.literal_eval(x) except Exception: x = x[1:-1] return x