> 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/