I’m trying to (slightly) improve a script that does a quick-and-hacky parse of some config files.
Upon recognising “an item” read from the file, I need to try to convert it into a simple python value. The value could be a number or a string.
To convert strings read from the file into Python numbers I can just use int or float and catch the ValueError if it wasn’t actually a number. Is there something similar for Python strings? i.e.
s1 = 'Goodbye World. :('
s2 = repr(s1)
s3 = ' "not a string literal" '
s4 = s3.strip()
v1 = parse_string_literal(s1) # throws ValueError
v2 = parse_string_literal(s2) # returns 'Goodby World. :('
v3 = parse_string_literal(s3) # throws ValueError
v4 = parse_string_literal(s4) # returns 'not a string literal'
In the file, string values are represented very similarly to Python string literals; they can be quoted with either ‘ or “, and could contain backslash escapes, etc. I could roll my own parser with regexes, but if there’s something already existing I’d rather not re-invent the wheel.
I could use eval of course, but that’s always somewhat dangerous.
… And sure enough, I just found the answer after I posted.
Even better than what I was looking for is
ast.literal_eval: ast — Abstract Syntax TreesIt can evaluate any Python expression consisting solely of literals, which makes it safe. It also means I can recognise items from the config file that are potentially numbers or strings without having attempt multiple conversions, falling back to the next conversion on a
ValueErrorexception. I don’t even have to figure out what type the item is.It’s even way more flexible than I need, which could be a problem if I cared about making sure the item was only a number or a string, but I don’t: