Closed thekafkaf closed 7 years ago
I am not sure if I understand your points correctly. Could you provide short code examples to reproduce the cases?
I'm sorry for my unclear report, here is an example:
In [1]: from jsonpointer import resolve_pointer
In [2]: d = {'a': {'b': 'c'}}
In [3]: resolve_pointer(d, '/a/b/d', None)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-5e4f54760a84> in <module>()
----> 1 resolve_pointer(d, '/a/b/d', None)
/home/kafkaf/dev/python-json-pointer/jsonpointer.pyc in resolve_pointer(doc, pointer, default)
104
105 pointer = JsonPointer(pointer)
--> 106 return pointer.resolve(doc, default)
107
108 def set_pointer(doc, pointer, value, inplace=True):
/home/kafkaf/dev/python-json-pointer/jsonpointer.pyc in resolve(self, doc, default)
161
162 try:
--> 163 doc = self.walk(doc, part)
164 except JsonPointerException:
165 if default is _nothing:
/home/kafkaf/dev/python-json-pointer/jsonpointer.pyc in walk(self, doc, part)
241 else:
242 # Object supports __getitem__, assume custom indexing
--> 243 return doc[part]
244
245 def contains(self, ptr):
TypeError: string indices must be integers, not unicode
The source of the error is clear, but I'll add an example for the second case, just in case:
In [16]: class Foo(MutableMapping):
def __init__(self, d):
self.d = d
def __getitem__(self, item):
return self.d[item]
def __len__(self):
return len(self.d)
def __iter__(self):
return iter(self.d)
def __delitem__(self, item):
del self.d[item]
def __setitem__(self, key, value):
self.d[key] = value
In [17]: f = Foo({'a': {'b': 'c'}})
In [19]: resolve_pointer(f, '/x/y', None)
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-19-a0b4cf24d5b0> in <module>()
----> 1 resolve_pointer(f, '/x/y', None)
/home/kafkaf/dev/python-json-pointer/jsonpointer.pyc in resolve_pointer(doc, pointer, default)
104
105 pointer = JsonPointer(pointer)
--> 106 return pointer.resolve(doc, default)
107
108 def set_pointer(doc, pointer, value, inplace=True):
/home/kafkaf/dev/python-json-pointer/jsonpointer.pyc in resolve(self, doc, default)
161
162 try:
--> 163 doc = self.walk(doc, part)
164 except JsonPointerException:
165 if default is _nothing:
/home/kafkaf/dev/python-json-pointer/jsonpointer.pyc in walk(self, doc, part)
241 else:
242 # Object supports __getitem__, assume custom indexing
--> 243 return doc[part]
244
245 def contains(self, ptr):
<ipython-input-16-180c99604678> in __getitem__(self, item)
3 self.d = d
4 def __getitem__(self, item):
----> 5 return self.d[item]
6 def __len__(self):
7 return len(self.d)
KeyError: u'x'
OK, now it's clear. I'd definitely consider both cases an error. It would be great if you could prepare pull requests for those.
I'm on it.
While reviewing open issues, I noticed that this is already fixed in the latest version.
>>> from jsonpointer import resolve_pointer
>>> from collections.abc import MutableMapping
>>>
>>> class Foo(MutableMapping):
... def __init__(self, d):
... self.d = d
... def __getitem__(self, item):
... return self.d[item]
... def __len__(self):
... return len(self.d)
... def __iter__(self):
... return iter(self.d)
... def __delitem__(self, item):
... del self.d[item]
... def __setitem__(self, key, value):
... self.d[key] = value
...
>>> f = Foo({'a': {'b': 'c'}})
>>> resolve_pointer(f, '/x/y', None) is None
True
>>> resolve_pointer(f, '/x/y', 'x') == 'x'
True
>>>
>>> d = {'a': {'b': 'c'}}
>>> resolve_pointer(d, '/a/b/d', 'y') == 'y'
True
I noticed the behavior in to cases:
Both this cases are the product of the handling of getitem in the function walk(), in case the doc is not a list nor a dict, getitem is called without an except. Is there a reason for that? If not, I'd would be more than happy to open a pull request with new tests and a fix.