@@ -57,53 +57,60 @@ def literal_eval(node_or_string):
57
57
Caution: A complex expression can overflow the C stack and cause a crash.
58
58
"""
59
59
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 ):
62
62
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 ):
71
71
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} ' )
107
114
108
115
109
116
def dump (
0 commit comments