Python is Magic
Python is Magic is a very restricted version of Python 3. On Python is Magic, only magic functions can be used.
Warm-up
This is a valid Python is Magic code:
__name__.__class__.__name__.__len__().__sub__(__name__.__class__.__name__.__len__())
That's good, but not pretty. To prettify it, you can remove the underscores:
name.class.name.len().sub(name.class.name.len())
It will result in the same code as above.
Literals, normal if-else, declaring classes normally, anything that is not magic functions are not allowed in Python is Magic. Other than that, it's just an unmodified Python 3.
Programming in Python is Magic
Constants
Here are some example constants of Python is Magic. A more complete list of constants can be found at Python is Magic/Constants.
Constant | Code |
---|---|
False |
__doc__.__bool__()
|
True |
__doc__.__eq__(__doc__)
|
1 |
__doc__.__eq__(__doc__).__int__()
|
7 |
__doc__.__dir__.__name__.__len__()
|
a |
__name__.__getitem__(__name__.__class__.__name__.__len__()) or __doc__.__bool__().__str__().__getitem__(__name__.__len__().__bool__())
|
() |
__name__.__getnewargs__().__class__()
|
[] |
__doc__.__dir__().__class__()
|
Variables
You can use __builtins__.__setattr__
to store data. For example, this sets __x__
to 1
:
__builtins__.__setattr__(__name__.__iter__().__next__().__add__(__name__.__iter__().__next__()).__add__(__doc__.__reduce_ex__.__name__.__getitem__(__doc__.__sizeof__.__name__.__len__())).__add__(__name__.__iter__().__next__()).__add__(__name__.__iter__().__next__()),__name__.__len__().__bool__().__int__())
Example codes
Hello, world!
__builtins__.__getattribute__(__doc__.__class__.__name__.__getitem__(__doc__.__le__.__name__.__len__()).__add__(__doc__.__repr__.__name__.__getitem__(__doc__.__bool__().__str__().__len__())).__add__(__name__.__len__().__class__.__name__))(__builtins__.__getattribute__(__name__.__doc__.__getitem__(__name__.__len__()).__add__(__doc__.__hash__.__name__.__getitem__(__doc__.__bool__().__str__().__len__())).__add__(__doc__.__repr__.__name__.__getitem__(__doc__.__bool__().__str__().__len__())))(__name__.__len__().__mul__(__name__.__len__().__invert__().__neg__())).__add__(__doc__.__str__().__getitem__(__name__.__class__.__name__.__len__())).__add__(__doc__.__bool__.__name__.__getitem__(__doc__.__bool__().__str__().__len__())).__add__(__doc__.__bool__.__name__.__getitem__(__doc__.__bool__().__str__().__len__())).__add__(__doc__.__str__().__getitem__(__name__.__len__().__bool__())).__add__(__doc__.__dir__().__str__().__getitem__(__doc__.__sizeof__.__name__.__len__())).__add__(__builtins__.__doc__.__getitem__(__name__.__len__())).__add__(__builtins__.__getattribute__(__name__.__doc__.__getitem__(__name__.__len__()).__add__(__doc__.__hash__.__name__.__getitem__(__doc__.__bool__().__str__().__len__())).__add__(__doc__.__repr__.__name__.__getitem__(__doc__.__bool__().__str__().__len__())))(__doc__.__setattr__.__name__.__len__().__mul__(__name__.__len__()).__neg__().__invert__())).__add__(__doc__.__str__().__getitem__(__name__.__len__().__bool__())).__add__(__doc__.__repr__.__name__.__getitem__(__doc__.__bool__().__str__().__len__())).__add__(__doc__.__bool__.__name__.__getitem__(__doc__.__bool__().__str__().__len__())).__add__(__name__.__mod__.__name__.__getitem__(__doc__.__str__().__len__())).__add__(__doc__.__ne__.__doc__.__getitem__(__doc__.__setattr__.__name__.__len__())))
Implementation
The following is a basic implementation of Python is Magic:
import re, sys allowed = r"A-Za-z().,_" regex = r"(?:__)?([{}]+)(?:__)?".format(allowed) banned = r"[^{}]".format(allowed) script = open(sys.argv[1]).read() if re.findall(banned, script): raise SyntaxError("Only letters, parenthesis, dot and underscore are allowed.") exec(re.sub(regex,r"__\1__",script))