jmespath / jmespath.py

JMESPath is a query language for JSON.
http://jmespath.org
MIT License
2.19k stars 181 forks source link

Custom function handling NoneType/Null/none #172

Open spmp opened 6 years ago

spmp commented 6 years ago

I have a custom function to test array subsets, but sometimes the field does not exist in my JSON, in this case the input is none instead of ['some', 'array'] giving the error:

JMESPathTypeError: In function issubset(), invalid type for value: None, expected one of: ['array', 'null'], received: "null"

I tired adding null to the input types, but this didn't help:

class CustomFunctions(jmespath.functions.Functions):
    # Check if the list x is a subset of the list y
    @jmespath.functions.signature({'types': ['array', 'null']}, {'types': ['array', 'null']})
    def _func_issubset(self, x, y):
      if x is None or y is None:
        return False
      else:
        return set(x).issubset(y)

How can I handle this case please? Can I filter only if key exists?

pmeyerson commented 3 years ago

In case anyone else sees this, it seems to work for me.

Added the custom function to a class I already had with other custom functions.

opts=jmespath.Options(custom_functions=custom.CustomFunctions())

>>> jmespath.search('issubset(`[0,1]`, `[0,1,2]`)',{}, opts)
True

>>> jmespath.search('issubset(`[0,1]`,None)',{}, opts)
False

>>> data= [{"foo":"bar"}, {'1': [1,2], '0': [1]}]
>>> jmespath.search('[].issubset("0","1")', data, opts)
[False, True]

*** remove the "null" option from the signature decoration
opts=jmespath.Options(custom_functions=custom.CustomFunctions())
>>> jmespath.search('[].issubset("0","1")', data, opts)

Traceback (most recent call last):
jmespath.exceptions.JMESPathTypeError: In function issubset(), invalid type for value: None, expected one of: ['array'], received: "null"

If its still an issue could you post your full search call? I've had issues in the past where invalid type is returned when I had a syntax issue.

HTH