Skip to content

Commit

Permalink
Reformat doc, add codeowners, rename pep, address feedback
Browse files Browse the repository at this point in the history
Signed-off-by: Pablo Galindo <[email protected]>
  • Loading branch information
pablogsal committed Oct 1, 2024
1 parent 3b2cbb5 commit df0b18a
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 19 deletions.
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,7 @@ peps/pep-0753.rst @warsaw
# ...
peps/pep-0756.rst @vstinner
peps/pep-0757.rst @vstinner
peps/pep-0758.rst @pablogsal @brettcannon
peps/pep-0789.rst @njsmith
# ...
peps/pep-0801.rst @warsaw
Expand Down
91 changes: 72 additions & 19 deletions peps/pep-0790.rst → peps/pep-0758.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
PEP: 758
Title: Allow ``except`` expressions without parentheses
Title: Allow ``except`` and ``except*`` expressions without parentheses
Author: Pablo Galindo <[email protected]>, Brett Cannon <[email protected]>
PEP-Delegate: TBD
Discussions-To: xxxx
Status: Draft
Type: Standards Track
Created: 30-Sep-2024
Expand All @@ -12,13 +11,20 @@ Python-Version: 3.14
Abstract
========

This PEP [1]_ proposes to allow unparenthesized ``except`` blocks in Python's exception handling syntax. Currently, when catching multiple exceptions, parentheses are required around the exception types. This was a Python 2 remnant. This PEP suggests allowing the omission of these parentheses, simplifying the syntax, making it more consistent with other parts of the syntax that make parentheses optional, and improving readability in certain cases.
This PEP [1]_ proposes to allow unparenthesized ``except`` and ``except*``
blocks in Python's exception handling syntax. Currently, when catching multiple
exceptions, parentheses are required around the exception types. This was a
Python 2 remnant. This PEP suggests allowing the omission of these parentheses,
simplifying the syntax, making it more consistent with other parts of the syntax
that make parentheses optional, and improving readability in certain cases.


Motivation
==========

The current syntax for catching multiple exceptions requires parentheses in the ``except`` expression:
The current syntax for catching multiple exceptions requires parentheses in the
``except`` expression (equivalently for the ``except*`` expression). For
example:

.. code-block:: python
Expand All @@ -27,7 +33,9 @@ The current syntax for catching multiple exceptions requires parentheses in the
except (ExceptionA, ExceptionB, ExceptionC):
...
While this syntax is clear and unambiguous, it can be seen as unnecessarily verbose in some cases, especially when catching a large number of exceptions. By allowing the omission of parentheses, we can simplify the syntax:
While this syntax is clear and unambiguous, it can be seen as unnecessarily
verbose in some cases, especially when catching a large number of exceptions. By
allowing the omission of parentheses, we can simplify the syntax:

.. code-block:: python
Expand All @@ -36,24 +44,49 @@ While this syntax is clear and unambiguous, it can be seen as unnecessarily verb
except ExceptionA, ExceptionB, ExceptionC:
...
This change would bring the syntax more in line with other comma-separated lists in Python, such as function arguments, generator expressions inside of a function call, and tuple literals, where parentheses are optional.
This change would bring the syntax more in line with other comma-separated lists
in Python, such as function arguments, generator expressions inside of a
function call, and tuple literals, where parentheses are optional.

The same change would apply to ``except*`` expressions. For example:

.. code-block:: python
try:
...
except* ExceptionA, ExceptionB, ExceptionC:
...
Both forms will also allow the use of the ``as`` clause to capture the exception
instance as before:

.. code-block:: python
try:
...
except ExceptionA, ExceptionB, ExceptionC as e:
...
Rationale
=========

The decision to allow unparenthesized ``except`` blocks is based on the following considerations:
The decision to allow unparenthesized ``except`` blocks is based on the
following considerations:

1. Simplicity: Removing the requirement for parentheses simplifies the syntax, making it more consistent with other parts of the language.
1. Simplicity: Removing the requirement for parentheses simplifies the syntax,
making it more consistent with other parts of the language.

2. Readability: In cases where many exceptions are being caught, the removal of parentheses can improve readability by reducing visual clutter.
2. Readability: In cases where many exceptions are being caught, the removal of
parentheses can improve readability by reducing visual clutter.

3. Consistency: This change makes the ``except`` clause more consistent with other parts of Python where unambiguous, comma-separated lists don't require parentheses.

Specification
=============

The syntax for the except clause will be modified to allow an unparenthesized list of exception types. The grammar will be updated as follows:
The syntax for the except clause will be modified to allow an unparenthesized
list of exception types. The grammar will be updated as follows:

.. code-block:: peg
Expand All @@ -70,7 +103,8 @@ The syntax for the except clause will be modified to allow an unparenthesized li
| invalid_except_star_stmt
This allows both the current parenthesized syntax and the new unparenthesized syntax:
This allows both the current parenthesized syntax and the new unparenthesized
syntax:

.. code-block:: python
Expand All @@ -81,25 +115,37 @@ This allows both the current parenthesized syntax and the new unparenthesized sy
except ExceptionC, ExceptionD: # New syntax
...
The semantics of exception handling remain unchanged. The interpreter will catch any of the listed exceptions, regardless of whether they are parenthesized or not.
The semantics of exception handling remain unchanged. The interpreter will catch
any of the listed exceptions, regardless of whether they are parenthesized or
not.


Backwards Compatibility
=======================

This change is fully backwards compatible. All existing code using parenthesized ``except`` blocks will continue to work without modification. The new syntax is purely additive and does not break any existing code.
This change is fully backwards compatible. All existing code using parenthesized
``except`` and ``except*`` blocks will continue to work without modification.
The new syntax is purely additive and does not break any existing code.

It's worth noting that in Python 2 the unparenthesized syntax was allowed with
two eleements, but had different semantics, in which the first element of the
list was used as the exception type and the second element as the capture
variable. This change does not reintroduce the Python 2 semantics, and the
unparenthesized syntax will behave identically to the parenthesized version.


Security Implications
=====================

There are no known security implications for this change. The semantics of exception handling remain the same, and this is purely a syntactic change.
There are no known security implications for this change. The semantics of
exception handling remain the same, and this is purely a syntactic change.


How to Teach This
=================

For new Python users, the unparenthesized syntax can be taught as the standard way to catch multiple exceptions:
For new Python users, the unparenthesized syntax can be taught as the standard
way to catch multiple exceptions:

.. code-block:: python
Expand All @@ -108,7 +154,9 @@ For new Python users, the unparenthesized syntax can be taught as the standard w
except ValueError, TypeError, OSError:
handle_errors()
For experienced users, it can be introduced as a new, optional syntax that can be used interchangeably with the parenthesized version. Documentation should note that both forms are equivalent:
For experienced users, it can be introduced as a new, optional syntax that can
be used interchangeably with the parenthesized version. Documentation should
note that both forms are equivalent:

.. code-block:: python
Expand All @@ -119,13 +167,17 @@ For experienced users, it can be introduced as a new, optional syntax that can b
except ValueError, TypeError:
...
It should be emphasized that this is purely a syntactic change and does not affect the behaviour of exception handling.
It should be emphasized that this is purely a syntactic change and does not
affect the behaviour of exception handling.


Reference Implementation
========================

A proof-of-concept implementation is available at https://github.com/pablogsal/cpython/commits/notuples/. This implementation modifies the Python parser to accept the new syntax and ensures that it behaves identically to the parenthesized version.
A proof-of-concept implementation is available at
https://github.com/pablogsal/cpython/commits/notuples/. This implementation
modifies the Python parser to accept the new syntax and ensures that it behaves
identically to the parenthesized version.


Rejected Ideas
Expand All @@ -140,7 +192,8 @@ Rejected Ideas
except (ValueError, TypeError), OSError:
...
This was rejected due to the potential for confusion and to maintain a clear distinction between the two styles.
This was rejected due to the potential for confusion and to maintain a clear
distinction between the two styles.

Footnotes
=========
Expand Down

0 comments on commit df0b18a

Please sign in to comment.