Python is Magic

From Esolang
Jump to navigation Jump to search

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))