-
-
Notifications
You must be signed in to change notification settings - Fork 29.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expose ast.unparse in the ast module #83051
Comments
As discussed in https://mail.python.org/archives/list/python-dev@python.org/thread/JAQDBMC23HW2PQ27HQNJ7G244T423IDD/ I propose to expose the unparse.py tool as part of the standard library in the ast module. The exposed function will have the interface: ast.unparse(ast_obj, *, option1, option2,...) and will return a string with the unparsed version of ast_obj. The unparse tool will need some cosmetic improvements that will be tracked separately in this issue. |
After PR17302 is merged we need to fix the following cosmetic issues indicated by Victor: (*) unparse adds many useless parentheses. The algorithm seems naive. (*) newlines in docstring are rendered as two characters: "\" + "n" (*) Indentation is hardcoded to 4 spaces. What if I want 2 spaces or (*) Float infinity is replaces with 1e309. Again, maybe someone wants |
After PR 17302 is accepted, I'll work on refactorings including a precedence algorithm to find when to parentheses. |
@gvanrossum are you OK with adding type comments support? Current version loses type comment information so if typed_ast parses this, they wont be the same in AST representation. |
Good catch, definitely do that! |
I created bpo-39069: "Move ast.unparse() function to a different module". |
ExtSlice nodes without second value doesn't roundtrip properly source: x[1:2,]
Expr(
value=Subscript(
value=Name(id='x', ctx=Load()),
- slice=ExtSlice(
- dims=[
- Slice(
- lower=Constant(value=1, kind=None),
- upper=Constant(value=2, kind=None),
- step=None)]),
+ slice=Slice(
+ lower=Constant(value=1, kind=None),
+ upper=Constant(value=2, kind=None),
+ step=None),
ctx=Load()))],
type_ignores=[]) (I have a fix for unifying both tuple, constant tuple and extslice dims traversing) |
We might need to tweak the documentation @pablogsal,
If I interpret >>> def wrap(expr):
... return ast.Module(body=[ast.Expr(expr)], type_ignores=[])
...
>>> constant_tuple = wrap(ast.Constant(value=(1, 2, 3), kind=None))
>>> normalpy_tuple = ast.parse("(1, 2, 3)")
>>> ast.unparse(constant_tuple) == ast.unparse(normalpy_tuple)
True
>>> ast.dump(ast.parse(ast.unparse(constant_tuple))) != ast.dump(constant_tuple)
True
>>> ast.dump(ast.parse(ast.unparse(constant_tuple))) == ast.dump(normalpy_tuple)
True This isn't a bug in the code because there is no way we can generate a string that can produce a constant tuple. But this makes the docstring false, at least in certain cases. |
Maybe we can say that is 'as close as possible' if you pass an arbitrary AST object (if only happens with Constants we could documment exactly that). Let me think about this and I will make PR updating the docs. |
Well, I'm happy to say that 3.9.0 is finally released with the ast.unparse interface. After tens of PRs, I think it is time for us to move on. For all future bugs, please create a new issue and nosy me. Thanks everyone who has participated this journey! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: