berkerpeksag / astor

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

Can't find implementation of method `SourceGenerator.get__pp` #203

Closed tristanlatr closed 9 months ago

tristanlatr commented 2 years ago

Hi,

I'm looking at your code in order to get inspirations to code a colorizer for ast values and I can't find where you defined the method SourceGenerator.get__pp.

Any help with that would be appreciated. Thanks.

berkerpeksag commented 2 years ago

Hello,

All the magic for get_* methods happens in the __getattr__ method:

https://github.com/berkerpeksag/astor/blob/ce56db29bdc3d7d86f66df3e501c7f90febdb0cb/astor/code_gen.py#L192-L207

And _pp is defined here:

https://github.com/berkerpeksag/astor/blob/ce56db29bdc3d7d86f66df3e501c7f90febdb0cb/astor/code_gen.py#L193

Let me know if this answers your question.

tristanlatr commented 2 years ago

Thanks for the quick response.

So, if I understand correctly, _p_op and _pp are only defined here:

https://github.com/berkerpeksag/astor/blob/ce56db29bdc3d7d86f66df3e501c7f90febdb0cb/astor/code_gen.py#L787

and there

https://github.com/berkerpeksag/astor/blob/ce56db29bdc3d7d86f66df3e501c7f90febdb0cb/astor/code_gen.py#L84

The precedence handling a real headache...

My use case is to colorize the assigned values to constant, so not all nodes needs to be handled, whereas in astor, only nodes valid in assignment expressions needs to be handled. For instance:

CONST = (3-6)*0.5 + func(123)

The current behaviour can be observed here: https://pydoctor--402.org.readthedocs.build/en/402/docformat/restructuredtext/restructuredtext_demo.constants.html#RE_RAW_STR2

For the little story, I ended up with always adding parenthesis when precedence of the parent operation is greater or equal to the precedence of the nested operation.

See the code adapted from the astor library here: https://github.com/tristanlatr/pydoctor/blob/c6316e4351ceac239152cf478e01a184faaccedd/pydoctor/epydoc/markup/_pyval_repr.py#L131-L158

It currently only support ast.UnaryOp, ast.BinOp and ast.BoolOp.

In your code, I'm not sure to understand why the set_precedence function is called practically all the time, I see only ast.UnaryOp, ast.BinOp, ast.BoolOp, ast.Compare and ast.IfExp that actually requires to handle delimiters in a dynamic manner. I'm not sure to see where it's actually useful outside of the listed nodes, in the case of assignments only.

Anyway, thanks for your answer.