@@ -33,6 +33,19 @@ def _is_special_integer_case(x, y):
33
33
return x is True or x is False
34
34
35
35
36
+ def _is_actual_number (x ):
37
+ # We need to handle python's quirkiness with booleans,
38
+ # specifically:
39
+ #
40
+ # >>> isinstance(False, int)
41
+ # True
42
+ # >>> isinstance(True, int)
43
+ # True
44
+ if x is True or x is False :
45
+ return False
46
+ return isinstance (x , (float , int ))
47
+
48
+
36
49
class Options (object ):
37
50
"""Options to control how a JMESPath function is evaluated."""
38
51
def __init__ (self , dict_cls = None , custom_functions = None ):
@@ -76,14 +89,14 @@ def default_visit(self, node, *args, **kwargs):
76
89
77
90
class TreeInterpreter (Visitor ):
78
91
COMPARATOR_FUNC = {
79
- 'le ' : operator . le ,
92
+ 'eq ' : _equals ,
80
93
'ne' : lambda x , y : not _equals (x , y ),
81
94
'lt' : operator .lt ,
82
- 'lte' : operator .le ,
83
- 'eq' : _equals ,
84
95
'gt' : operator .gt ,
96
+ 'lte' : operator .le ,
85
97
'gte' : operator .ge
86
98
}
99
+ _EQUALITY_OPS = ['eq' , 'ne' ]
87
100
MAP_TYPE = dict
88
101
89
102
def __init__ (self , options = None ):
@@ -115,11 +128,24 @@ def visit_field(self, node, value):
115
128
return None
116
129
117
130
def visit_comparator (self , node , value ):
131
+ # Common case: comparator is == or !=
118
132
comparator_func = self .COMPARATOR_FUNC [node ['value' ]]
119
- return comparator_func (
120
- self .visit (node ['children' ][0 ], value ),
121
- self .visit (node ['children' ][1 ], value )
122
- )
133
+ if node ['value' ] in self ._EQUALITY_OPS :
134
+ return comparator_func (
135
+ self .visit (node ['children' ][0 ], value ),
136
+ self .visit (node ['children' ][1 ], value )
137
+ )
138
+ else :
139
+ # Ordering operators are only valid for numbers.
140
+ # Evaluating any other type with a comparison operator
141
+ # will yield a None value.
142
+ left = self .visit (node ['children' ][0 ], value )
143
+ right = self .visit (node ['children' ][1 ], value )
144
+ num_types = (int , float )
145
+ if not (_is_actual_number (left ) and
146
+ _is_actual_number (right )):
147
+ return None
148
+ return comparator_func (left , right )
123
149
124
150
def visit_current (self , node , value ):
125
151
return value
0 commit comments