diff --git a/jsonpath/pointer.py b/jsonpath/pointer.py index 261d613..e6ec9a0 100644 --- a/jsonpath/pointer.py +++ b/jsonpath/pointer.py @@ -166,6 +166,20 @@ def _handle_key_error(self, obj: Any, key: str, err: Exception) -> object: ): return key[1:] + # Handle dictionaries with integer or float keys. Note that JSON objects must + # have string keys. We are supporting this for historical reasons. + if isinstance(obj, Mapping): + try: + _key: Union[int, float] = int(key) + except ValueError: + try: + _key = float(key) + except ValueError: + raise JSONPointerKeyError(key) from err + + if _key in obj: + return obj[_key] + raise JSONPointerKeyError(key) from err def _handle_type_error(self, obj: Any, key: str, err: Exception) -> object: diff --git a/tests/test_json_pointer.py b/tests/test_json_pointer.py index 6c666ff..d9b31f2 100644 --- a/tests/test_json_pointer.py +++ b/tests/test_json_pointer.py @@ -329,3 +329,17 @@ def test_index_like_token_on_object_value() -> None: data = {"foo": {"-1": "bar"}} pointer = JSONPointer("/foo/-1") assert pointer.resolve(data) == "bar" + + +def test_dictionary_with_int_key() -> None: + # JSON object keys must be strings, but Python dicts can have integer keys. + data = {"foo": {1: "bar"}} + pointer = JSONPointer("/foo/1") + assert pointer.resolve(data) == "bar" + + +def test_dictionary_with_float_key() -> None: + # JSON object keys must be strings, but Python dicts can have float keys. + data = {"foo": {1.1: "bar"}} + pointer = JSONPointer("/foo/1.1") + assert pointer.resolve(data) == "bar"