Skip to content

0xaead/desugar

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

desugar

Unravelling Python's syntactic sugar source code.

There are accompanying blog posts to go with all of the code in this repository.

Unravelled syntax

  1. obj.attrbuiltins.getattr(obj, "attr") (including object.__getattribute__())
  2. a + boperator.__add__(a, b)
  3. a - boperator.__sub__(a, b)
  4. a * boperator.__mul__(a, b)
  5. a @ boperator.__matmul__(a, b)
  6. a / boperator.__truediv__(a, b)
  7. a // boperator.__floordiv__(a, b)
  8. a % boperator.__mod__(a, b)
  9. a ** boperator.__pow__(a, b)
  10. a << boperator.__lshift__(a, b)
  11. a >> boperator.__rshift__(a, b)
  12. a & boperator.__and__(a, b)
  13. a ^ boperator.__xor__(a, b)
  14. a | boperator.__or__(a, b)
  15. a += ba = operator.__iadd__(a, b)
  16. a -= ba = operator.__isub__(a, b)
  17. a *= ba = operator.__imul__(a, b)
  18. a @= ba = operator.__imatmul__(a, b)
  19. a /= ba = operator.__itruediv__(a, b)
  20. a //= ba = operator.__ifloordiv__(a, b)
  21. a %= ba = operator.__imod__(a, b)
  22. a **= ba = operator.__ipow__(a, b)
  23. a <<= ba = operator.__ilshift__(a, b)
  24. a >>= ba = operator.__irshift__(a, b)
  25. a &= ba = operator.__iand__(a, b)
  26. a ^= ba = operator.__ixor__(a, b)
  27. a |= ba = operator.__ior__(a, b)
  28. ~ aoperator.__invert__(a)
  29. - aoperator.__neg__(a)
  30. + aoperator.__pos__(a)
  31. a == boperator.__eq__(a, b) (including object.__eq__())
  32. a != boperator.__ne__(a, b) (including object.__ne__())
  33. a < boperator.__lt__(a, b)
  34. a <= boperator.__le__(a, b)
  35. a > boperator.__gt__(a, b)
  36. a >= boperator.__ge__(a, b)
  37. a is boperator.is_(a, b)
  38. a is not boperator.is_not(a, b)
  39. not aoperator.not_(a)
  40. a in boperator.__contains__(b, a)
  41. a not in boperator.not_(operator.__contains__(b, a))
  42. a or b_temp if (_temp := a) else b
  43. a and b_temp if not (_temp := a) else b
  44. import a.ba = __import__('a.b', globals(), locals())
  45. import a.b as cc = __import__('a', globals(), locals(), ['b'], 0).b
  46. from .a import bb = __import__('a', globals(), locals(), ['b'], 1).b
  47. from .a import b as cc = __import__('a', globals(), locals(), ['b'], 1).b
  48. assert ... ➠ see below
  49. for ... ➠ see below (including builtins.iter() and builtins.next())
  50. pass"pass"
  51. with ... ➠ see below
  52. async def ... ➠ see below
  53. await ...desugar.builtins._await(...)

assert ...

With message

assert a, b

if __debug__:
    if not a:
        raise AssertionError(b)

Without a message

assert a

if __debug__:
    if not a:
        raise AssertionError

for ...

Without else

for a in b:
    c

_iter = iter(b)
while True:
    try:
        a = next(_iter)
    except StopIteration:
        break
    else:
        c
del _iter

With else

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

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

async def spam():
    ...

@types.coroutine
def spam():
    ...

Syntax to (potentially) unravel

Keywords

Taken from the keyword module.

Expressions

  1. yield
  2. lambda

Statements

  1. break

  2. continue

  3. if/elif/else

  4. while/else

  5. async for/else *

  6. async with *

  7. def

  8. class ~

  9. try/except/else/finally

  10. global

  11. nonlocal

  12. del

  13. raise/from

  14. return

Tokens

Taken from the token module.

  1. =

  2. :=

  3. [] for list display *

  4. [] for list comprehensions *

  5. [] for subscriptions (get, set, del), : for slicing *

  6. {} for set display *

  7. {} for set comprehensions *

  8. {} for dictionary display *

  9. {} for dictionary comprehensions *

  10. () for tuple display *

  11. () for calls

  12. @ for decorators *

  13. ,

  14. ; *

  15. ... *

The list below ignores literals which are represented via syntax above. For instance, lists are ignored as they are represented by [] tokens.

  1. None
  2. False
  3. True
  4. Bytes (b, r)
  5. Strings (u, f, r; single line, multi-line)
  6. Integers (base-10, b, o, x)
  7. Floats (point, e)
  8. Complex/imaginary numbers

About

Unravelling Python source code

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Python 100.0%