On Sun, 3 Feb 2013 00:40:47 +1000
Nick Coghlan
On 3 Feb 2013 00:21, "Steven D'Aprano"
wrote: On 03/02/13 00:06, Stefan Behnel wrote:
Hua Lu, 02.02.2013 08:38:
> > import ast > ast.literal_eval("{ 'key': 'val' }")
{'key': 'val'}
> > ast.literal_eval("{ ('key',): 'val' }")
{('key',): 'val'}
> > ast.literal_eval("{ frozenset({'key'}): 'val' }")
Traceback (most recent call last): File "<stdin>", line 1, in<module> File "/usr/lib/python3.3/ast.py", line 86, in literal_eval return _convert(node_or_string) File "/usr/lib/python3.3/ast.py", line 63, in _convert in zip(node.keys, node.values)) File "/usr/lib/python3.3/ast.py", line 62, in<genexpr> return dict((_convert(k), _convert(v)) for k, v File "/usr/lib/python3.3/ast.py", line 85, in _convert raise ValueError('malformed node or string: ' + repr(node)) ValueError: malformed node or string:<_ast.Call object at
0x7f865a8c1450>
So, why exactly are you using ast.literal_eval() to evaluate a
non-literal
expression?
Stefan, you did ask Hua Lu to show an example of what isn't working. It's just a demonstration of what doesn't work -- you can't create a frozenset using ast.literal_eval.
I think Hua Lu's original post made it quite clear. He wishes there to be a frozenset literal, because currently there is no way to have ast.literal_eval evaluate something containing a frozenset. Because there is no frozenset literal.
I think Raymond Hettinger's proposal back in 2008:
http://mail.python.org/pipermail/python-3000/2008-January/011798.html
and the following thread is worth reading. Guido even pronounced his agreement:
http://mail.python.org/pipermail/python-3000/2008-January/011814.html
but then changed his mind (as did Raymond). So the status quo remains.
Unfortunately the proposal to use f{ ... } for frozen sets cannot work within the constraints of Python's lexer:
http://mail.python.org/pipermail/python-3000/2008-January/011838.html
To clarify Guido's comment in that post, I'm fairly sure it *can* be made to work, it just won' t be the same way that string prefixes work (because the contents of dict and set displays are not opaque to the compiler the way string contents are).
The hypothetical "What if we want to allow expr{} as a general construct?" objection needs to be balanced against the immediate value of a more expressive language subset for use in ast.literal_eval().
I've just tried: ast.literal_eval() works just fine on a normal set:
ast.literal_eval("{1,2,3}") {1, 2, 3}
So I'd like to know why people find it important to build a frozenset rather than a normal set. The situation of wanting to use sets as hash keys is very rare in my experience. Regards Antoine.