berkerpeksag / astor

Python AST read/write
https://pypi.org/project/astor/
BSD 3-Clause "New" or "Revised" License
810 stars 102 forks source link

Allow specifying the generator class. #114

Closed matham closed 5 years ago

matham commented 6 years ago

Fixes #113 Adds the ability to specify the class to be used to generate the source code.

matham commented 6 years ago

I have another related question. I would like to be able to adjust the maxline parameter passed to split_lines in to_source. Would it make sense if I added maxline to the function signature and forwarded it to split_line?

berkerpeksag commented 6 years ago

Would it make sense if I added maxline to the function signature and forwarded it to split_line?

Could you open a new issue to discuss this one? There is an open PR to refactor astor/source_repr.py and its friends, so maybe we can come up with a better solution.

matham commented 6 years ago

I just wanted to update that I have not forgotten about the PR, it's just that I ended up using astor quite a bit in new code I wrote, so before I continued with the PR I wanted to get a clearer picture for myself how I was going to use astor to make sure my solution was good approach.

In the end, I just wrote my own version of to_source (https://github.com/matham/kivy/blob/ast_compile/kivy/lang/compiler/ast_parse.py#L320) because I needed further customization, so I'm wondering if I should continue with this PR, or if it's better that the user make their own to_source, like I did rather than making to_source more complex? Especially if the API will be changing as you mentioned?

If the underlying API used in to_source is available more clearly, maybe that's better than adding more stuff to to_source? But either way, I can add tests etc to this PR or drop it. Whichever you think is better.

berkerpeksag commented 5 years ago

I think this PR would still help users to customize source generator. I recently came across a blog post using astor (I can't read Chinese, but I can read Python :)): http://blog.soliloquize.org/2017/02/08/%E4%BD%BF%E7%94%A8ast%E7%A7%BB%E9%99%A4%E4%BB%A3%E7%A0%81%E4%B8%AD%E7%9A%84print%E8%AF%AD%E5%8F%A5/

With source_generator_class, the latest example can be written without needing to subclass ast.NodeTransformer:

import astor

class RemovePrintGenerator(astor.code_gen.SourceGenerator):

    def visit_Call(self, node):
        if node.func.id != 'print':
            super().visit_Call(node)

print(astor.to_source(astor.parse_file('foo.py'), source_generator_class=RemovePrintGenerator))
matham commented 5 years ago

Thanks for finishing this off. I hadn't had the time to complete it.