Skip to content

Commit f23b196

Browse files
committed
Fix invalid-type error messages
Was always saying that the actual type was a string, which is wrong.
1 parent 5726355 commit f23b196

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

jmespath/functions.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ def _func_sort_by(self, array, expref):
317317
# that validates that type, which requires that remaining array
318318
# elements resolve to the same type as the first element.
319319
required_type = self._convert_to_jmespath_type(
320-
self.interpreter.visit(expref.expression, array[0]))
320+
type(self.interpreter.visit(expref.expression, array[0])).__name__)
321321
if required_type not in ['number', 'string']:
322322
raise exceptions.JMESPathTypeError(
323323
'sort_by', array[0], required_type, ['string', 'number'])
@@ -345,12 +345,14 @@ def _create_key_func(self, expr_node, allowed_types, function_name):
345345

346346
def keyfunc(x):
347347
result = interpreter.visit(expr_node, x)
348-
jmespath_type = self._convert_to_jmespath_type(result)
348+
actual_typename = type(result).__name__
349+
jmespath_type = self._convert_to_jmespath_type(actual_typename)
350+
# allowed_types is in term of jmespath types, not python types.
349351
if jmespath_type not in allowed_types:
350352
raise exceptions.JMESPathTypeError(
351353
function_name, result, jmespath_type, allowed_types)
352354
return result
353355
return keyfunc
354356

355357
def _convert_to_jmespath_type(self, pyobject):
356-
return TYPES_MAP.get(type(pyobject).__name__, 'unknown')
358+
return TYPES_MAP.get(pyobject, 'unknown')

tests/test_functions.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import json
55

66
import jmespath
7+
from jmespath.exceptions import JMESPathTypeError
78

89

910
class TestFunctions(unittest.TestCase):
@@ -16,3 +17,17 @@ def test_can_max_datetimes(self):
1617
data = [datetime.now(), datetime.now() + timedelta(seconds=1)]
1718
result = jmespath.search('max([*].to_string(@))', data)
1819
self.assertEqual(json.loads(result), str(data[-1]))
20+
21+
def test_type_error_messages(self):
22+
with self.assertRaises(JMESPathTypeError) as e:
23+
jmespath.search('length(@)', 2)
24+
exception = e.exception
25+
# 1. Function name should be in error message
26+
self.assertIn('length()', str(exception))
27+
# 2. Mention it's an invalid type
28+
self.assertIn('invalid type for value: 2', str(exception))
29+
# 3. Mention the valid types:
30+
self.assertIn("expected one of: ['string', 'array', 'object']",
31+
str(exception))
32+
# 4. Mention the actual type.
33+
self.assertIn('received: "number"', str(exception))

0 commit comments

Comments
 (0)