classification
Title: __context__ for yields inside except clause
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.6, Python 3.5, Python 3.3, Python 3.4
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: benjamin.peterson, ebarry, gvanrossum, njs, vstinner, yselivanov
Priority: normal Keywords:

Created on 2015-11-20 16:29 by yselivanov, last changed 2017-02-17 11:55 by njs. This issue is now closed.

Messages (5)
msg254994 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2015-11-20 16:29
In the below snippet, SubError will propagate with __context__ set to None, instead of MainError.  Maybe this isn't a bug?

    class MainError(Exception): pass
    class SubError(Exception): pass

    def main():
        try:
            raise MainError()
        except MainError:
            yield

    coro = main()
    coro.send(None)
    coro.throw(SubError())
msg255348 - (view) Author: Emanuel Barry (ebarry) * Date: 2015-11-25 13:38
This is due to the fact that Python 3 added the ability to define only __eq__ and get a free __ne__ defined. If my memory serves me right, functools.total_ordering was added in 3.2 and then backported to 2.x - where the relationship with __eq__ and __ne__ is not present. total_ordering doesn't do anything to touch __ne__ as it expects Python itself to do so (which it doesn't in 2.x).
msg255349 - (view) Author: Emanuel Barry (ebarry) * Date: 2015-11-25 13:39
Oops, that was *completely* the wrong issue. I apologize for the noise.
msg256621 - (view) Author: Yury Selivanov (yselivanov) * (Python committer) Date: 2015-12-17 23:07
I now don't think this is a bug.

In the above example, SubError is instantiated outside of `main` generator.  It's also thrown *into* `main` from the *outside* scope.  And __context__ should be set for exceptions that were originated by the code that was handling other exceptions.

Closing this issue with 'not a bug'.
msg287993 - (view) Author: Nathaniel Smith (njs) * Date: 2017-02-17 11:55
I disagree with the stated reason for closing this, because in general, implicit context chaining doesn't care about where the exception was instantiated, only where it was raised. For example:

-----
err = ValueError()
try:
    raise KeyError
except Exception:
    raise err
-----

Prints:

-----
Traceback (most recent call last):
  File "/tmp/bar.py", line 3, in <module>
    raise KeyError
KeyError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/tmp/bar.py", line 5, in <module>
    raise err
ValueError
-----

I would expect 'gen.throw(OBJ)' to be equivalent to doing 'raise OBJ' inside the generator, and raise does set __context__.
History
Date User Action Args
2017-02-17 11:55:09njssetnosy: + njs
messages: + msg287993
2015-12-17 23:07:38yselivanovsetstatus: open -> closed
resolution: not a bug
messages: + msg256621

stage: resolved
2015-11-25 13:39:24ebarrysetmessages: + msg255349
2015-11-25 13:38:49ebarrysetnosy: + ebarry
messages: + msg255348
2015-11-20 16:29:46yselivanovcreate