Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why would `eval('dict('+s+')')` work but not `literal_eval('dict('+s+')')`?

I could do this with eval():

>>> s = 'hello=True,world="foobar"'
>>> eval('dict('+s+')')
{'hello': True, 'world': 'foobar'}

but with literal_eval():

>>> from ast import literal_eval
>>> literal_eval('dict('+s+')')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/ast.py", line 110, in literal_eval
    return _convert(node_or_string)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/ast.py", line 109, in _convert
    return _convert_signed_num(node)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/ast.py", line 83, in _convert_signed_num
    return _convert_num(node)
           ^^^^^^^^^^^^^^^^^^
  File "/usr/local/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/ast.py", line 74, in _convert_num
    _raise_malformed_node(node)
  File "/usr/local/Cellar/python@3.11/3.11.3/Frameworks/Python.framework/Versions/3.11/lib/python3.11/ast.py", line 71, in _raise_malformed_node
    raise ValueError(msg + f': {node!r}')
ValueError: malformed node or string on line 1: <ast.Call object at 0x1014cb940>

Q (part 1): Why would eval() work but not literal_eval()?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Q (part 2): Is there a name for the '+s+' style/format?

Q (part 3): Is it possible to use something like the +s+ with literal_eval()?

>Solution :

This isn’t special syntax: +s+ doesn’t have any atypical meaning. You’re just concatenating strings together, the same way 'abc' + 'def' evaluates to 'abcdef'.

In this case, when you concatenate the string 'dict(', the string 'hello=True,world="foobar"', and the string ')' together, you get 'dict(hello=True,world="foobar")'.

dict(hello=True,world="foobar") is valid Python code (so eval can run it), but it’s not a valid literal definition (because dict is a function call, not literal syntax), so ast.literal_eval() correctly refuses it.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading