@@ -92,7 +92,7 @@ def _get_intermediate_items(cls, item):
92
92
93
93
def traverse ( self , predicate = lambda i ,d : True ,
94
94
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 ):
96
96
"""
97
97
``Returns``
98
98
iterator yieling of items found when traversing self
@@ -119,41 +119,49 @@ def traverse( self, predicate = lambda i,d: True,
119
119
120
120
``ignore_self``
121
121
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"""
123
129
visited = set ()
124
130
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
126
132
127
- def addToStack ( stack , lst , branch_first , dpth ):
133
+ def addToStack ( stack , item , branch_first , depth ):
134
+ lst = self ._get_intermediate_items ( item )
128
135
if not lst :
129
136
return
130
137
if branch_first :
131
- stack .extendleft ( ( dpth , item ) for item in lst )
138
+ stack .extendleft ( ( depth , i , item ) for i in lst )
132
139
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 ) )
134
141
stack .extend ( reviter )
135
142
# END addToStack local method
136
143
137
144
while stack :
138
- d , item = stack .pop () # depth of item, item
145
+ d , item , src = stack .pop () # depth of item, item, item_source
139
146
140
147
if visit_once and item in visited :
141
148
continue
142
149
143
150
if visit_once :
144
151
visited .add (item )
145
152
146
- if prune ( item , d ):
153
+ rval = ( as_edge and (src , item ) ) or item
154
+ if prune ( rval , d ):
147
155
continue
148
156
149
157
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
152
160
153
161
# only continue to next level if this is appropriate !
154
162
nd = d + 1
155
163
if depth > - 1 and nd > depth :
156
164
continue
157
165
158
- addToStack ( stack , self . _get_intermediate_items ( item ) , branch_first , nd )
166
+ addToStack ( stack , item , branch_first , nd )
159
167
# END for each item on work stack
0 commit comments