> This part could be solved without making the lists AST nodes at all. Just
use new bare subclasses of list for each of the kinds of lists, so a field
in a node never has an empty list, it has an empty ExprList or StmtList or
whatever. If that’s sufficient for your needs, that seems pretty easy, and
I don’t think it would have any compatibility problems.
This would probably be sufficient. It would make it pretty easy to write
replacement versions of what I want from ast.py with the behavior I want.

>  Also, while a I can see a use for StmtList (because every StmtList is a
block or a module body, so they all have quite a bit in common), where
would you use ExprList?
You are right I only really care about StmtList.  Just seemed like a
strange asymmetry to have StmtList but not ExprList ect...

> But I don’t think there’s any actual behavior in AST that you need
(except maybe for looking like a structseq, with _fields, but you can fake
that with a plain old class a la namedtuple or dataclass, as long as
there’s no C code that relies on being able to iterate the structseq
fields).
I really don't care about the SmttList being a  structseq or at least I
don't think I do.  I am pretty unfamiliar with the C bits of CPython.

Both your suggestions seem completely sufficient to me.

----

> Just to make sure we're  on the same page: what are you using the ast
module for?
I am building DSLs and need to perform AST analysis / rewriting.  I
commonly perform block level analysis but it gets pretty verbose because of
all the different places stmt* can be.
I am unfamiliar with parso but it  looks like it has some nice convenience
functions. It probably won't be useful for me though because I need to be
able to exec the AST.  Further, it is highly desirable for me to be able to
turn the AST back into a string (as astor allows) so that I can generate
reasonable error messages and debug.


On Fri, Aug 16, 2019 at 1:24 PM Anders Hovmöller <bo...@killingar.net>
wrote:

> Just to make sure we're  on the same page: what are you using the ast
> module for?
>
> Maybe moving to another lib like parso actually helps your real problem
> more...
>
> > On 15 Aug 2019, at 22:02, Caleb Donovick <donov...@cs.stanford.edu>
> wrote:
> >
> > When walking an ast it impossible to know the type of an empty list
> without writing down some giant lookup from node types and field names to
> field types.
> >
> > More concretely it would nice be to able to programatically visit all
> blocks (stmt*)  without having to something like:
> >
> > ```
> > class BlockVisitor(NodeVisitor):
> >     def visit_If(self, node: If):
> >         self.visit(node.test)
> >         self.visit_block(node.body)
> >         self.visit_block(node.orelse)
> >
> >     def visit_FunctionDef(self, node: FunctionDef):
> >         for field, value in iter_fields(node):
> >             if field == 'body':
> >                 self.visit_block(value)
> >             else:
> >                 # the implementation of generic_visit
> > ```
> > Now it turns out that all fields that are lists and are named "body",
> "orelse", or "finalbody" are stmt* and only such fields are stmt*.  A rule
> could also be synthesized to identify expr* and so forth but this seems
> incredibly hacky to me.
> >
> > It would be much cleaner if <type>* were actual nodes in the ast. E.g.
> something like:
> > ```
> > class ast_list(AST, MutableSequence[T_co]): ...
> > class StmtList(ast_list[stmt]): ...
> > class ExprList(ast_list[expr]): ...
> > ...
> > class FunctionDef(stmt):
> >     name: identifier
> >     args: arguments
> >     body: StmtList
> >     decorator_list: ExprList
> >     returns: Optional[expr]
> > ```
> > This would not change the behavior or structure in any way other than
> tagging <type>* and allowing <type>* to be visited.
> >
> > It would potentially break old code which relies on stuff like `if
> isinstance(node.field, list)` e.g. the implementation of generic_visit.
> >
> >
> > Caleb Donovick
> >
> > _______________________________________________
> > Python-ideas mailing list -- python-ideas@python.org
> > To unsubscribe send an email to python-ideas-le...@python.org
> > https://mail.python.org/mailman3/lists/python-ideas.python.org/
> > Message archived at
> https://mail.python.org/archives/list/python-ideas@python.org/message/ZHOXQTDSHOERZSGUJXLNJCYLKKQJOYTA/
> > Code of Conduct: http://python.org/psf/codeofconduct/
>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/3BX7ZI32YBRZ5JYMFJQLOF4W2GWRMOXB/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to