• Stars
    star
    134
  • Rank 270,967 (Top 6 %)
  • Language
    Python
  • License
    MIT License
  • Created over 4 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Unravelling Python source code

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.attr ➠ builtins.getattr(obj, "attr") (including object.__getattribute__())
  2. a + b ➠ operator.__add__(a, b)
  3. a - b ➠ operator.__sub__(a, b)
  4. a * b ➠ operator.__mul__(a, b)
  5. a @ b ➠ operator.__matmul__(a, b)
  6. a / b ➠ operator.__truediv__(a, b)
  7. a // b ➠ operator.__floordiv__(a, b)
  8. a % b ➠ operator.__mod__(a, b)
  9. a ** b ➠ operator.__pow__(a, b)
  10. a << b ➠ operator.__lshift__(a, b)
  11. a >> b ➠ operator.__rshift__(a, b)
  12. a & b ➠ operator.__and__(a, b)
  13. a ^ b ➠ operator.__xor__(a, b)
  14. a | b ➠ operator.__or__(a, b)
  15. a += b ➠ a = operator.__iadd__(a, b)
  16. a -= b ➠ a = operator.__isub__(a, b)
  17. a *= b ➠ a = operator.__imul__(a, b)
  18. a @= b ➠ a = operator.__imatmul__(a, b)
  19. a /= b ➠ a = operator.__itruediv__(a, b)
  20. a //= b ➠ a = operator.__ifloordiv__(a, b)
  21. a %= b ➠ a = operator.__imod__(a, b)
  22. a **= b ➠ a = operator.__ipow__(a, b)
  23. a <<= b ➠ a = operator.__ilshift__(a, b)
  24. a >>= b ➠ a = operator.__irshift__(a, b)
  25. a &= b ➠ a = operator.__iand__(a, b)
  26. a ^= b ➠ a = operator.__ixor__(a, b)
  27. a |= b ➠ a = operator.__ior__(a, b)
  28. ~ a ➠ operator.__invert__(a)
  29. - a ➠ operator.__neg__(a)
  30. + a ➠ operator.__pos__(a)
  31. a == b ➠ operator.__eq__(a, b) (including object.__eq__())
  32. a != b ➠ operator.__ne__(a, b) (including object.__ne__())
  33. a < b ➠ operator.__lt__(a, b)
  34. a <= b ➠ operator.__le__(a, b)
  35. a > b ➠ operator.__gt__(a, b)
  36. a >= b ➠ operator.__ge__(a, b)
  37. a is b ➠ operator.is_(a, b)
  38. a is not b ➠ operator.is_not(a, b)
  39. not a ➠ operator.not_(a)
  40. a in b ➠ operator.__contains__(b, a)
  41. a not in b ➠ operator.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.b ➠ a = __import__('a.b', globals(), locals())
  45. import a.b as c ➠ c = __import__('a', globals(), locals(), ['b'], 0).b
  46. from .a import b ➠ b = __import__('a', globals(), locals(), ['b'], 1).b
  47. from .a import b as c ➠ c = __import__('a', globals(), locals(), ['b'], 1).b
  48. assert ... ➠ see below (post)
  49. for ... ➠ see below (including builtins.iter() and builtins.next())
  50. pass ➠ "pass"
  51. with ... ➠ see below (post)
  52. async def ... ➠ see below (post)
  53. await ... ➠ desugar.builtins._await(...)
  54. async for ➠ see below (including builtins.aiter() and builtins.anext())
  55. async with ➠ see below (post)
  56. (c for b in a) ➠ see below (post)
  57. [c for b in a] ➠ list(c for b in a)
  58. {c for b in a} ➠ set(c for b in a)
  59. {c: d for b in a} ➠ dict((c, d) for b in a)
  60. [a, b] ➠ list((a, b)) (includes iterable unpacking)
  61. {a, b} ➠ set((a, b)) (includes iterable unpacking)
  62. (a, b)) ➠ (lambda *args: args)(a, b) (includes iterable unpacking)
  63. {a: b, c: d}) ➠ dict(((a, b), (c, d))) (include dictionary unpacking)
  64. @decorator ➠ see below (post)
  65. break ➠ see below (post)
  66. continue ➠ see below (post)
  67. else clause on while ➠ see below (post)
  68. elif and else clauses on if ➠ see below (post)
  69. else clause on try ➠ see below (post)
  70. finally clause on try ➠ see below (post)
  71. raise A from B ➠ see below (post)
  72. x[A, B] ➠ type(x).__getitem__(x, (A, B))
  73. x[A, B] = C ➠ type(x).__setitem__(x, (A, B), C)
  74. del x[A, B] ➠ type(x).__delitem__(x, (A, B))
  75. A:B:C ➠ slice(A, B, C)
  76. 4+3j ➠ complex(4, 3)
  77. True ➠ bool(1)
  78. False ➠ bool(0)
  79. None ➠ see below (post)
  80. b"ABC" ➠ bytes([65, 66, 67])
  81. "ABC" ➠ bytes([65, 66, 67]).decode("utf-8")
  82. ... ➠ Ellipsis
  83. class A: ... ➠ see below (post) . ;` ➠ newline plus proper indentation
  84. if ...: ... ➠ see below (post)
  85. a := b see the post
  86. lambda a: b ➠ see below (post)
  87. global A; A = 42 ➠ getattr(dict, "__setitem__")(globals(), "A", 42)
  88. del A ➠ see below (post)

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():
    ...

async for ...

Without else

async for a in b:
    c

➠

_iter = aiter(b)
while True:
    try:
        a = await anext(_iter)
    except StopAsyncIteration:
        break
    else:
        c
del _iter

With else

async for a in b:
    c
else:
    d

➠

_iter = aiter(b)
_looping = True
while _looping:
    try:
        a = await anext(_iter)
    except StopAsyncIteration:
        _looping = False
        continue
    else:
        c
else:
    d
del _iter, _looping

async with ...

async with a as b:
    c

➠

_enter = type(a).__aenter__
_exit = type(a).__aexit__
b = await _enter(a)

try:
    c
except:
    if not await _exit(a, *sys.exc_info()):
        raise
else:
    await _exit(a, None, None, None)

(c for b in a)

(c for b in a)

➠

def _gen_exp(_leftmost_iterable):
    for b in _leftmost_iterable:
        yield c

_gen_exp(a)

@decorator

@decorator
def func():
    ...

➠

def func():
    ...

_temp_func_name = func
del func

func = decorator(_temp_func_name)

break

while x:
    break

➠

class _BreakStatement(Exception):
    pass

try:
    while x:
        raise _BreakStatement
except BreakStatement:
    pass

continue

while x:
    continue

➠

class _ContinueStatement(Exception):
    pass

while x:
    try:
        raise _ContinueStatement
    except ContinueStatement:
        pass

else clause on a loop

while x:
    break
else:
    ...

➠

class _BreakStatement(Exception):
    pass

try:
    while x:
        raise _BreakStatement
except _BreakStatement:
    pass
else:
    ...

if

if A:
    B

➠

class _Done(Exception):
    pass

try:
    while A:
        B
        raise _Done
except _Done:
    pass

elif/else on an if statement

if A:
    B
elif C:
    D
else:
    E

➠

_B_ran = _D_ran = False
if A:
    _B_ran = True
    B
if not _B_ran and C:
    _D_ran = True
    D
if not (_B_ran or _D_ran):
    E

try

else

try:
    A
except:
    B
else:
    C

➠

_A_finished = False
try:
    A
    _A_finished = True
except:
    B
if _A_finished:
    C

finally

try:
    A
except Exception:
    B
finally:
    C

➠

try:
    try:
        A
    except Exception:
        B
except BaseException:
    C
    raise
C

raise A from B

raise A from B

➠

_raise = A
if isinstance(_raise, type) and issubclass(_raise, BaseException):
        _raise = _raise()
elif not isinstance(_raise, BaseException):
    raise TypeError("exceptions must derive from BaseException")

_from = B
if isinstance(_from, type) and issubclass(_from, BaseException):
        _from = _from()
if _from is not None:
    _raise.__cause__ = _from

raise _raise

None

None

➠

def _None():
    pass

_None()

class

class Example(SuperClass):
  """Docstring."""
  a: int = 3
  def c(self): return 42

➠

def _exec_Example(_ns):
    _temp_ns = {}

    _temp_ns["__module__"] = _ns["__module__"] = __name__
    _temp_ns[__"qualname__"] = _ns["__qualname__"] = "Example"
    _temp_ns["__doc__"] = _ns["__doc__"] = """Docstring."""
    _temp_ns["__annotations__"] = _ns["__annotations__"] = {"a": int}

    _temp_ns["a"] = _ns["a"] = 3

    def _method_c(self):
        return 42
    _method_c.__name__ = "c"
    _method_c.__qualname__ = "Example.c"
    temp_ns["c"] = _ns["c"] = _method_c
    del _method_c

def _class_Example():
    # Resolving MRO entries.
    bases = types.resolve_bases((SuperClass, ))
    # Determining the appropriate metaclass **and**
    # preparing the class namespace.
    meta, ns, kwds = types.prepare_class("Example", bases)
    # Executing the class body.
    _exec_Example(ns)
    # Creating the class object.
    cls = meta("Example", bases, ns)
    ## Class decorators, if there were any.
    ## Make the namespace read-only.
    cls.__dict__ = read_only_proxy(ns)

    return cls

 Example = _class_Example()

lambda

lambda A: B

➠

def _lambda(A):
    return B
_lambda.__name__ = "<lambda>"

del

del A

➠

Local

_DELETED = object()

# `del A`
A = _DELETED
# Referencing `A`
if A is _DELETED:
    raise UnboundLocalError("cannot access local variable 'A' where it is not associated with a value")

Global

try:
    gettattr(globals(), "__delitem__")("A")
except KeyError:
    raise NameError("name 'A' is not defined")

Syntax that can't be unravelled

Summary post

Keywords

Taken from the keyword module.

Nothing; all unravelled!

Expressions

  1. yield

Statements

  1. def

  2. nonlocal

  3. return

  4. try/except

  5. while

Tokens

Taken from the token module.

  1. =

  2. () for calls

  3. ,

Literals

  1. Integers

More Repositories

1

python-launcher

Python launcher for Unix
Rust
503
star
2

caniusepython3

Can I Use Python 3?
Python
414
star
3

gidgethub

An async GitHub API library for Python
Python
314
star
4

sans-io

Network protocol implementations in Python, sans I/O
Python
120
star
5

mousebender

Create reproducible installations for a virtual environment from a lock file
HTML
83
star
6

oplop

Generate account passwords based on a nickname and a master password
JavaScript
33
star
7

mnfy

Minify Python code
Python
28
star
8

pip-secure-install

Action to have pip install from a requirements file as securely as possible
27
star
9

stdlib-stats

Various statistics on Python's standard library
Jupyter Notebook
21
star
10

modutil

A library for working with Python modules
Python
19
star
11

free-labour

Calculate your open source contributions
Python
18
star
12

WWBD

The "What Would Brett Do?" VS Code extension
TypeScript
16
star
13

brettcannon

Python
13
star
14

find-duplicate-files

Find duplicate files recursively in one or more directories
Go
12
star
15

riscv-harmony

A RISC-V ISA simulator written in Rust
Rust
12
star
16

basicenum

Simple(r) enums
Python
12
star
17

dotfiles

Vim Script
8
star
18

check-for-changed-files

Action to check that PRs have changed certain files
TypeScript
8
star
19

release-often

GitHub Action for releasing a Python project to PyPI after every relevant, merged PR
Python
8
star
20

python-azure-web-app-cookiecutter

Cookiecutter template for a Python site on Azure Web Apps
Python
6
star
21

time-clock

A simple, one-page time/punch clock web app
Elm
4
star
22

vscode-zephyr-asdl

VS Code extension for the Zephyr Abstract Syntax Description Language
2
star
23

trips-history

Convert from a trip-oriented JSON format for easy inputting to GeoJSON for easy mapping
Dart
1
star
24

microvenv

A minimal re-implementation of Python's `venv` module
Python
1
star
25

travelbrag

Travelogue for Andrea & Brett
Jupyter Notebook
1
star
26

dotconfig

My collection of configuration files
Vim Script
1
star
27

nowhere-on-the-web

uBlock Origin filter list for "around the web"-style advertisers
1
star