Skip to content

Instantly share code, notes, and snippets.

@erikbern
Last active April 3, 2022 21:35
Show Gist options
  • Save erikbern/ad7615d22b700e8dbbafd8e4d2f335e1 to your computer and use it in GitHub Desktop.
Save erikbern/ad7615d22b700e8dbbafd8e4d2f335e1 to your computer and use it in GitHub Desktop.

Revisions

  1. erikbern revised this gist Mar 25, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion loop_hack.py
    Original file line number Diff line number Diff line change
    @@ -33,7 +33,7 @@ def thing_interceptor(coro):
    # and still make it possible to interact back with a sort of
    # "context", which in this case is a very silly thing that just
    # resolves Thing(n) to n, but in theory could be something a
    # lot more compelx
    # lot more complex
    async def f(n):
    if n <= 1:
    value = await Thing(n)
  2. erikbern revised this gist Mar 25, 2022. 1 changed file with 19 additions and 1 deletion.
    20 changes: 19 additions & 1 deletion loop_hack.py
    Original file line number Diff line number Diff line change
    @@ -1,21 +1,39 @@
    # First, let's create an awaitable object.
    # In this case it's a very dumb container of integers.
    # Any time a coroutine runs `await Thing(n)` it just resolves to n
    # However, we could resolve it to something completely different if we wanted to

    class Thing:
    def __init__(self, n):
    self._n = n

    def __await__(self):
    return (yield self)


    # Simple runner of the coroutine, which ignores a bunch of
    # things like error handling etc.
    def thing_interceptor(coro):
    value_to_send = None
    while True:
    try:
    thing = coro.send(value_to_send)
    # At this point, we assume everything we get back
    # is a Thing object. But we could actually accept
    # asyncio coroutines here if we wanted to, and relay
    # them to the event loop. This would make it possible
    # for the coroutine to use anything in asyncio
    # (eg asyncio.sleep)
    value_to_send = thing._n
    except StopIteration as exc:
    return exc.value


    # This is just the standard recursive Fibonacci definition
    # It serves the purpose of how you can have a deep call stack
    # and still make it possible to interact back with a sort of
    # "context", which in this case is a very silly thing that just
    # resolves Thing(n) to n, but in theory could be something a
    # lot more compelx
    async def f(n):
    if n <= 1:
    value = await Thing(n)
  3. erikbern created this gist Mar 25, 2022.
    28 changes: 28 additions & 0 deletions loop_hack.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,28 @@
    class Thing:
    def __init__(self, n):
    self._n = n

    def __await__(self):
    return (yield self)


    def thing_interceptor(coro):
    value_to_send = None
    while True:
    try:
    thing = coro.send(value_to_send)
    value_to_send = thing._n
    except StopIteration as exc:
    return exc.value


    async def f(n):
    if n <= 1:
    value = await Thing(n)
    else:
    value = await f(n-2) + await f(n-1)
    return value


    coro = f(10)
    print(thing_interceptor(coro))