diff options
Diffstat (limited to 'lib/sqlalchemy/sql/visitors.py')
| -rw-r--r-- | lib/sqlalchemy/sql/visitors.py | 37 |
1 files changed, 12 insertions, 25 deletions
diff --git a/lib/sqlalchemy/sql/visitors.py b/lib/sqlalchemy/sql/visitors.py index 09d5a0982..7eccc9b89 100644 --- a/lib/sqlalchemy/sql/visitors.py +++ b/lib/sqlalchemy/sql/visitors.py @@ -37,17 +37,17 @@ class ClauseVisitor(object): traverse_chained = traverse_single def iterate(self, obj): - """traverse the given expression structure, and return an iterator of all elements.""" + """traverse the given expression structure, returning an iterator of all elements.""" stack = [obj] - traversal = [] - while len(stack) > 0: + traversal = util.deque() + while stack: t = stack.pop() - yield t - traversal.insert(0, t) + traversal.appendleft(t) for c in t.get_children(**self.__traverse_options__): stack.append(c) - + return iter(traversal) + def traverse(self, obj, clone=False): """traverse and visit the given expression structure. @@ -119,32 +119,19 @@ class ClauseVisitor(object): def clone(element): return self._clone_element(element, stop_on, cloned) elem._copy_internals(clone=clone) - - for v in self._iterate_visitors: - meth = getattr(v, "visit_%s" % elem.__visit_name__, None) - if meth: - meth(elem) + + self.traverse_single(elem) for e in elem.get_children(**self.__traverse_options__): if e not in stop_on: self._cloned_traversal_impl(e, stop_on, cloned) return elem - + def _non_cloned_traversal(self, obj): """a non-recursive, non-cloning traversal.""" - - stack = [obj] - traversal = [] - while len(stack) > 0: - t = stack.pop() - traversal.insert(0, t) - for c in t.get_children(**self.__traverse_options__): - stack.append(c) - for target in traversal: - for v in self._iterate_visitors: - meth = getattr(v, "visit_%s" % target.__visit_name__, None) - if meth: - meth(target) + + for target in self.iterate(obj): + self.traverse_single(target) return obj def _iterate_visitors(self): |
