@@ -52,53 +52,53 @@ If you'd like your library to be detected by ``sniffio``, it's pretty
5252easy.
5353
5454**Step 1: ** Pick the magic string that will identify your library. To
55- avoid collisions, this should match your library's name on PyPI.
55+ avoid collisions, this should match your library's PEP 503 normalized name on PyPI.
5656
57- **Step 2: ** There's a special :class: `contextvars.ContextVar ` object:
57+ **Step 2: ** There's a special :class: `threading.local ` object:
5858
59- .. data :: current_async_library_cvar
59+ .. data :: thread_local.name
6060
61- Make sure that whenever your library is running, this is set to your
62- identifier string. In most cases, this will be as simple as:
61+ Make sure that whenever your library is calling a coroutine `` throw() ``, `` send() ``, or `` close() ``
62+ that this is set to your identifier string. In most cases, this will be as simple as:
6363
6464.. code-block :: python3
6565
66- from sniffio import current_async_library_cvar
66+ from sniffio import thread_local
6767
68- # Your library's run function
69- def run (...):
70- token = current_async_library_cvar.set( "my-library's-PyPI-name")
68+ # Your library's step function
69+ def step (...):
70+ old_name, thread_local.name = thread_local.name, "my-library's-PyPI-name"
7171 try:
72- # The actual body of your run() function:
73- ...
72+ result = coro.send(None)
7473 finally:
75- current_async_library_cvar.reset(token)
74+ thread_local.name = old_name
7675
7776 **Step 3: ** Send us a PR to add your library to the list of supported
7877libraries above.
7978
8079That's it!
8180
82- Notes:
81+ There are libraries that directly drive a sniffio-naive coroutine from another,
82+ outer sniffio-aware coroutine such as `trio_asyncio `.
83+ These libraries should make sure to set the correct value
84+ while calling a synchronous function that will go on to drive the
85+ sniffio-naive coroutine.
8386
84- On older Pythons without native contextvars support, sniffio
85- transparently uses `the official contextvars backport
86- <https://pypi.org/project/contextvars/> `__, so you don't need to worry
87- about that.
8887
89- There are libraries that can switch back and forth between different
90- async modes within a single call-task – like ``trio_asyncio `` or
91- Twisted's asyncio operability. These libraries should make sure to set
92- the value back and forth at appropriate points.
88+ .. code-block :: python3
89+
90+ from sniffio import thread_local
9391
94- The general rule of thumb: :data: `current_async_library_cvar ` should
95- be set to X exactly at those moments when ``await X.sleep(...) `` will
96- work.
92+ # Your library's compatibility loop
93+ async def main_loop(self, ...) -> None:
94+ ...
95+ handle: asyncio.Handle = await self.get_next_handle()
96+ old_name, thread_local.name = thread_local.name, "asyncio"
97+ try:
98+ result = handle._callback(obj._args)
99+ finally:
100+ thread_local.name = old_name
97101
98- .. warning :: You shouldn't attempt to read the value of
99- ``current_async_library_cvar `` directly –
100- :func: `current_async_library ` has a little bit more cleverness than
101- that.
102102
103103 .. toctree ::
104104 :maxdepth: 1
0 commit comments