Unravelling Python's syntactic sugar source code.
There are accompanying blog posts to go with all of the code in this repository.
obj.attr
➠builtins.getattr(obj, "attr")
(includingobject.__getattribute__()
)a + b
➠operator.__add__(a, b)
a - b
➠operator.__sub__(a, b)
a * b
➠operator.__mul__(a, b)
a @ b
➠operator.__matmul__(a, b)
a / b
➠operator.__truediv__(a, b)
a // b
➠operator.__floordiv__(a, b)
a % b
➠operator.__mod__(a, b)
a ** b
➠operator.__pow__(a, b)
a << b
➠operator.__lshift__(a, b)
a >> b
➠operator.__rshift__(a, b)
a & b
➠operator.__and__(a, b)
a ^ b
➠operator.__xor__(a, b)
a | b
➠operator.__or__(a, b)
a += b
➠a = operator.__iadd__(a, b)
a -= b
➠a = operator.__isub__(a, b)
a *= b
➠a = operator.__imul__(a, b)
a @= b
➠a = operator.__imatmul__(a, b)
a /= b
➠a = operator.__itruediv__(a, b)
a //= b
➠a = operator.__ifloordiv__(a, b)
a %= b
➠a = operator.__imod__(a, b)
a **= b
➠a = operator.__ipow__(a, b)
a <<= b
➠a = operator.__ilshift__(a, b)
a >>= b
➠a = operator.__irshift__(a, b)
a &= b
➠a = operator.__iand__(a, b)
a ^= b
➠a = operator.__ixor__(a, b)
a |= b
➠a = operator.__ior__(a, b)
~ a
➠operator.__invert__(a)
- a
➠operator.__neg__(a)
+ a
➠operator.__pos__(a)
a == b
➠operator.__eq__(a, b)
(includingobject.__eq__()
)a != b
➠operator.__ne__(a, b)
(includingobject.__ne__()
)a < b
➠operator.__lt__(a, b)
a <= b
➠operator.__le__(a, b)
a > b
➠operator.__gt__(a, b)
a >= b
➠operator.__ge__(a, b)
a is b
➠operator.is_(a, b)
a is not b
➠operator.is_not(a, b)
not a
➠operator.not_(a)
a in b
➠operator.__contains__(b, a)
a not in b
➠operator.not_(operator.__contains__(b, a))
a or b
➠_temp if (_temp := a) else b
a and b
➠_temp if not (_temp := a) else b
import a.b
➠a = __import__('a.b', globals(), locals())
import a.b as c
➠c = __import__('a', globals(), locals(), ['b'], 0).b
from .a import b
➠b = __import__('a', globals(), locals(), ['b'], 1).b
from .a import b as c
➠c = __import__('a', globals(), locals(), ['b'], 1).b
assert ...
➠ see belowfor ...
➠ see below (includingbuiltins.iter()
andbuiltins.next()
)pass
➠"pass"
with ...
➠ see belowasync def ...
➠ see belowawait ...
➠desugar.builtins._await(...)
assert a, b
➠
if __debug__:
if not a:
raise AssertionError(b)
assert a
➠
if __debug__:
if not a:
raise AssertionError
for a in b:
c
➠
_iter = iter(b)
while True:
try:
a = next(_iter)
except StopIteration:
break
else:
c
del _iter
for a in b:
c
else:
d
➠
_iter = iter(b)
_looping = True
while _looping:
try:
a = next(_iter)
except StopIteration:
_looping = False
continue
else:
c
else:
d
del _iter, _looping
with a as b:
c
➠
_enter = type(a).__enter__
_exit = type(a).__exit__
b = _enter(a)
try:
c
except:
if not _exit(a, *sys.exc_info()):
raise
else:
_exit(a, None, None, None)
async def spam():
...
➠
@types.coroutine
def spam():
...
Taken from the keyword
module.
-
class
~
Taken from the token
module.
-
[]
for list display * -
[]
for list comprehensions * -
[]
for subscriptions (get, set, del),:
for slicing * -
{}
for set display * -
{}
for set comprehensions * -
{}
for dictionary display * -
{}
for dictionary comprehensions * -
()
for tuple display * -
()
for calls -
@
for decorators * -
,
-
;
* -
...
*
The list below ignores literals which are represented via syntax above.
For instance, lists are ignored as they are represented by []
tokens.
None
False
True
- Bytes (
b
,r
) - Strings (
u
,f
,r
; single line, multi-line) - Integers (base-10,
b
,o
,x
) - Floats (point,
e
) - Complex/imaginary numbers