Skip to content

Commit

Permalink
Add a utility function to strip Comment nodes from a parsed tree.
Browse files Browse the repository at this point in the history
Resolves issue #23
  • Loading branch information
wahuneke authored and t3rn0 committed Oct 27, 2023
1 parent f9b0221 commit 6a98cfe
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1 deletion.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ If you have python3.9 or above it's also possible to unparse the tree object wit
>>> print(unparse(tree))
hello = 'hello' # comment to hello
```
**Note**: Python `compile()` cannot be run on the tree output from parse. The included `pre_compile_fixer()` function can be used to fix the tree (stripping
comment nodes) if it will be necessary to compile the output.

More examples can be found in test_parse.py and test_unparse.py.

## Contributing
Expand Down
13 changes: 13 additions & 0 deletions ast_comments.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,3 +262,16 @@ def _get_first_not_comment_idx(orelse: list[ast.stmt]) -> int:

def unparse(ast_obj: ast.AST) -> str:
return _Unparser().visit(ast_obj)


def pre_compile_fixer(tree: ast.AST) -> ast.AST:
"""
The parse output from ast_comments cannot compile (see issue #23). This function can be
run to fix the output so that it can compile. This transformer strips out Comment nodes.
"""

class RewriteComments(ast.NodeTransformer):
def visit_Comment(self, node: ast.AST) -> ast.AST:
return None

return RewriteComments().visit(tree)
32 changes: 31 additions & 1 deletion test_parse.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,41 @@
"""Tests for `ast_comments.parse`."""

import ast
import dis
from textwrap import dedent

import pytest

from ast_comments import Comment, parse
from ast_comments import Comment, parse, pre_compile_fixer


def test_compile_parse_output():
"""
Output of `ast_comments.parse` can be compiled after applying the compile_fix helper function.
The tree resulting from this compilation should be the same as the tree resulting from
compiling the same code without comments.
"""
with_comments = dedent(
"""
func(1, 2) # comment
# Another comment
x = 5 * "s"
"""
)
without_comments = dedent(
"""
func(1, 2)
x = 5 * "s"
"""
)

compiled_with = compile(pre_compile_fixer(parse(with_comments)), "<string>", "exec")
compiled_without = compile(parse(without_comments), "<string>", "exec")

assert list(dis.get_instructions(compiled_with)) == list(
dis.get_instructions(compiled_without)
)


def test_comment_at_start_of_inner_block_getting_correctly_parsed():
Expand Down

0 comments on commit 6a98cfe

Please sign in to comment.