From 668beb0cdeefaee655818af00b4b700746ef7541 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Tue, 1 Oct 2024 22:55:14 +0100 Subject: [PATCH 1/4] PEP 758: Allow ``except`` and ``except*`` expressions without parentheses (#4008) --- .github/CODEOWNERS | 1 + peps/pep-0758.rst | 207 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+) create mode 100644 peps/pep-0758.rst diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 36b5fbed6d0..2c99583b4cc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -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 diff --git a/peps/pep-0758.rst b/peps/pep-0758.rst new file mode 100644 index 00000000000..df3efa0e0c9 --- /dev/null +++ b/peps/pep-0758.rst @@ -0,0 +1,207 @@ +PEP: 758 +Title: Allow ``except`` and ``except*`` expressions without parentheses +Author: Pablo Galindo , Brett Cannon +PEP-Delegate: TBD +Status: Draft +Type: Standards Track +Created: 30-Sep-2024 +Python-Version: 3.14 + + +Abstract +======== + +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 (equivalently for the ``except*`` expression). For +example: + +.. code-block:: python + + try: + ... + 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: + +.. code-block:: python + + try: + ... + 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. + +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: + +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. + +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: + +.. code-block:: peg + + except_block[excepthandler_ty]: + | invalid_except_stmt_indent + | 'except' e=expressions t=['as' z=NAME { z }] ':' b=block { + _PyAST_ExceptHandler(e, (t) ? ((expr_ty) t)->v.Name.id : NULL, b, EXTRA) } + | 'except' ':' b=block { _PyAST_ExceptHandler(NULL, NULL, b, EXTRA) } + | invalid_except_stmt + except_star_block[excepthandler_ty]: + | invalid_except_star_stmt_indent + | 'except' '*' e=expressions t=['as' z=NAME { z }] ':' b=block { + _PyAST_ExceptHandler(e, (t) ? ((expr_ty) t)->v.Name.id : NULL, b, EXTRA) } + | invalid_except_star_stmt + + +This allows both the current parenthesized syntax and the new unparenthesized +syntax: + +.. code-block:: python + + try: + ... + except (ExceptionA, ExceptionB): # Still valid + ... + 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. + + +Backwards Compatibility +======================= + +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 elements, 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. + + +How to Teach This +================= + +For new Python users, the unparenthesized syntax can be taught as the standard +way to catch multiple exceptions: + +.. code-block:: python + + try: + risky_operation() + 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: + +.. code-block:: python + + # These are equivalent: + except (ValueError, TypeError): + ... + + except ValueError, TypeError: + ... + +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. + + +Rejected Ideas +============== + +1. Allowing mixed parenthesized and unparenthesized syntax: + + .. code-block:: python + + try: + ... + except (ValueError, TypeError), OSError: + ... + + This was rejected due to the potential for confusion and to maintain a clear + distinction between the two styles. + +Footnotes +========= + +.. [1] Originally named "Parenthetically Speaking, We Don't Need 'Em" + +Copyright +========= + +This document is placed in the public domain or under the +CC0-1.0-Universal license, whichever is more permissive. From a65bbd2d2865602d9fdcc3d8442d43cc835bb5b8 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Salgado Date: Tue, 1 Oct 2024 23:47:21 +0100 Subject: [PATCH 2/4] PEP 758: Small updates to PEG syntax and formatting (#4013) --- peps/pep-0758.rst | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/peps/pep-0758.rst b/peps/pep-0758.rst index df3efa0e0c9..cffa85bb70e 100644 --- a/peps/pep-0758.rst +++ b/peps/pep-0758.rst @@ -75,12 +75,14 @@ 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. + 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. + 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. +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 ============= @@ -90,18 +92,12 @@ list of exception types. The grammar will be updated as follows: .. code-block:: peg - except_block[excepthandler_ty]: - | invalid_except_stmt_indent - | 'except' e=expressions t=['as' z=NAME { z }] ':' b=block { - _PyAST_ExceptHandler(e, (t) ? ((expr_ty) t)->v.Name.id : NULL, b, EXTRA) } - | 'except' ':' b=block { _PyAST_ExceptHandler(NULL, NULL, b, EXTRA) } - | invalid_except_stmt - except_star_block[excepthandler_ty]: - | invalid_except_star_stmt_indent - | 'except' '*' e=expressions t=['as' z=NAME { z }] ':' b=block { - _PyAST_ExceptHandler(e, (t) ? ((expr_ty) t)->v.Name.id : NULL, b, EXTRA) } - | invalid_except_star_stmt + except_block: + | 'except' expressions ['as' NAME] ':' block + | 'except' ':' block + except_star_block + | 'except' '*' expressions ['as' NAME] ':' block This allows both the current parenthesized syntax and the new unparenthesized syntax: From a405273a4da91a7b0d2aaddbcc85615ad4eb2006 Mon Sep 17 00:00:00 2001 From: Savannah Ostrowski Date: Wed, 2 Oct 2024 04:57:33 -0700 Subject: [PATCH 3/4] PEP 703: Fix typo (#3956) --- peps/pep-0703.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/peps/pep-0703.rst b/peps/pep-0703.rst index 0cc4e84145b..bed80c7842d 100644 --- a/peps/pep-0703.rst +++ b/peps/pep-0703.rst @@ -13,7 +13,7 @@ Post-History: `09-Jan-2023 `__, Resolution: https://discuss.python.org/t/pep-703-making-the-global-interpreter-lock-optional-in-cpython-acceptance/37075 .. note:: - The Steering Council accepts PEP 703, but with clear provisio: that + The Steering Council accepts PEP 703, but with clear proviso: that the rollout be gradual and break as little as possible, and that we can roll back any changes that turn out to be too disruptive – which includes potentially rolling back all of PEP 703 entirely if necessary From 168bf569288f486722660377fec3fa1197d845bb Mon Sep 17 00:00:00 2001 From: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com> Date: Wed, 2 Oct 2024 19:25:19 +0300 Subject: [PATCH 4/4] PEP 755: Add missing CODEOWNERS entry (#4014) --- .github/CODEOWNERS | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2c99583b4cc..60450e4eed6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -565,7 +565,6 @@ peps/pep-0681.rst @jellezijlstra peps/pep-0682.rst peps/pep-0683.rst @ericsnowcurrently peps/pep-0684.rst @ericsnowcurrently -# peps/pep-0684.rst peps/pep-0685.rst @brettcannon peps/pep-0686.rst @methane peps/pep-0687.rst @encukou @erlend-aasland @@ -628,22 +627,22 @@ peps/pep-0746.rst @JelleZijlstra peps/pep-0747.rst @JelleZijlstra # ... peps/pep-0749.rst @JelleZijlstra -# ... peps/pep-0750.rst @gvanrossum @lysnikolaou peps/pep-0751.rst @brettcannon peps/pep-0752.rst @warsaw peps/pep-0753.rst @warsaw -# ... # peps/pep-0754.rst -# ... +peps/pep-0755.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 # ... peps/pep-2026.rst @hugovk +# ... peps/pep-3000.rst @gvanrossum peps/pep-3001.rst @birkenfeld # peps/pep-3002.rst