@@ -606,8 +606,8 @@ class Index(JSONPath):
606606 NOTE: For the concrete syntax of `[*]`, the abstract syntax is a Slice() with no parameters (equiv to `[:]`
607607 """
608608
609- def __init__ (self , index ):
610- self .index = index
609+ def __init__ (self , * indices ):
610+ self .indices = indices
611611
612612 def find (self , datum ):
613613 return self ._find_base (datum , create = False )
@@ -621,10 +621,12 @@ def _find_base(self, datum, create):
621621 if datum .value == {}:
622622 datum .value = _create_list_key (datum .value )
623623 self ._pad_value (datum .value )
624- if datum .value and len (datum .value ) > self .index :
625- return [DatumInContext (datum .value [self .index ], path = self , context = datum )]
626- else :
627- return []
624+ rv = []
625+ for index in self .indices :
626+ # invalid indices do not crash, return [] instead
627+ if datum .value and len (datum .value ) > index :
628+ rv += [DatumInContext (datum .value [index ], path = Index (index ), context = datum )]
629+ return rv
628630
629631 def update (self , data , val ):
630632 return self ._update_base (data , val , create = False )
@@ -638,31 +640,39 @@ def _update_base(self, data, val, create):
638640 data = _create_list_key (data )
639641 self ._pad_value (data )
640642 if hasattr (val , '__call__' ):
641- val .__call__ (data [self .index ], data , self .index )
642- elif len (data ) > self .index :
643- data [self .index ] = val
643+ for index in self .indices :
644+ val .__call__ (data [index ], data , index )
645+ else :
646+ if not isinstance (val , list ):
647+ val = [val ]
648+ # allows somelist[5,1,2] = [some_value, another_value, third_value]
649+ # skip the indices that are too high but the value will be applied to the next index
650+ for index in self .indices :
651+ if len (data ) > index :
652+ data [index ] = val .pop (0 )
644653 return data
645654
646655 def filter (self , fn , data ):
647- if fn (data [self .index ]):
648- data .pop (self .index ) # relies on mutation :(
656+ for index in self .indices :
657+ if fn (data [index ]):
658+ data .pop (index ) # relies on mutation :(
649659 return data
650660
651661 def __eq__ (self , other ):
652- return isinstance (other , Index ) and self .index == other .index
662+ return isinstance (other , Index ) and sorted ( self .indices ) == sorted ( other .indices )
653663
654664 def __str__ (self ):
655- return '[%i]' % self .index
665+ return str ( list ( self .indices ))
656666
657667 def __repr__ (self ):
658- return '%s(index =%r)' % (self .__class__ .__name__ , self .index )
668+ return '%s(indices =%r)' % (self .__class__ .__name__ , self .indices )
659669
660670 def _pad_value (self , value ):
661- if len (value ) <= self .index :
662- pad = self .index - len (value ) + 1
671+ _max = max (self .indices )
672+ if len (value ) <= _max :
673+ pad = _max - len (value ) + 1
663674 value += [{} for __ in range (pad )]
664675
665-
666676class Slice (JSONPath ):
667677 """
668678 JSONPath matching a slice of an array.
@@ -709,7 +719,7 @@ def find(self, datum):
709719 return [DatumInContext (datum .value [i ], path = Index (i ), context = datum ) for i in xrange (0 , len (datum .value ))]
710720 else :
711721 return [DatumInContext (datum .value [i ], path = Index (i ), context = datum ) for i in range (0 , len (datum .value ))[self .start :self .end :self .step ]]
712-
722+
713723 def update (self , data , val ):
714724 for datum in self .find (data ):
715725 datum .path .update (data , val )
0 commit comments