> On 16 Aug 2019, at 21:44, Caleb Donovick <donov...@cs.stanford.edu> wrote:
> 
> > 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. 

You can dump the AST back to a string with Parso.  In fact it's built in and 
way better because it keeps the formatting and comments!

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

Then you really should look at parso!


> 
>> 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/CLIRR7PZQDQC5DJI55MHNA3GMNRTOLKB/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to