20
@jargnar github.com/jargnar Hacking the Python AST

Hacking the Python AST

Embed Size (px)

Citation preview

Page 1: Hacking the Python AST

@jargnar

github.com/jargnar

Hacking the Python AST

Page 2: Hacking the Python AST

01010101010101010101010101...

Page 3: Hacking the Python AST

Aprimeroncompilingcomputerlanguages

Front end Middle end Back endC

JAVAARMx86

IR IR

Page 4: Hacking the Python AST

Intel’s developer manual

Page 5: Hacking the Python AST

Aprimeroncompilingcomputerlanguages

Front end Middle end Back endC

JAVAARMx86

IR IR

Page 6: Hacking the Python AST

@jargnar

github.com/jargnar

The Dragon Book

Page 7: Hacking the Python AST

Grammars

S –> ABA –> aA | εB –> b | bB

SAB S–>ABaAB A–>aAaaAB A–>aAaaaAB A–>aAaaaεB A–>εaaab B–>b

A parse of aaabDoes aaab belong to this Grammar?

Page 8: Hacking the Python AST

@jargnar

github.com/jargnar

LL(1) GrammarLeft-to-right scanLeftmost derivation

Page 9: Hacking the Python AST

@jargnar

github.com/jargnar

Let’stakeaquicklookatPython’sGrammar(Grammar/Grammar)

Page 10: Hacking the Python AST

DesignoftheCPython Compiler

Parser/pgen.c

Python/ast.c

Python/compile.c

Python/compile.c

Parse Tree

.pyfile

Byte code

AST CFG

Page 11: Hacking the Python AST

@jargnar

github.com/jargnar

dis

Page 12: Hacking the Python AST

DesignoftheCPython Compiler

Parser/pgen.c

Python/ast.c

Python/compile.c

Python/compile.c

Parse Tree

.pyfile

Byte code

AST CFG

Page 13: Hacking the Python AST

Pythontox86andthenthe01010101s

Parser/pgen.c

Python/ast.c

Python/compile.c

Python/compile.c

Parse Tree

.pyfile

Byte code

AST CFG

Python/ceval.c

Page 14: Hacking the Python AST

@jargnar

github.com/jargnar

Page 15: Hacking the Python AST

AccessingtheAST

a = 26b = 0print(a + b)

example.pyIn [1]: import ast

In [2]: source = open('example.py').read()

In [3]: tree = ast.parse(source)

Page 16: Hacking the Python AST

AccessingtheAST

a = 26b = 0print(a + b)

example.py

Module(body=[Expr(value=Str(s='Docstring')),Assign(

targets=[Name(id='a',ctx=Store())],

value=Num(n=26)),Assign(

targets=[Name(id='b',ctx=Store())],

value=Num(n=0)),Expr(value=Call(

func=Name(id='print',ctx=Load()),

args=[BinOp(left=Name(

id='a',ctx=Load()),

op=Add(),right=Name(

id='b',ctx=Load()))],

keywords=[]))])

Page 17: Hacking the Python AST

Havingalittlefun,now

In [3]: tree = ast.parse('x = 5')

In [4]:print(astunparse.dump(tree))Module(body=[Assign(

targets=[Name(id='x',ctx=Store())],

value=Num(n=5))])

In [5]: tree.body[0].targets[0].idOut[5]: 'x'

In [6]: astunparse.unparse(tree)

x = 5

In [7]:tree.body[0].targets[0].id = 'y'

In [8]:print(astunparse.unparse(tree))

y = 5

Page 18: Hacking the Python AST

@jargnar

github.com/jargnar

Let’sdoabsolutelysillythingswith

ast.NodeVisitorast.NodeTransformer

Page 19: Hacking the Python AST

@jargnar

github.com/jargnar

Evenmoresillythingswith

Flake8

Page 20: Hacking the Python AST

@jargnar

github.com/jargnar

Hacking is a mindset, not a skill.

suhas.org