Title: [doc] Scope for raise without argument is different in Python 2 and 3
Type: behavior Stage: patch review
Components: Documentation, Interpreter Core Versions: Python 3.11, Python 3.10, Python 3.9
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: SilentGhost, a3nm, collinwinter, docs@python, iritkatriel, jayvdb, kinshukdua, martin.panter
Priority: normal Keywords: easy, patch

Created on 2015-03-01 12:14 by a3nm, last changed 2021-10-27 13:10 by kinshukdua.

File name Uploaded Description Edit a3nm, 2015-03-01 12:14 Minimal example
raise-scope-py3.patch martin.panter, 2015-07-29 09:28 For Python 3 review
Pull Requests
URL Status Linked Edit
PR 29236 open kinshukdua, 2021-10-27 13:10
Messages (6)
msg236957 - (view) Author: Antoine Amarilli (a3nm) Date: 2015-03-01 12:14

Python 2.7.8 and Python 3.4.2 (from Debian testing) have a different behavior on the attached file. Python 2 raises "bar", Python 3 raises "foo".

I can't find an adequate explanation in the documentation for this behavior difference. It probably relates to (search for "When an exception has been assigned") but this is unsatisfying because it only talks about the "as target" construction, which is not used in the example.

I think that at least the documentation should be clarified to point out what "raise" without arguments will do. Currently the documentation of this in Python 2 and 3 is the same even though the behavior is different

Note: this question was originally asked on SO: I reported this as a bug at Terry Jan Reedy's request
msg236959 - (view) Author: SilentGhost (SilentGhost) * (Python triager) Date: 2015-03-01 12:23
There is this bit in : 

> When raising a new exception (rather than using a bare raise to re-raise the exception currently being handled),...

I presume this can be also suitable for tutorial if it's not already there.
msg237493 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2015-03-08 01:49
For the Python 3 case, the documentation is vague and probably wrong, depending on what you understand “the current scope” to mean. I think it should read something like

. . . raise re-raises the current exception that is being handled. If no exception is being handled, a RuntimeError exception is raised indicating that this is an error.

I’m not sure but I suspect Python 2 is different because does not save the original exception when it handles a nested exception. In other words, at the point where the nested “bar” exception is raised inside the “foo” handler, Python forgets that “foo” was being handled.
msg247563 - (view) Author: Martin Panter (martin.panter) * (Python committer) Date: 2015-07-29 09:28
Here is a patch for Python 3. The re-raise behaviour reported by Antoine is already tested in test_raise.TestRaise.test_except_reraise().

My patch also clarifies some details about how __context__ is set:

* Context is the exception being handled, not necessarily the last exception
* “With” statements can influence context
* Re-raising does not set context; must be new exception object
* Add test case when context is not the last exception

I’m not so experienced with Python 2’s exception handling, so I haven’t got a patch for that. I suspect there is some shared “last exception” context. I wonder how it interacts with generators, multi-threading, __del__() and other callbacks, etc.
msg256907 - (view) Author: John Mark Vandenberg (jayvdb) * Date: 2015-12-23 11:23
In pyflakes we've looked at some of the strange scenarios where a raise without argument is 'legal'.  A patch to report errors for some of these was rejected because they are legal. See  The worst example of 'legal' is an exception in one module can be re-raised by another module.
msg405000 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2021-10-25 21:00
Martin's patch needs to be converted to a GitHub PR and then reviewed.
Date User Action Args
2021-10-27 13:10:44kinshukduasetkeywords: + patch
nosy: + kinshukdua
pull_requests: + pull_request27499
2021-10-25 21:00:36iritkatrielsetnosy: + iritkatriel
versions: + Python 3.9, Python 3.10, Python 3.11, - Python 2.7, Python 3.4, Python 3.5, Python 3.6
messages: + msg405000

keywords: + easy, - patch
title: Scope for raise without argument is different in Python 2 and 3 -> [doc] Scope for raise without argument is different in Python 2 and 3
2015-12-23 11:23:08jayvdbsetnosy: + jayvdb
messages: + msg256907
2015-07-29 09:28:16martin.pantersetfiles: + raise-scope-py3.patch
versions: + Python 3.5, Python 3.6
messages: + msg247563

keywords: + patch
stage: patch review
2015-07-21 07:23:29ethan.furmansetnosy: - ethan.furman
2015-03-14 00:13:44ethan.furmansetnosy: + ethan.furman
2015-03-08 01:49:34martin.pantersetassignee: docs@python

components: + Documentation
nosy: + docs@python
2015-03-08 01:49:13martin.pantersetmessages: + msg237493
2015-03-01 21:39:27martin.pantersetnosy: + martin.panter
2015-03-01 12:26:36SilentGhostsetnosy: + collinwinter
2015-03-01 12:23:21SilentGhostsetnosy: + SilentGhost
messages: + msg236959
components: + Interpreter Core
2015-03-01 12:14:32a3nmcreate