Comments (8)
Looks great! Yeah, this approach makes sense to me.
I understand you were interested in ExceptionGroup support so once we get anyio 4 unblocked, I'd be happy to read your input on how to add support for that in aiometer, and how you'd use it in practice (possibly with some motivating example code?).
I think this solves my use case already. I primarily just want to be able to use except*
when calling aiometer
in application code. As long as I use Python 3.11 and higher, I should now receive native ExceptionGroups (if multiple errors occur) or unwrapped exceptions. I can handle both with a single except*
clause, which is what I needed.
The general problem was that we use Python task groups as well as aiometer
for metering, so we were getting different types of ExceptionGroups around the codebase, which made error handling confusing. Now it should be all good!
from aiometer.
Hi,
There's no blocker against this, I would be happy to help get a PR reviewed and merged to add anyio 4 support :)
Let's try to target anyio >= 3.2 if we can?
from aiometer.
Thanks for the quick reply!
I tried running the testing suite with anyio
4.1.0 and one of the tests fails, specifically this one:
test_amap_task_exception
The test asserts that if one of the tasks started in aiometer.amap
fails, the exception is propagated to the caller. Under anyio
4, we now get the exception wrapped in an ExceptionGroup though.
If we retain support for anyio
3, how should we deal with this? The behaviour will differ between the supported anyio
versions. We can make the test expect either the exception, or an ExceptionGroup wrapping it, but I'm not sure if that's acceptable for the users.
from aiometer.
Is the ExceptionGroup raised on all Python versions, or only most recent ones?
Does the ExceptionGroup contain only the exception raised by user code? I assume not. Then what's the other exception?
If there's only the user exception, would it make sense to unwrap the exception group so we keep the current behaviour?
Or should we embrace the new exception group stuff? I must say I haven't really kept on top of that and I'm not sure we can assume users will be comfortable handling exception groups either, so in that case we probably need some extra pointers in the docs.
One thing we can sure of is we don't want any anyio specific APIs to leak through.
from aiometer.
Is the ExceptionGroup raised on all Python versions, or only most recent ones?
Does the ExceptionGroup contain only the exception raised by user code? I assume not. Then what's the other exception?
I tried on Python 3.8 and 3.11 and the behaviour is the same, the only difference is that on 3.8 we get an ExceptionGroup backport from exceptiongroup
and on 3.11 we get the Python-native ExceptionGroup.
It really is just one exception in the group. The anyio
release docs mention that after 4.0.0, "any exceptions raising out of a task groups are now nested inside an ExceptionGroup
."
In fact, aiometer.amap
now raises the following:
- Exception Group with 1 sub-exception
- - Exception Group with 1 sub-exception
- - - Failure (exception defined in the test)
Looking at the implementation, I think this is because there are two nested task groups - one in amap
, and one in run_on_each
. So because anyio
no longer unwraps the exception if only 1 exception occurs, the nesting of exceptions is proportional to the nesting of task groups.
If there's only the user exception, would it make sense to unwrap the exception group so we keep the current behaviour?
I'm not sure, but I'm leaning towards no. I don't think that's something that should happen in aiometer
. It's unfortunate that it is a breaking change, but I think anyio
went for it because it is consistent with Python-native task groups, where any exception is wrapped in an ExceptionGroup
, even if there is only 1. It seems to be a more consistent and predictable API. So my personal opinion would be that aiometer
shouldn't diverge from what's become the "standard" behaviour in the standard library.
from aiometer.
Thanks for the input and bouncing off of ideas.
It's interesting that the anyio migration guide suggests to do this kind of unwrapping "If you need to stay compatible with both AnyIO 3 and 4". I just opened #43 as an attempt of that.
from aiometer.
@kwzrd #43 is passing. Happy to read your thoughts on this approach?
This would lead to a non-breaking release of aiometer, as 0.5.0.
We could add ExceptionGroup support to aiometer in the future, so that it's possible to really get all exceptions that might happen concurrently as tasks execute.
But I think it's okay treat that as a follow-up enhancement, with its own proper compatibility and upgrade approach, rather than a blocker for anyio 4 support, since we don't have it now anyways.
I understand you were interested in ExceptionGroup support so once we get anyio 4 unblocked, I'd be happy to read your input on how to add support for that in aiometer, and how you'd use it in practice (possibly with some motivating example code?).
from aiometer.
Right, the compat code only unwraps single exception groups. 👍
from aiometer.
Related Issues (10)
- Simplifying amap usage HOT 3
- requests as list HOT 2
- Interaction with tenacity retry HOT 5
- swap the stream contexts with the taskgroup context HOT 5
- Update requirements HOT 5
- Handling of exceptions and documentation
- Best practice for handling rate limits HOT 1
- `gather` drop-in replacement HOT 3
- Allow AsyncGenerator or AsyncIterator for "args" HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from aiometer.