redbaron
redbaron copied to clipboard
How to get list of children?
Is there a way to get a list of a Node's children? Alternatively is it possible to get a list of which attributes of a Node are actually valid?
I'm writing code that recurses through a redbaron ast. At the moment, I have an if case for every subclass of Node, but it would be much simpler for me to have a default case that just recurses through all children.
This is a fantastic project and it's been extremely handy for me. Thank you!
mmm, I am not sure that I get you clearly, but you can specify an argument recursive
for find and find_all. As you can see in docs, it's already set up to True.
Could you be more specific, u wanna something like Visitor Pattern when u use ast module?
Here's an example. I want to write a function that recursively visits each node in an ast
Let's say I have this bit of code that I want to recurse through.
def incX():
global x
x = x + 1
return x
Right now my function looks like this. It's very long and there's a special case for every type of node and I'm probably going to forget to implement half the cases.
def visit_nodes(node):
do_something(node)
if isinstance(node, redbaron.nodes.DefNode):
visit_nodes(node.decorators)
visit_nodes(node.arguments)
visit_nodes(node.value)
elif isinstance(node, redbaron.base_nodes.LineProxyList):
[visit_nodes(x) for x in node]
elif isinstance(node, redbaron.nodes.GlobalNode):
visit_nodes(node.value)
elif isinstance(node, redbaron.base_nodes.CommaProxyList):
[visit_nodes(x) for x in node]
elif isinstance(node, redbaron.nodes.AssignmentNode):
visit_nodes(node.target)
visit_nodes(node.value)
...
...
...
It would be much cleaner for my purposes if there were some way to get the children of a node without needing to know anything about their relation. Here is what that code might look like:
def visit_nodes(node):
do_something(node)
for child in node.children():
visit_nodes(child)
In reality, I want to recurse through two ast's at the same time so I can compare them. Is it possible to do this with the existing node.find() and node.find_all()?
Hello,
There is actually no official API yet for that, you can find the internal way to do that there:
https://github.com/PyCQA/redbaron/blob/master/redbaron/base_nodes.py#L271-L293 which I should really convert into something like a .walk
method or something like that because it's a recurring demand (but test/docs takes time, feel free to submit a PR :))
This is exactly what i was looking for, thank you so much!
Expect a PR from me in a few days. It's finals week at Poly and I need to procrastinate ;)
@yabberyabber I can't get it, how that piece of code:
def visit_nodes(node):
do_something(node)
for child in node.children():
visit_nodes(child)
could help you do not check a type of node? It's only a top-bottom recursive descent which could have done via node_list, cause, as I remember, It stores child nodes of the current element. And for your task, a Typed Visitor is much preferred.
But as @Psycojoker said, I would be happy to see something like that in redbaron)