@@ -63,7 +63,7 @@ class LazyVisitor(GenericVisitor):
63
63
64
64
"""
65
65
A generic visitor that lazily yields results instead of flattening results
66
- from children at every step (unless required for rebuilding) .
66
+ from children at every step.
67
67
68
68
Subclass-defined visit methods (and default_retval) should be generators.
69
69
"""
@@ -1014,12 +1014,15 @@ def visit_Node(self, o, ret=None, parents=None, in_parent=False):
1014
1014
class FindSymbols (LazyVisitor ):
1015
1015
1016
1016
@classmethod
1017
- def retval (cls , * its : Iterable [Any ]) -> Iterator [Any ]:
1017
+ def join (cls , * its : Iterable [Any ], key : Callable [[ Any ], Any ] = str ) -> Iterator [Any ]:
1018
1018
"""
1019
- Filterrs and flattens nested iterables while preserving relative order.
1019
+ Flattens nested iterables and filters for uniqueness, ordering results
1020
+ lexicographically so we don't need to sort the final result.
1020
1021
"""
1021
- ret = chain (flatten_iter (it ) for it in its )
1022
- return filter_ordered_iter (flatten_iter (ret ), key = id )
1022
+
1023
+ _it = (flatten_iter (it ) for it in its )
1024
+ yield from filter_ordered_iter (flatten_iter (_it ), key = id )
1025
+
1023
1026
1024
1027
"""
1025
1028
Find symbols in an Iteration/Expression tree.
@@ -1070,27 +1073,27 @@ def __init__(self, mode: str = 'symbolics') -> None:
1070
1073
else :
1071
1074
self .rule = lambda n : chain (* [self .rules [mode ](n ) for mode in modes ])
1072
1075
1073
- def _post_visit (self , ret : Iterable [Any ]) -> list [Any ]:
1074
- return sorted (ret , key = lambda i : str ( i ) )
1076
+ def _post_visit (self , ret : Iterable [Any ]) -> Iterable [Any ]:
1077
+ return sorted (ret , key = str )
1075
1078
1076
1079
def visit_tuple (self , o : Sequence [Any ]) -> Iterator [Any ]:
1077
- yield from self .retval (self ._visit (i ) for i in o )
1080
+ yield from self .join (self ._visit (i ) for i in o )
1078
1081
1079
1082
visit_list = visit_tuple
1080
1083
1081
1084
def visit_Node (self , o : Node ) -> Iterator [Any ]:
1082
- yield from self .retval (self ._visit (o .children ), self .rule (o ))
1085
+ yield from self .join (self ._visit (o .children ), self .rule (o ))
1083
1086
1084
1087
def visit_ThreadedProdder (self , o ) -> Iterator [Any ]:
1085
1088
# TODO: this handle required because ThreadedProdder suffers from the
1086
1089
# long-standing issue affecting all Node subclasses which rely on
1087
1090
# multiple inheritance
1088
- yield from self .retval (self ._visit (o .then_body ), self .rule (o ))
1091
+ yield from self .join (self ._visit (o .then_body ), self .rule (o ))
1089
1092
1090
1093
def visit_Operator (self , o ) -> Iterator [Any ]:
1091
- yield from self .retval (self ._visit (o .body ),
1092
- flatten_iter ( self ._visit ( i ) for i in o . _dspace . parts ),
1093
- self .rule ( o ))
1094
+ yield from self .join (self ._visit (o .body ),
1095
+ self .rule ( o ),
1096
+ * ( self ._visit ( i ) for i in o . _dspace . parts ))
1094
1097
1095
1098
1096
1099
class FindNodes (LazyVisitor ):
0 commit comments