classification
Title: [doc] First argument to raise can also be BaseException
Type: enhancement Stage:
Components: Documentation Versions: Python 3.11, Python 3.10, Python 3.9
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: docs@python Nosy List: aroberge, docs@python, gtitze, iritkatriel, sobolevn, veky
Priority: normal Keywords: easy

Created on 2022-01-07 13:30 by gtitze, last changed 2022-01-08 23:29 by veky.

Messages (15)
msg409961 - (view) Author: Gregor Titze (gtitze) * Date: 2022-01-07 13:30
The Python Tutorial describes the first argument to the raise statement as follows:

"""
This must be either an exception instance or an exception class (a class that derives from Exception).
"""
https://docs.python.org/3/tutorial/errors.html#raising-exceptions

However, the Python Language Reference states, that exceptions should be a subclass or instance of BaseException.
https://docs.python.org/3/reference/simple_stmts.html#grammar-token-python-grammar-raise_stmt

I think it would be correct, to adapt the Tutorial to match the Reference.
msg409988 - (view) Author: Nikita Sobolev (sobolevn) * (Python triager) Date: 2022-01-07 17:08
I think that this is intentional: tutorial gives some very basic ideas about what can be raised. Giving the whole context (you can `raise` two kinds of errors: `Exception` and `BaseException`, but they are different, should be used in different cases, and they are caught differently). Probably most users don't need to subclass `BaseException` at all.

And if they need to: there are docs for that https://docs.python.org/3/library/exceptions.html#BaseException

In my opinion - nothing should be changed there :)
msg410001 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-01-07 18:58
If you scroll up, you can see that BaseException was mentioned above:

"All exceptions inherit from BaseException, and so it can be used to serve as a wildcard"

so I don't think it will add confusion to fix this. And it will be more accurate.

Gregor, would you like to submit a patch?
msg410005 - (view) Author: Andre Roberge (aroberge) * Date: 2022-01-07 19:05
In https://docs.python.org/3/library/exceptions.html#Exception, it is written:

"All built-in, non-system-exiting exceptions are derived from this class. All user-defined exceptions should also be derived from this class."

Yes, technically, the root of all exceptions is BaseException. However, this seems to indicate that the advice given in the tutorial is correct.
msg410008 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-01-07 19:16
Andre, I don't follow. The OP is reporting an issue with a line about raising exceptions. Why is it correct to advise us to raise only Exception subclasses?
msg410013 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-01-07 19:32
There are other issues in this doc:

1. The paragraph starting with "The except clause may specify a variable after the exception name.." appears after this face was used in an example. It should move up.

2. In the User-defined Exceptions Section, there is a link to the Classes tutorial in the beginning "(See Classes for more about Python classes)", and another one at the end, "More information on classes it presented in chapter Classes".     The second one can be removed.
msg410027 - (view) Author: Andre Roberge (aroberge) * Date: 2022-01-07 20:26
Irit:

Gregor indicates that, while the tutorial refers to "a class that derives from Exception", the Python Reference Language states exceptions should be subclasses of BaseException  (which Exception *is*).

You then invited Gregor to submit a patch to change the wording of the tutorial (implying that it would refer to a class that derives from BaseException).

I pointed out that the advice given elsewhere is that user-defined exceptions should derive from Exception (thus, not from BaseException), so that nothing should be changed in the tutorial, and no change should be submitted.

So, as I understand it: there is a strict hierarchy of exceptions classes, all inheriting from BaseException. However, user-defined exceptions should be derived from Exception (and not BaseException), as indicated in the tutorial and on the page describing what each exception indicates. If that is correct, nothing needs to be changed in the tutorial.
msg410028 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-01-07 20:37
Andre, are you saying that we should only RAISE Exception subclasses?
msg410035 - (view) Author: Andre Roberge (aroberge) * Date: 2022-01-07 21:10
Irit:


In all the books and tutorials I have seen, the advice is to try to catch specific exceptions whenever possible or, *at most*, to catch Exception (and not BaseException).  This is to allow, for example, a program to be interrupted by a KeyboardInterrupt.

As you know, the hierarchy is as follows:

BaseException
 +-- SystemExit
 +-- KeyboardInterrupt
 +-- GeneratorExit
 +-- Exception
      +-- all others

If specific action to do some cleanup before a SystemExit (usually the result of calling sys.exit()) or catching some KeyboardInterrupt (which is generally NOT done via a raise statement), then these specific exception should be caught.
The documentation refers to GeneratorExit as not indicating an error needing to be caught by users.

For this advice (catching Exception and not BaseException) to be correct, users should be advised (as they are in the tutorial) to raise exceptions derived from Exception (and not BaseException).
msg410036 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-01-07 21:14
> For this advice (catching Exception and not BaseException) to be correct, users should be advised (as they are in the tutorial) to raise exceptions derived from Exception (and not BaseException).

I disagree with that.
msg410037 - (view) Author: Andre Roberge (aroberge) * Date: 2022-01-07 21:22
>> For this advice (catching Exception and not BaseException) to be correct, users should be advised (as they are in the tutorial) to raise exceptions derived from Exception (and not BaseException).

> I disagree with that.

You are a core developer and I just an end-user. I respect your expertise and will no longer comment.
msg410057 - (view) Author: Gregor Titze (gtitze) * Date: 2022-01-08 00:04
Andre:

You mention that user-defined exceptions should inherit from Exception. This is totally right and explicitly stated just a bit later in 8.6 on the same page of the tutorial. I think this perfectly covers this concern .

However, the paragraph I refer to explains the raise statement and as stated in the reference, the raise statement must be followed by a class or instance derived from BaseException. Thus, I think it would just be accurate and people reading on don't stumble over this difference as I did.

Regarding the mentioned wildcard: I think it wouldn't be a real wildcard anymore if it didn't catch ALL exceptions. Anyway the tutorial states that it needs to be used with extreme caution and the example re-raises the error.

Irit:

Yes I am happy provide a patch. I would also correct the other two issues you mentioned.
msg410060 - (view) Author: Gregor Titze (gtitze) * Date: 2022-01-08 00:22
Irit:

I would move the paragraph starting with "The except clause may specify a variable after the exception name ..." and the following example before the paragraph starting with "All exceptions inherit from BaseException, and so it can be used to serve as a wildcard ..."

Or did you have another position in mind?
msg410064 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-01-08 00:47
Make a PR and we can then tweak it via code reviews, it will be easier.
msg410123 - (view) Author: Vedran Čačić (veky) * Date: 2022-01-08 23:29
Let me just say that I use `raise SystemExit` all the time. Beats `from sys import exit`, weird error messages about having to type parentheses, and surely beats "oh, am I on Windows so Ctrl+Z, or on Linux so Ctrl+D". :-]

I also use `raise KeyboardInterrupt` sometimes in games, to test whether Ctrl+C handling works as expected at precise moments in the game (beats having to guess the millisecond in which to press Ctrl+C:).
History
Date User Action Args
2022-01-08 23:29:55vekysetnosy: + veky
messages: + msg410123
2022-01-08 00:47:59iritkatrielsetmessages: + msg410064
2022-01-08 00:22:27gtitzesetmessages: + msg410060
2022-01-08 00:04:17gtitzesetmessages: + msg410057
2022-01-07 21:22:52arobergesetmessages: + msg410037
2022-01-07 21:14:55iritkatrielsetmessages: + msg410036
2022-01-07 21:10:25arobergesetmessages: + msg410035
2022-01-07 20:37:07iritkatrielsetmessages: + msg410028
2022-01-07 20:26:20arobergesetmessages: + msg410027
2022-01-07 19:35:04iritkatrielsetkeywords: + easy
2022-01-07 19:34:25iritkatrielsetversions: - Python 3.6, Python 3.7, Python 3.8
2022-01-07 19:32:21iritkatrielsetmessages: + msg410013
2022-01-07 19:16:58iritkatrielsetmessages: + msg410008
2022-01-07 19:05:38arobergesetnosy: + aroberge
messages: + msg410005
2022-01-07 18:58:23iritkatrielsetnosy: + iritkatriel
messages: + msg410001
2022-01-07 17:08:04sobolevnsetnosy: + sobolevn
messages: + msg409988
2022-01-07 13:30:17gtitzecreate