Repository navigation
Conversation
`sort_by` validates the type of the sort key, but when the key resolves to
something other than a number or a string it raised JMESPathTypeError with
the *array element* as the offending value:
>>> jmespath.search('sort_by(@, &k)', [{'k': [1, 2]}])
JMESPathTypeError: In function sort_by(), invalid type for value:
{'k': [1, 2]}, expected one of: ['string', 'number'], received: "array"
The signature in the specification is
sort_by(array elements, expression->number|expression->string expr)
so the value the constraint applies to is the value `expr` resolved to,
not the element it was resolved against. The reported value was also
inconsistent with the reported type: the message claimed to have received
an "array" while showing an object. `min_by` and `max_by`, which share the
same signature, already report the resolved key; this makes `sort_by`
consistent with them:
>>> jmespath.search('sort_by(@, &k)', [{'k': [1, 2]}])
JMESPathTypeError: In function sort_by(), invalid type for value: [1, 2],
expected one of: ['string', 'number'], received: "array"
The type check now goes through the same key function that performs the
sort, so the key is resolved exactly once for the type check and once per
sort comparison, as before. Error types, error values for keys that are
already valid, and all successful results are unchanged.
Signed-off-by: simpleqt <2015900818@qq.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the value reported by
JMESPathTypeErrorwhensort_byrejects the type of a sort key.Root cause
jmespath/functions.py,_func_sort_by(jmespath/functions.py:319-323ondevelop):The type is computed from the resolved key, but the error is constructed with
array[0], the array element the key was resolved against._func_min_byand_func_max_by, which take the identicalexpression->number|expression->stringargument, construct the error with the key (jmespath/functions.py:331-347+_create_key_func), so the three functions disagree.Reproduction
Before (on
develop, 2812594):The message is self-contradictory: it claims to have received an
"array"while printing an object. Note also that the element is not what the constraint applies to — the specification's signature isso the constrained value is what
exprresolves to.min_by/max_byon the same input reportvalue: [1], i.e. the resolved key.After:
Fix
The type check now goes through the same key function that performs the sort, so the key is evaluated and converted exactly as
min_by/max_bydo it, and the reported value is the key. The key is resolved once for the type check and once per comparison during the sort, which is the same number of evaluations as before (the old code also evaluatedarray[0]twice for the first element).Tests
tests/test_functions.py::TestFunctions::test_sort_by_reports_the_resolved_key_in_type_errorsRED on
develop(2812594):GREEN with the fix:
The new test sits next to the existing
test_type_error_messages, which asserts the same message shape forlength().Impact
Callers that catch
JMESPathTypeErrorand surface its message (or use the message to tell their users which value was rejected) are told that an element of the input array has an invalid type, when in fact it is the key resolved from that element. The error type was already correct, and no successful result changes; a before/after sweep over empty arrays, single elements, ties, float keys, string keys, mixed number/string keys,sort_by(@, &a.b), andsort_by(x, &to_number(k))produced identical results and identical error types, differing only in the value printed for the first-element key error.