@@ -92,7 +92,7 @@ def _get_intermediate_items(cls, item):
9292
9393 def traverse ( self , predicate = lambda i ,d : True ,
9494 prune = lambda i ,d : False , depth = - 1 , branch_first = True ,
95- visit_once = True , ignore_self = 1 ):
95+ visit_once = True , ignore_self = 1 , as_edge = False ):
9696 """
9797 ``Returns``
9898 iterator yieling of items found when traversing self
@@ -119,41 +119,49 @@ def traverse( self, predicate = lambda i,d: True,
119119
120120 ``ignore_self``
121121 if True, self will be ignored and automatically pruned from
122- the result. Otherwise it will be the first item to be returned"""
122+ the result. Otherwise it will be the first item to be returned.
123+ If as_edge is True, the source of the first edge is None
124+
125+ ``as_edge``
126+ if True, return a pair of items, first being the source, second the
127+ destinatination, i.e. tuple(src, dest) with the edge spanning from
128+ source to destination"""
123129 visited = set ()
124130 stack = Deque ()
125- stack .append ( ( 0 ,self ) ) # self is always depth level 0
131+ stack .append ( ( 0 ,self , None ) ) # self is always depth level 0
126132
127- def addToStack ( stack , lst , branch_first , dpth ):
133+ def addToStack ( stack , item , branch_first , depth ):
134+ lst = self ._get_intermediate_items ( item )
128135 if not lst :
129136 return
130137 if branch_first :
131- stack .extendleft ( ( dpth , item ) for item in lst )
138+ stack .extendleft ( ( depth , i , item ) for i in lst )
132139 else :
133- reviter = ( ( dpth , lst [i ] ) for i in range ( len ( lst )- 1 ,- 1 ,- 1 ) )
140+ reviter = ( ( depth , lst [i ], item ) for i in range ( len ( lst )- 1 ,- 1 ,- 1 ) )
134141 stack .extend ( reviter )
135142 # END addToStack local method
136143
137144 while stack :
138- d , item = stack .pop () # depth of item, item
145+ d , item , src = stack .pop () # depth of item, item, item_source
139146
140147 if visit_once and item in visited :
141148 continue
142149
143150 if visit_once :
144151 visited .add (item )
145152
146- if prune ( item , d ):
153+ rval = ( as_edge and (src , item ) ) or item
154+ if prune ( rval , d ):
147155 continue
148156
149157 skipStartItem = ignore_self and ( item == self )
150- if not skipStartItem and predicate ( item , d ):
151- yield item
158+ if not skipStartItem and predicate ( rval , d ):
159+ yield rval
152160
153161 # only continue to next level if this is appropriate !
154162 nd = d + 1
155163 if depth > - 1 and nd > depth :
156164 continue
157165
158- addToStack ( stack , self . _get_intermediate_items ( item ) , branch_first , nd )
166+ addToStack ( stack , item , branch_first , nd )
159167 # END for each item on work stack
0 commit comments