replacing `import` with `accio`

92
replacing import with accio

Upload: amy-hanlon

Post on 03-Jul-2015

253 views

Category:

Technology


5 download

DESCRIPTION

Replacing `import` with `accio`! Compiling Pythons with Custom Grammar for the sake of a joke! In Python, overwriting builtin functions is fairly easy. You can even do it in the interpreter! But can you overwrite a statement, like import, just as easily? Let's go on an adventure, discovering how the import statement works, and how Python statements are defined in the CPython source code. We'll face some consequences of bootstrapping, and, to get our custom Harry Potter-themed Grammar to work, we'll have to compile a Python to compile a Python.

TRANSCRIPT

Page 1: replacing `import` with `accio`

replacing import with accio

Page 2: replacing `import` with `accio`

muggle python

Page 3: replacing `import` with `accio`

>>> import random!

!

>>> random.random()!

0.18660693012691754!

!

>>> accio random!

File "<stdin>", line 1!

accio random!

^!

SyntaxError: invalid syntax

Page 4: replacing `import` with `accio`

>>> import random!

!

>>> random.random()!

0.18660693012691754!

!

>>> accio random!

File "<stdin>", line 1!

accio random!

^!

SyntaxError: invalid syntax

Page 5: replacing `import` with `accio`

>>> import random!

!

>>> random.random()!

0.18660693012691754!

!

>>> accio random!

File "<stdin>", line 1!

accio random!

^!

SyntaxError: invalid syntax

Page 6: replacing `import` with `accio`

>>> import random!

!

>>> random.random()!

0.18660693012691754!

!

>>> accio random!

File "<stdin>", line 1!

accio random!

^!

SyntaxError: invalid syntax

Page 7: replacing `import` with `accio`

>>> import random!

!

>>> random.random()!

0.18660693012691754!

!

>>> accio random!

File "<stdin>", line 1!

accio random!

^!

SyntaxError: invalid syntax

Page 8: replacing `import` with `accio`

nagini

Page 9: replacing `import` with `accio`

>>> accio random!! ! # no error!

!

>>> random.random()!

0.18660693012691754!

!

>>> import random!

File "<stdin>", line 1!

import random!

^!

SyntaxError: invalid syntax

Page 10: replacing `import` with `accio`

>>> accio random!! ! # no error!

!

>>> random.random()!

0.18660693012691754!

!

>>> import random!

File "<stdin>", line 1!

import random!

^!

SyntaxError: invalid syntax

Page 11: replacing `import` with `accio`

>>> accio random!! ! # no error!

!

>>> random.random()!

0.18660693012691754!

!

>>> import random!

File "<stdin>", line 1!

import random!

^!

SyntaxError: invalid syntax

Page 12: replacing `import` with `accio`

>>> accio random!! ! # no error!

!

>>> random.random()!

0.18660693012691754!

!

>>> import random!

File "<stdin>", line 1!

import random!

^!

SyntaxError: invalid syntax

Page 13: replacing `import` with `accio`

>>> accio random!! ! # no error!

!

>>> random.random()!

0.18660693012691754!

!

>>> import random!

File "<stdin>", line 1!

import random!

^!

SyntaxError: invalid syntax

Page 14: replacing `import` with `accio`

__builtins__!import!Grammar!

bootstrapping

Page 15: replacing `import` with `accio`

__builtins__!import!Grammar!

bootstrapping

Page 16: replacing `import` with `accio`

>>> __builtins__!

<module '__builtin__' (built-in)>!

!

>>> dir(__builtins__)!

[‘ArithmeticError’,…,’__import__’,…,’float’,…,’zip']

Page 17: replacing `import` with `accio`

>>> __builtins__!

<module '__builtin__' (built-in)>!

!

>>> dir(__builtins__)!

[‘ArithmeticError’,…,’__import__’,…,’float’,…,’zip']

Page 18: replacing `import` with `accio`

>>> __builtins__!

<module '__builtin__' (built-in)>!

!

>>> dir(__builtins__)!

[‘ArithmeticError’,…,’__import__’,…,’float’,…,’zip']

Page 19: replacing `import` with `accio`

>>> __builtins__!

<module '__builtin__' (built-in)>!

!

>>> dir(__builtins__)!

[‘ArithmeticError’,…,’__import__’,…,’float’,…,’zip']

Page 20: replacing `import` with `accio`

we can shadow builtins!

Page 21: replacing `import` with `accio`

>>> float(3)!

3.0!

!

>>> wingardium_leviosa = __builtins__.float!

!

>>> wingardium_leviosa(3)!

3.0

Page 22: replacing `import` with `accio`

>>> float(3)!

3.0!

!

>>> wingardium_leviosa = __builtins__.float!

!

>>> wingardium_leviosa(3)!

3.0

Page 23: replacing `import` with `accio`

>>> float(3)!

3.0!

!

>>> wingardium_leviosa = __builtins__.float!

!

>>> wingardium_leviosa(3)!

3.0

Page 24: replacing `import` with `accio`

>>> float(3)!

3.0!

!

>>> wingardium_leviosa = __builtins__.float!

!

>>> wingardium_leviosa(3)!

3.0

Page 25: replacing `import` with `accio`

>>> float(3)!

3.0!

!

>>> wingardium_leviosa = __builtins__.float!

!

>>> wingardium_leviosa(3)!

3.0

Page 26: replacing `import` with `accio`

we can delete builtins!

Page 27: replacing `import` with `accio`

>>> del __builtins__.float!

!

>>> float(3)!

Traceback (most recent call last):!

File "<stdin>", line 1, in <module>!

NameError: name 'float' is not defined!

!

>>> wingardium_leviosa(3)!

3.0

Page 28: replacing `import` with `accio`

>>> del __builtins__.float!

!

>>> float(3)!

Traceback (most recent call last):!

File "<stdin>", line 1, in <module>!

NameError: name 'float' is not defined!

!

>>> wingardium_leviosa(3)!

3.0

Page 29: replacing `import` with `accio`

>>> del __builtins__.float!

!

>>> float(3)!

Traceback (most recent call last):!

File "<stdin>", line 1, in <module>!

NameError: name 'float' is not defined!

!

>>> wingardium_leviosa(3)!

3.0

Page 30: replacing `import` with `accio`

>>> del __builtins__.float!

!

>>> float(3)!

Traceback (most recent call last):!

File "<stdin>", line 1, in <module>!

NameError: name 'float' is not defined!

!

>>> wingardium_leviosa(3)!

3.0

Page 31: replacing `import` with `accio`

>>> del __builtins__.float!

!

>>> float(3)!

Traceback (most recent call last):!

File "<stdin>", line 1, in <module>!

NameError: name 'float' is not defined!

!

>>> wingardium_leviosa(3)!

3.0

Page 32: replacing `import` with `accio`

__builtins__!import!Grammar!

bootstrapping

Page 33: replacing `import` with `accio`

can we shadow import?

Page 34: replacing `import` with `accio`

>>> accio = import!

File "<stdin>", line 1!

accio = import!

^!

SyntaxError: invalid syntax

Page 35: replacing `import` with `accio`

>>> accio = import!

File "<stdin>", line 1!

accio = import!

^!

SyntaxError: invalid syntax

Page 36: replacing `import` with `accio`

:(

Page 37: replacing `import` with `accio`

can we delete import?

Page 38: replacing `import` with `accio`

>>> del import!

File "<stdin>", line 1!

del = import!

^!

SyntaxError: invalid syntax

Page 39: replacing `import` with `accio`

>>> del import!

File "<stdin>", line 1!

del = import!

^!

SyntaxError: invalid syntax

Page 40: replacing `import` with `accio`

:(

Page 41: replacing `import` with `accio`

__import__

Page 42: replacing `import` with `accio`

>>> dir(__builtins__)!

[‘ArithmeticError’,…,’__import__’,…,’float’,…,’zip’]!

!

>>> __builtins__.__import__!

<built-in function __import__>

Page 43: replacing `import` with `accio`

>>> dir(__builtins__)!

[‘ArithmeticError’,…,’__import__’,…,’float’,…,’zip’]!

!

>>> __builtins__.__import__!

<built-in function __import__>

Page 44: replacing `import` with `accio`

>>> dir(__builtins__)!

[‘ArithmeticError’,…,’__import__’,…,’float’,…,’zip’]!

!

>>> __builtins__.__import__!

<built-in function __import__>

Page 45: replacing `import` with `accio`

>>> dir(__builtins__)!

[‘ArithmeticError’,…,’__import__’,…,’float’,…,’zip’]!

!

>>> __builtins__.__import__!

<built-in function __import__>

Page 46: replacing `import` with `accio`

>>> __builtins__.__import__(random)!

Traceback (most recent call last):!

File "<stdin>", line 1, in <module>!

NameError: name 'random' is not defined!

!

>>> __builtins__.__import__(‘random’)!

<module 'random' from ‘/usr/local/…/random.pyc’>

Page 47: replacing `import` with `accio`

>>> __builtins__.__import__(random)!

Traceback (most recent call last):!

File "<stdin>", line 1, in <module>!

NameError: name 'random' is not defined!

!

>>> __builtins__.__import__(‘random’)!

<module 'random' from ‘/usr/local/…/random.pyc’>

Page 48: replacing `import` with `accio`

>>> __builtins__.__import__(random)!

Traceback (most recent call last):!

File "<stdin>", line 1, in <module>!

NameError: name 'random' is not defined!

!

>>> __builtins__.__import__(‘random’)!

<module 'random' from ‘/usr/local/…/random.pyc’>

Page 49: replacing `import` with `accio`

>>> __builtins__.__import__(random)!

Traceback (most recent call last):!

File "<stdin>", line 1, in <module>!

NameError: name 'random' is not defined!

!

>>> __builtins__.__import__(‘random’)!

<module 'random' from ‘/usr/local/…/random.pyc’>

Page 50: replacing `import` with `accio`

>>> random = __builtins__.__import__(‘random’)!

!

>>> random.random()!

0.05857571707711129

Page 51: replacing `import` with `accio`

>>> random = __builtins__.__import__(‘random’)!

!

>>> random.random()!

0.05857571707711129

Page 52: replacing `import` with `accio`

>>> random = __builtins__.__import__(‘random’)!

!

>>> random.random()!

0.05857571707711129

Page 53: replacing `import` with `accio`

can we shadow __import__?

Page 54: replacing `import` with `accio`

>>> accio = __builtins__.__import__!

!

>>> random = accio(‘random’)!

!

>>> random.random()!

0.8735934644377295

Page 55: replacing `import` with `accio`

>>> accio = __builtins__.__import__!

!

>>> random = accio(‘random’)!

!

>>> random.random()!

0.8735934644377295

Page 56: replacing `import` with `accio`

>>> accio = __builtins__.__import__!

!

>>> random = accio(‘random’)!

!

>>> random.random()!

0.8735934644377295

Page 57: replacing `import` with `accio`

>>> accio = __builtins__.__import__!

!

>>> random = accio(‘random’)!

!

>>> random.random()!

0.8735934644377295

Page 58: replacing `import` with `accio`

can we delete __import__?

Page 59: replacing `import` with `accio`

>>> del __builtins__.__import__!

!

>>> random = accio(‘random’)!

Traceback (most recent call last):!

File "<stdin>", line 1, in <module>!

File “/usr/local/…/random.py”, line 42, in <module>!

from __future__ import division!

ImportError: __import__ not found

Page 60: replacing `import` with `accio`

>>> del __builtins__.__import__!

!

>>> random = accio(‘random’)!

Traceback (most recent call last):!

File "<stdin>", line 1, in <module>!

File “/usr/local/…/random.py”, line 42, in <module>!

from __future__ import division!

ImportError: __import__ not found

Page 61: replacing `import` with `accio`

>>> del __builtins__.__import__!

!

>>> random = accio(‘random’)!

Traceback (most recent call last):!

File "<stdin>", line 1, in <module>!

File “/usr/local/…/random.py”, line 42, in <module>!

from __future__ import division!

ImportError: __import__ not found

Page 62: replacing `import` with `accio`

`import x` is a statement

Page 63: replacing `import` with `accio`

__builtins__!import!Grammar!

bootstrapping

Page 64: replacing `import` with `accio`

clone cpython!

Page 65: replacing `import` with `accio`

$ ls -d cpython/*/!

Doc/!! ! ! ! Objects/!

Grammar/!! ! PC/!

Include/!! ! PCbuild/!

Lib/!! ! ! ! Parser/!

Mac/!! ! ! ! Python/!

Misc/!! ! ! Tools/!

Modules/

Page 66: replacing `import` with `accio`

$ ls -d cpython/*/!

Doc/!! ! ! ! Objects/!

Grammar/!! ! PC/!

Include/!! ! PCbuild/!

Lib/!! ! ! ! Parser/!

Mac/!! ! ! ! Python/!

Misc/!! ! ! Tools/!

Modules/

Page 67: replacing `import` with `accio`

$ ls -d cpython/*/!

Doc/!! ! ! ! Objects/!

Grammar/!! ! PC/!

Include/!! ! PCbuild/!

Lib/!! ! ! ! Parser/!

Mac/!! ! ! ! Python/!

Misc/!! ! ! Tools/!

Modules/

Page 68: replacing `import` with `accio`

import_stmt: import_name | !

! ! import_from!

import_name: 'import' dotted_as_names!

import_from: ('from' (‘.'* !

! ! dotted_name | '.'+)'import' (‘*'!

! ! | '(' import_as_names ')' | !

! ! import_as_names))

Page 69: replacing `import` with `accio`

import_stmt: import_name | !

! ! import_from!

import_name: 'import' dotted_as_names!

import_from: ('from' (‘.'* !

! ! dotted_name | '.'+)'import' (‘*'!

! ! | '(' import_as_names ')' | !

! ! import_as_names))

Page 70: replacing `import` with `accio`

import_stmt: import_name | !

! ! import_from!

import_name: 'import' dotted_as_names!

import_from: ('from' (‘.'* !

! ! dotted_name | '.'+)'import' (‘*'!

! ! | '(' import_as_names ')' | !

! ! import_as_names))

Page 71: replacing `import` with `accio`

import_name: !

! import matplotlib.pyplot as plt!

!

import_from:!

! from matplotlib import pyplot as plt

Page 72: replacing `import` with `accio`

import_name: !

! import matplotlib.pyplot as plt!

!

import_from:!

! from matplotlib import pyplot as plt

Page 73: replacing `import` with `accio`

import_stmt: import_name | !

! ! import_from!

import_name: 'import' dotted_as_names!

import_from: ('from' (‘.'* !

! ! dotted_name | ‘.'+) 'import' (‘*'!

! ! | '(' import_as_names ')' | !

! ! import_as_names))

Page 74: replacing `import` with `accio`

import_stmt: import_name | !

! ! import_from!

import_name: 'accio' dotted_as_names!

import_from: ('from' (‘.'* !

! ! dotted_name | ‘.'+) 'accio' (‘*'!

! ! | '(' import_as_names ')' | !

! ! import_as_names))

Page 75: replacing `import` with `accio`

$ make!

Traceback (most recent call last):!

…!

File “/…/cpython/Lib/sysconfig.py”, line 4!

import sys!

^!

SyntaxError: invalid syntax

Page 76: replacing `import` with `accio`

$ make!

Traceback (most recent call last):!

…!

File “/…/cpython/Lib/sysconfig.py”, line 4!

import sys!

^!

SyntaxError: invalid syntax

Page 77: replacing `import` with `accio`

half of cpython is written in python!

Page 78: replacing `import` with `accio`

$ (script that replaces `import` with `accio` in all .py files)!

!

$ make!

Traceback (most recent call last):!

…!

accio sys!

^!

SyntaxError: invalid syntax

Page 79: replacing `import` with `accio`

$ (script that replaces `import` with `accio` in all .py cpython files)!

!

$ make!

Traceback (most recent call last):!

…!

accio sys!

^!

SyntaxError: invalid syntax

Page 80: replacing `import` with `accio`

$ (script that replaces `import` with `accio` in all .py cpython files)!

!

$ make!

Traceback (most recent call last):!

…!

accio sys!

^!

SyntaxError: invalid syntax

Page 81: replacing `import` with `accio`

wat!

Page 82: replacing `import` with `accio`

__builtins__!import!Grammar!

bootstrapping

Page 83: replacing `import` with `accio`

import_stmt: import_name | !

! ! import_from!

import_name: 'import' dotted_as_names!

import_from: ('from' (‘.'* !

! ! dotted_name | '.'+)'import' (‘*'!

! ! | '(' import_as_names ')' | !

! ! import_as_names))

Page 84: replacing `import` with `accio`

import_stmt: import_name | !

! ! import_from!

import_name: 'import' dotted_as_names!

import_from: ('from' (‘.'* !

! ! dotted_name | '.'+)'import' (‘*'!

! ! | '(' import_as_names ')' | !

! ! import_as_names))

Page 85: replacing `import` with `accio`

import_name: 'import' dotted_as_names!

! ! | 'accio' dotted_as_names

Page 86: replacing `import` with `accio`

import_name: 'import' dotted_as_names!

! ! | 'accio' dotted_as_names

Page 87: replacing `import` with `accio`

$ make!

!

$ ./python!

!

>>> accio random!! ! # no errors!!

!

>>> import sys!! ! ! # no errors :(

Page 88: replacing `import` with `accio`

$ make!

!

$ ./python!

!

>>> accio random!! ! # no errors!!

!

>>> import sys!! ! ! # no errors :(

Page 89: replacing `import` with `accio`

$ make!

!

$ ./python!

!

>>> accio random!! ! # no errors!!

!

>>> import sys!! ! ! # no errors :(

Page 90: replacing `import` with `accio`

$ make!

!

$ ./python!

!

>>> accio random!! ! # no errors!!

!

>>> import sys!! ! ! # no errors :(

Page 91: replacing `import` with `accio`

yo dawg I heard you like pythons

Page 92: replacing `import` with `accio`

fin