Commit 6ea47ca
committed
2.8.0 - Refactoring, bug fixes + new loop_run function
**Tl;Dr; important changes**
- Added asyncx functions: `loop_run`, `is_async_context`, `_awaitable_blacklisted`
- Added asyncx decorator `awaitable_class`, and mixin class `AwaitableMixin` (mixin version of awaitable_class decorator)
- Removed class `helpers.extras.git.Git` and replaced it with an alias to `AsyncGit` as `@awaitable_class` rendered the
wrapper class obsolete
- Refactored some types from `common` module into `types`
- Refactored tests and added some new tests for some of the added functions/classes
- Various refactoring and general cleanup
**New Features / Additions**
- `asyncx.loop_run` is similar to `asyncx.run_sync`, but more flexible, and doesn't use the deprecated `asyncio.coroutine`
function. It can be passed either a coroutine directly for execution, or if a function/method is passed,
(doesn't have to be async) then it can attempt to extract the coroutine by calling each layer until a coroutine
or non-callable is found.
While there's no plan to remove `asynx.run_sync` in the near future, it's strongly recommended to switch usages of `run_sync`
to `loop_run` because it's better at handling different forms of awaitable objects:
- Unlike `run_sync`, loop_run can handle both async function references AND coroutines
- Unlike `run_sync`, loop_run can unwrap coroutines / async function references that are wrapped in a normal
non-async function (e.g. `@awaitable` wrapper functions)
- Unlike `run_sync`, loop_run can accept the optional `_loop` keyword argument, allowing you to specify a custom asyncio
event loop if you desire.
- Unlike `run_sync`, loop_run will cleanly execute non-async functions if they're encountered, and simply return
non-callable objects that were passed to it, instead of failing.
- New function / class decorator `asyncx.awaitable_class` - wraps a class and overrides `__getattribute__` to enable all async
methods to be called from non-async code. Similar to `asyncx.awaitable`, but affects all async methods in a class, and
doesn't require non-async wrapper functions to be written.
- If a non-async method or standard attribute is requested, then those are returned as normal without modification.
- If an async method is called on the class, then it checks to see if there's a current AsyncIO context - if there is, it
simply returns the coroutine for `await`'ing
- If there isn't an async context, it will use `loop_run` to call the method synchronously using the
current event loop, and return the method's result synchronously.
- New class `asyncx.AwaitableMixin` - a mixin class which works the same as `asyncx.awaitable_class`, but as a mixin class
add to your class's inheritance, instead of a decorator.
- Created the file `CHANGELOG.md` - note that it doesn't contain a full changelog yet, it only goes back as far as version 2.5
**Changes / Updates**
- **The wrapper class `helpers.extras.git.Git` has been removed,** as `AsyncGit` now uses the much simpler `@awaitable_class`
decorator to enable synchronous usage of all async methods, instead of a sub-class with individually `@awaitable` wrapped
methods.
To avoid breaking any existing code which relied on `extras.git.Git`, `Git` is now an alias for `AsyncGit`. No changes
needed to be made to the Git tests in `tests/test_extras.py`, so this change isn't believed to cause code breakage.
- A large portion of the decorator `asyncx.awaitable` has been refactored into the smaller functions: `_awaitable_blacklisted`
and `is_async_context`.
- During the refactoring of `asyncx.awaitable`, a bug was discovered in the blacklist scanning for sub-modules - this is now
fixed (note: blacklist scanning is refactored into `_awaitable_blacklisted`)
- `asyncx.py` now has an `__all__` module attribute, allowing `__init__` to simply import `*` instead of having to list each
class/function etc.
- `cache.asyncx.__init__`
- Added a PyDoc comment at the start of the file, explaining the AsyncIO adapters and how to use them.
- Added the attributes `HAS_ASYNC_REDIS`, `HAS_ASYNC_MEMORY`, and `HAS_ASYNC_MEMCACHED` to allow for easy availability
checking of async cache adapters.
- Lowered the `ImportError` log level for AsyncRedisCache and AsyncMemcachedCache from `log.exception` down to `log.debug`
- Refactored various generic / template types (e.g. `T`, `K`, `CL`) from `helpers.common` into `helpers.types`
**Testing**
- Refactored `tests/test_general.py` into a folder `tests/general/`
- Refactored AsyncIO related tests from `tests/test_general.py` into `tests/asyncx/test_async_common.py`
- Added several new AsyncIO tests to `tests/asyncx/test_async_common.py`, mainly aimed at the new `asyncx.awaitable_class`,
and `asyncx.AwaitableMixin`1 parent 015a889 commit 6ea47ca
2 files changed
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
136 | 136 | | |
137 | 137 | | |
138 | 138 | | |
139 | | - | |
| 139 | + | |
140 | 140 | | |
141 | 141 | | |
142 | 142 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
76 | 76 | | |
77 | 77 | | |
78 | 78 | | |
79 | | - | |
| 79 | + | |
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
| |||
0 commit comments