66 lines
1.6 KiB
Markdown
Raw Normal View History

2024-12-04 20:45:33 +00:00
# AsyncPatch
# A mixin written by me to use to enable async on all your non async classes! It's not only a patch to use it but actually really executes the code in the event loop!
## How to use
```python
# (C) retoor 2024-12-01
import os
import AsyncioPatch from asyncio_patch.py
# Non async traditional class.
class Reader:
def readline(self):
return os.stdin.readline()
# Extend the class with the mixin.
class AsyncReader(Reader, AsyncioPatch):
pass
# Use it for blocking code.
async def main():
reader = AsyncReader()
# method 1
print(await reader.areadline())
# method 2
print(await reader.readline_async())
asyncio.run(main())
```
## Source code
```python
import asyncio
class AsyncioPatch:
def __getattr__(self, name):
if name.endswith("_async"):
name = name.split("_async")[0]
elif name.startswith("a"):
name = name[1:]
else:
return self.__dict__.get(name, None)
return self.patch_async(getattr(self, name))
def patch_async(self, method, *args, **kwargs):
async def patched_async(*args, **kwargs):
loop = asyncio.get_running_loop()
import functools
patched_call = functools.partial(method, *args, **kwargs)
return await loop.run_in_executor(None, patched_call)
return patched_async
async def __aenter__(self):
fn = self.patch_async(self.__enter__)
return await fn()
async def __aexit__(self, *args, **kwargs):
fn = self.patch_async(self.__exit__,*args, **kwargs)
return await fn()
```