Skip to content

Instantly share code, notes, and snippets.

@decentral1se
Last active January 17, 2020 12:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save decentral1se/579f9cda4ef3913fa8006cd4e96a40ba to your computer and use it in GitHub Desktop.
Save decentral1se/579f9cda4ef3913fa8006cd4e96a40ba to your computer and use it in GitHub Desktop.
example memory channel context usage
# 1 (ain't working, weird usage anyway)
>>> async def main():
... incoming = open_memory_channel(15)
... async with incoming:
... await incoming[0].send(b'aaaa')
...
>>> run(main)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/decentral1se/work/datpy/hypercore-protocol/.venv/lib/python3.8/site-packages/trio/_core/_run.py", line 1804, in run
raise runner.main_task_outcome.error
File "<stdin>", line 3, in main
AttributeError: __aexit__
# 2 (ain't working, more reasonable)
>>> async def main():
... async with open_memory_channel(15) as left, right:
... await left.send(b'aaa')
...
>>> run(main)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/decentral1se/work/datpy/hypercore-protocol/.venv/lib/python3.8/site-packages/trio/_core/_run.py", line 1804, in run
raise runner.main_task_outcome.error
File "<stdin>", line 2, in main
AttributeError: __aexit__
# 3 (works)
>>> from trio import *
>>> async def main():
... left, right = open_memory_channel(15)
... async with left, right:
... await left.send(b'aaa')
...
>>> run(main)
@decentral1se
Copy link
Author

decentral1se commented Jan 17, 2020

Outcome of the working usage is that if I want to use two channels, incoming and outgoing, I need to do:

    in_send, out_recv = open_memory_channel(0)
    out_send, out_recv = open_memory_channel(0)

    async with in_send, out_recv, out_send, out_recv:
        pass  # do stuff with the channels

Right? That feels a bit cumbersome at the moment but can work!

@decentral1se
Copy link
Author

decentral1se commented Jan 17, 2020

I would like to see that option 2 could work so that I can write objects that have the following interface:

class P:
    incoming: Tuple[MemorySendChannel, MemoryReceiveChannel]
    outgoing: Tuple[MemorySendChannel, MemoryReceiveChannel]

But instead, I need to (following the logic of breaking up the tuple to use in the context manager):

class P:
    in_send: MemorySendChannel
    in_recv: MemoryReceiveChannel

    out_send: MemorySendChannel
    out_recv: MemoryReceiveChannel

Or? This is only for the case where I want to instantiate the channel context outside of the P object. I'm doing this because I also instantiate my stream context externally of the object (so I can do P(stream=stream)) and so want to also follow this logic of composition with the channels.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment