def exclude( self ): '''exclude data paths. Only those data paths not matching the exclude term are accepted. ''' if not self.exclude_paths: return data_paths = DataTree.getPaths( self.data ) # currently enumerates - bfs more efficient all_paths = list(itertools.product( *data_paths )) for path in all_paths: for s in self.exclude_paths: if s in path: self.debug( "%s: ignoring path %s because of :exclude:=%s" % (self.tracker, path, s)) try: DataTree.removeLeaf( self.data, path ) except KeyError: pass elif s.startswith("r(") and s.endswith(")"): # collect pattern matches: # remove r() s = s[2:-1] # remove flanking quotation marks if s[0] in ('"', "'") and s[-1] in ('"', "'"): s = s[1:-1] rx = re.compile( s ) if any( ( rx.search( p ) for p in path ) ): self.debug( "%s: ignoring path %s because of :exclude:=%s" % (self.tracker, path, s)) try: DataTree.removeLeaf( self.data, path ) except KeyError: pass
def __call__(self, data ): if self.nlevels == None: raise NotImplementedError("incomplete implementation of %s" % str(self)) labels = DataTree.getPaths( data ) debug( "transform: started with paths: %s" % labels) assert len(labels) >= self.nlevels, "expected at least %i levels - got %i" % (self.nlevels, len(labels)) paths = list(itertools.product( *labels[:-self.nlevels] )) for path in paths: work = DataTree.getLeaf( data, path ) if not work: continue new_data = self.transform( work, path ) if new_data: if path: DataTree.setLeaf( data, path, new_data ) else: # set new root data = new_data else: warn( "no data at %s - removing branch" % str(path)) DataTree.removeLeaf( data, path ) debug( "transform: finished with paths: %s" % DataTree.getPaths( data )) return data