Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions Lib/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,18 +501,26 @@ class NodeVisitor(object):
class name of the node. So a `TryFinally` node visit function would
be `visit_TryFinally`. This behavior can be changed by overriding
the `visit` method. If no visitor function exists for a node
(return value `None`) the `generic_visit` visitor is used instead.
(return value `list` | `None`) the `generic_visit` visitor is used instead.
The `generic_visit` visitor iterates the nodes, calls appropriate `visit_` method
and returns a list of all return values of ``'visit_'`` method calls.

Don't use the `NodeVisitor` if you want to apply changes to nodes during
traversing. For this a special visitor exists (`NodeTransformer`) that
allows modifications.
"""
def __init__(self):
self.visited_items = []

def visit(self, node):
"""Visit a node."""
method = 'visit_' + node.__class__.__name__
visitor = getattr(self, method, self.generic_visit)
return visitor(node)
visited = visitor(node)
if (visitor != self.generic_visit) and not isinstance(visited, list):
if hasattr(self, 'visited_items'):
self.visited_items.append(visited)
return visited

def generic_visit(self, node):
"""Called if no explicit visitor function exists for a node."""
Expand All @@ -523,6 +531,10 @@ def generic_visit(self, node):
self.visit(item)
elif isinstance(value, AST):
self.visit(value)
try:
return self.visited_items
except AttributeError:
return None


class NodeTransformer(NodeVisitor):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Change behaviour of NodeVisitor's generic_visit to return list of return
values of calls to visit_x method instead of None. For new functionailty to
work derived classes need to call NodeVisitors constructor otherwise, it
behaves same as before(returns None).
Loading