Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AssertionError from MultiError.__init__() #1199

Closed
belm0 opened this issue Aug 27, 2019 · 13 comments
Closed

AssertionError from MultiError.__init__() #1199

belm0 opened this issue Aug 27, 2019 · 13 comments

Comments

@belm0
Copy link
Member

belm0 commented Aug 27, 2019

seen in Trio 0.12.1

Traceback (most recent call last):
  File "/usr/lib/python3.7/contextlib.py", line 635, in __aexit__
    cb_suppress = await cb(*exc_details)
  File "/usr/lib/python3.7/contextlib.py", line 539, in _exit_wrapper
    return await cm_exit(cm, exc_type, exc, tb)
  File "/.../python3.7/site-packages/anyio/_backends/_trio.py", line 123, in __aexit__
    raise TrioExceptionGroup(exc.exceptions) from None
  File "/.../python3.7/site-packages/trio/_core/_multierror.py", line 184, in __init__
    assert len(exceptions) == 1 and exceptions[0] is self
AssertionError
@belm0
Copy link
Member Author

belm0 commented Aug 27, 2019

When __init__() is invoked, the exceptions class instance member is an empty tuple.

And here is the value of the exceptions arg, in all its glory (ConnectionClosed is from trio_websocket):

 [Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, Cancelled(), ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, Cancelled(), Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, <MultiError: Cancelled(), Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>>, <MultiError: Cancelled(), Cancelled(), ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>>, <MultiError: Cancelled(), Cancelled(), ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>>>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled()>>, <MultiError: Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>>, <MultiError: Cancelled(), Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>, Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled(), Cancelled()>>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>, Cancelled()>>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>, Cancelled()>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled()>>, Cancelled()>, <MultiError: Cancelled(), Cancelled(), Cancelled(), ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, <MultiError: Cancelled(), Cancelled(), Cancelled()>, Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled(), Cancelled()>>>>, <MultiError: Cancelled(), <MultiError: Cancelled(), Cancelled()>, <MultiError: Cancelled(), Cancelled(), <MultiError: Cancelled(), Cancelled()>>>, Cancelled(), ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>>, Cancelled()]

@belm0
Copy link
Member Author

belm0 commented Aug 27, 2019

So it's related to anyio exception groups. The base class ExceptionGroup has an exceptions attribute, and TrioExceptionGroup inherits from ExceptionGroup and trio.MultiError.

Hmm, I see in anyio head some hack for Trio 0.12 to turn around and delete the attribute.

https://github.com/agronholm/anyio/blob/37c1e21c4edd2a5c35706144f6813139ec57af5f/anyio/exceptions.py#L10-L11

quite a mess all around...

@belm0
Copy link
Member Author

belm0 commented Aug 27, 2019

I tried anyio HEAD. Same problem, although now the exceptions class instance member is populated rather than an empty tuple:

[ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, <MultiError: ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>>, <MultiError: ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, <MultiError: ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>>, <MultiError: ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>, ConnectionClosed<CloseReason<code=1006, name=ABNORMAL_CLOSURE, reason=None>>]

So it's to do with multiple inheritance and MultiError?

@njsmith
Copy link
Member

njsmith commented Aug 27, 2019

I definitely haven't thought through how to support subclassing on MultiError... @agronholm, I guess you're the one doing the subclassing here; any thoughts? I think the proximal change that's triggering this is probably #1067 / #1066

@agronholm
Copy link
Contributor

That change in trio was not particularly welcomed by yours truly, as it completely broke anyio compatibility and I had to do the hack mentioned by @belm0 to work around it. I've never seen guards like that anywhere else. How exactly did you trigger the problem @belm0 ?

@belm0
Copy link
Member Author

belm0 commented Aug 27, 2019

Are we sure that MultiError worked correctly in the face of subclassing / multiple inheritance even prior to that change?

@agronholm
Copy link
Contributor

Well, at least it was fine in anyio as far as I can tell.

@agronholm
Copy link
Contributor

@belm0 tell me again, how are you triggering the problem on the latest master version of anyio? The test suite passes just fine.

@belm0
Copy link
Member Author

belm0 commented Aug 27, 2019

It's a non-trivial app, I can't offer a repro at this point.

I'm sure that the behavior is different between anyio 1.0.0 and head, yet the latter is not sufficient.

From the debugging I did above, I think we can conclude that with subclassing and/or multiple inheritance there are other paths where __init__() may be called on an existing object, beyond what is assumed in the Trio code.

@agronholm
Copy link
Contributor

Are you by any chance serializing the MultiErrors, possibly via multiprocessing?

@agronholm
Copy link
Contributor

I guess not. But can you at least find out what exactly is being passed to TrioExceptionGroup's constructor?

@belm0
Copy link
Member Author

belm0 commented Aug 27, 2019

Sorry, operator error here. Indeed, there is not an AssertionError from Trio with anyio HEAD.

So outstanding is to decide on policy about MultiError inheritance, and whether to make the internals less fragile.

@Zac-HD
Copy link
Member

Zac-HD commented Nov 3, 2022

Closing this because we've dropped MultiError.

@Zac-HD Zac-HD closed this as completed Nov 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants