Last active
June 17, 2020 06:22
-
-
Save marsam/d2a5af1563d129bb9482 to your computer and use it in GitHub Desktop.
An IPython extension to pretty print python AST.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/build/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
""" | |
astpp | |
===== | |
A pretty-printing dump function for the ast module. The code was copied from | |
the ast.dump function and modified slightly to pretty-print. | |
Alex Leone (acleone ~AT~ gmail.com), 2010-01-30 | |
Usage | |
----- | |
ipython | |
~~~~~~~ | |
Add the following in your ipython profile config: | |
.. code:: python | |
c = get_config() | |
try: | |
import astpp | |
except ImportError: | |
pass | |
else: | |
c.TerminalIPythonApp.extensions.append('astpp') | |
c.InteractiveShellApp.extensions.append('astpp') | |
""" | |
from __future__ import print_function | |
from ast import AST, iter_fields, parse | |
def dump(node, annotate_fields=True, include_attributes=False, indent=' '): | |
""" | |
Return a formatted dump of the tree in *node*. This is mainly useful for | |
debugging purposes. The returned string will show the names and the values | |
for fields. This makes the code impossible to evaluate, so if evaluation is | |
wanted *annotate_fields* must be set to False. Attributes such as line | |
numbers and column offsets are not dumped by default. If this is wanted, | |
*include_attributes* can be set to True. | |
""" | |
def _format(node, level=0): | |
if isinstance(node, AST): | |
fields = [(a, _format(b, level)) for a, b in iter_fields(node)] | |
rv = '%s(%s' % (node.__class__.__name__, ', '.join( | |
('%s=%s' % field for field in fields) | |
if annotate_fields else | |
(b for a, b in fields) | |
)) | |
if include_attributes and node._attributes: | |
rv += fields and ', ' or ' ' | |
rv += ', '.join('%s=%s' % (a, _format(getattr(node, a))) | |
for a in node._attributes) | |
return rv + ')' | |
elif isinstance(node, list): | |
lines = ['['] | |
lines.extend((indent * (level + 2) + _format(x, level + 2) + ',' | |
for x in node)) | |
if len(lines) > 1: | |
lines.append(indent * (level + 1) + ']') | |
else: | |
lines[-1] += ']' | |
return '\n'.join(lines) | |
return repr(node) | |
if not isinstance(node, AST): | |
raise TypeError('expected AST, got %r' % node.__class__.__name__) | |
return _format(node) | |
def parseprint(source, filename='<unknown>', mode="exec", **kwargs): | |
"""Parse the source and pretty-print the AST.""" | |
node = parse(source, filename, mode=mode) | |
print(dump(node, **kwargs)) | |
# Short name: pdp = parse, dump, print | |
pdp = parseprint | |
def load_ipython_extension(ip): | |
from IPython.core.magic import Magics, magics_class, line_cell_magic | |
@magics_class | |
class AstMagics(Magics): | |
@line_cell_magic | |
def astpp(self, line='', cell=None): | |
"""Parse the a python code or expression and pretty-print the AST. | |
Usage, in line mode: | |
%astpp statement | |
or in cell mode: | |
%%astpp | |
code | |
code... | |
Examples | |
-------- | |
:: | |
In [1]: %astpp pass | |
Module(body=[ | |
Pass(), | |
]) | |
In [2]: %astpp from ..main.app import foo as bar | |
Module(body=[ | |
ImportFrom(module='main.app', names=[ | |
alias(name='foo', asname='bar'), | |
], level=2), | |
]) | |
""" | |
opts, stmt = self.parse_options(line, '', posix=False, strict=False) | |
if stmt == '' and cell is None: | |
return | |
transform = self.shell.input_splitter.transform_cell | |
if cell is None: # called as line magic | |
ast_stmt = self.shell.compile.ast_parse(transform(stmt)) | |
else: | |
ast_stmt = self.shell.compile.ast_parse(transform(cell)) | |
self.shell.user_ns['_'] = ast_stmt | |
print(dump(ast_stmt)) | |
ip.register_magics(AstMagics) | |
if __name__ == '__main__': | |
import argparse | |
import sys | |
parser = argparse.ArgumentParser(description=__doc__) | |
parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), | |
default=sys.stdin) | |
args = parser.parse_args() | |
parseprint(args.infile.read(), filename=args.infile.name, include_attributes=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
from setuptools import setup | |
setup( | |
name='astpp', | |
version='0.1', | |
description="An IPython extension to pretty print python AST.", | |
py_modules=['astpp'], | |
license='MIT', | |
classifiers=( | |
"Development Status :: 4 - Beta", | |
'Intended Audience :: Developers', | |
'Natural Language :: English', | |
'License :: OSI Approved :: MIT', | |
'Programming Language :: Python', | |
'Programming Language :: Python :: 2.7', | |
'Programming Language :: Python :: 3.3', | |
'Programming Language :: Python :: 3.4', | |
'Environment :: Console', | |
'Framework :: IPython', | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment