@@ -41,6 +41,7 @@ class JSONPath:
4141
4242 # common patterns
4343 SEP = ";"
44+ _MISSING = object ()
4445 REP_DOUBLEDOT = re .compile (r"\.\." )
4546 REP_DOT = re .compile (r"(?<!\.)\.(?!\.)" )
4647
@@ -177,11 +178,14 @@ def _traverse(f, obj, i: int, path: str, *args):
177178 def _getattr (obj : dict , path : str , * , convert_number_str = False ):
178179 r = obj
179180 for k in path .split ("." ):
180- try :
181- r = r .get (k )
182- except (AttributeError , KeyError ) as err :
183- logger .error (err )
184- return None
181+ if isinstance (r , dict ):
182+ if k in r :
183+ r = r [k ]
184+ else :
185+ return JSONPath ._MISSING
186+ else :
187+ return JSONPath ._MISSING
188+
185189 if convert_number_str and isinstance (r , str ):
186190 try :
187191 if r .isdigit ():
@@ -193,15 +197,19 @@ def _getattr(obj: dict, path: str, *, convert_number_str=False):
193197
194198 @staticmethod
195199 def _sorter (obj , sortbys ):
200+ def key_func (t , k ):
201+ v = JSONPath ._getattr (t [1 ], k , convert_number_str = True )
202+ return v if v is not JSONPath ._MISSING else None
203+
196204 try :
197205 for sortby in sortbys .split ("," )[::- 1 ]:
198206 if sortby .startswith ("~" ):
199207 obj .sort (
200- key = lambda t , k = sortby : JSONPath . _getattr ( t [ 1 ] , k [1 :], convert_number_str = True ),
208+ key = lambda t , k = sortby : key_func ( t , k [1 :]),
201209 reverse = True ,
202210 )
203211 else :
204- obj .sort (key = lambda t , k = sortby : JSONPath . _getattr ( t [ 1 ] , k , convert_number_str = True ))
212+ obj .sort (key = lambda t , k = sortby : key_func ( t , k ))
205213 except TypeError as e :
206214 raise JSONPathTypeError (f"not possible to compare str and int when sorting: { e } " ) from e
207215
@@ -314,7 +322,9 @@ def _trace(self, obj, i: int, path):
314322 if isinstance (obj , dict ):
315323 obj_ = {}
316324 for k in step [1 :- 1 ].split ("," ):
317- obj_ [k ] = self ._getattr (obj , k )
325+ v = self ._getattr (obj , k )
326+ if v is not JSONPath ._MISSING :
327+ obj_ [k ] = v
318328 self ._trace (obj_ , i + 1 , path )
319329 else :
320330 raise ExprSyntaxError ("field-extractor must acting on dict" )
0 commit comments