@@ -57,53 +57,60 @@ def literal_eval(node_or_string):
5757 Caution: A complex expression can overflow the C stack and cause a crash.
5858 """
5959 if isinstance (node_or_string , str ):
60- node_or_string = parse (node_or_string .lstrip (" \t " ), mode = 'eval' )
61- if isinstance (node_or_string , Expression ):
60+ node_or_string = parse (node_or_string .lstrip (" \t " ), mode = 'eval' ). body
61+ elif isinstance (node_or_string , Expression ):
6262 node_or_string = node_or_string .body
63- def _raise_malformed_node ( node ):
64- msg = "malformed node or string"
65- if lno := getattr ( node , 'lineno' , None ):
66- msg += f' on line { lno } '
67- raise ValueError ( msg + f': { node !r } ' )
68- def _convert_num ( node ):
69- if not isinstance ( node , Constant ) or type ( node . value ) not in ( int , float , complex ):
70- _raise_malformed_node (node )
63+ return _convert_literal ( node_or_string )
64+
65+
66+ def _convert_literal ( node ):
67+ """
68+ Used by `literal_eval` to convert an AST node into a value.
69+ """
70+ if isinstance (node , Constant ):
7171 return node .value
72- def _convert_signed_num (node ):
73- if isinstance (node , UnaryOp ) and isinstance (node .op , (UAdd , USub )):
74- operand = _convert_num (node .operand )
75- if isinstance (node .op , UAdd ):
76- return + operand
77- else :
78- return - operand
79- return _convert_num (node )
80- def _convert (node ):
81- if isinstance (node , Constant ):
82- return node .value
83- elif isinstance (node , Tuple ):
84- return tuple (map (_convert , node .elts ))
85- elif isinstance (node , List ):
86- return list (map (_convert , node .elts ))
87- elif isinstance (node , Set ):
88- return set (map (_convert , node .elts ))
89- elif (isinstance (node , Call ) and isinstance (node .func , Name ) and
90- node .func .id == 'set' and node .args == node .keywords == []):
91- return set ()
92- elif isinstance (node , Dict ):
93- if len (node .keys ) != len (node .values ):
94- _raise_malformed_node (node )
95- return dict (zip (map (_convert , node .keys ),
96- map (_convert , node .values )))
97- elif isinstance (node , BinOp ) and isinstance (node .op , (Add , Sub )):
98- left = _convert_signed_num (node .left )
99- right = _convert_num (node .right )
100- if isinstance (left , (int , float )) and isinstance (right , complex ):
101- if isinstance (node .op , Add ):
102- return left + right
103- else :
104- return left - right
105- return _convert_signed_num (node )
106- return _convert (node_or_string )
72+ if isinstance (node , Dict ) and len (node .keys ) == len (node .values ):
73+ return dict (zip (
74+ map (_convert_literal , node .keys ),
75+ map (_convert_literal , node .values ),
76+ ))
77+ if isinstance (node , Tuple ):
78+ return tuple (map (_convert_literal , node .elts ))
79+ if isinstance (node , List ):
80+ return list (map (_convert_literal , node .elts ))
81+ if isinstance (node , Set ):
82+ return set (map (_convert_literal , node .elts ))
83+ if (
84+ isinstance (node , Call ) and isinstance (node .func , Name )
85+ and node .func .id == 'set' and node .args == node .keywords == []
86+ ):
87+ return set ()
88+ if (
89+ isinstance (node , UnaryOp )
90+ and isinstance (node .op , (UAdd , USub ))
91+ and isinstance (node .operand , Constant )
92+ and type (operand := node .operand .value ) in (int , float , complex )
93+ ):
94+ if isinstance (node .op , UAdd ):
95+ return + operand
96+ else :
97+ return - operand
98+ if (
99+ isinstance (node , BinOp )
100+ and isinstance (node .op , (Add , Sub ))
101+ and isinstance (node .left , (Constant , UnaryOp ))
102+ and isinstance (node .right , Constant )
103+ and type (left := _convert_literal (node .left )) in (int , float )
104+ and type (right := _convert_literal (node .right )) is complex
105+ ):
106+ if isinstance (node .op , Add ):
107+ return left + right
108+ else :
109+ return left - right
110+ msg = "malformed node or string"
111+ if lno := getattr (node , 'lineno' , None ):
112+ msg += f' on line { lno } '
113+ raise ValueError (msg + f': { node !r} ' )
107114
108115
109116def dump (
0 commit comments