GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — [ExceptionGroup] Inconsistent raise inside except* · Issue #103590 · python/cpython

[ExceptionGroup] Inconsistent raise inside except* #103590

New issue
Copy link
New issue
Copy link
Closed
#103665
Closed
[ExceptionGroup] Inconsistent raise inside except*#103590
#103665
Copy link
Labels
type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@andriilahuta
andriilahuta
opened on Apr 17, 2023
Issue body actions

Bug report

When raising inside except* block and the caught exception wasn't an ExceptionGroup originally, then raised exception doesn't get wrapped in ExceptionGroup:

try:
    try:
        raise TypeError(1)  # prints ValueError(3)
        raise ExceptionGroup('', [TypeError(2)])  # prints ExceptionGroup('', [ValueError(3)])
    except* TypeError:
        raise ValueError(3)
except BaseException as e:
    print(repr(e))

Your environment

  • CPython versions tested on: 3.11.3
  • Operating system and architecture: Windows 11 / Ubuntu 22.04

Linked PRs

  • gh-103590: do not wrap a single exception raised from a try-except* #103665
  • [3.11] gh-103590: do not wrap a single exception raised from a try-except* #104094
  • gh-103590: mention that the change is included in 3.11.4 and clarify except* documentation #104095

Activity

  1. andriilahuta
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Apr 17, 2023
  2. mdboom commented on Apr 17, 2023

    @mdboom
    mdboom
    on Apr 17, 2023
    Contributor
    More actions

    Cc: @iritkatriel

  3. sunmy2019 commented on Apr 17, 2023

    @sunmy2019
    sunmy2019
    on Apr 17, 2023
    Member
    More actions

    This is fully documented behavior. https://peps.python.org/pep-0654/#raising-new-exceptions

    Raising a new instance of a naked exception does not cause this exception to be wrapped by an exception group. Rather, the exception is raised as is, and if it needs to be combined with other propagated exceptions, it becomes a direct child of the new exception group created for that.

    >>> try:
    ...     raise ExceptionGroup("eg", [ValueError('a')])
    ... except* ValueError:
    ...     raise KeyError('x')
    ...
      | ExceptionGroup:  (1 sub-exception)
      +-+---------------- 1 ----------------
        | Exception Group Traceback (most recent call last):
        |   File "<stdin>", line 2, in <module>
        | ExceptionGroup: eg (1 sub-exception)
        +-+---------------- 1 ----------------
          | ValueError: a
          +------------------------------------
        |
        | During handling of the above exception, another exception occurred:
        |
        | Traceback (most recent call last):
        |   File "<stdin>", line 4, in <module>
        | KeyError: 'x'
        +------------------------------------
    >>>
    >>> try:
    ...     raise ExceptionGroup("eg", [ValueError('a'), TypeError('b')])
    ... except* ValueError:
    ...     raise KeyError('x')
    ...
      | ExceptionGroup:  (2 sub-exceptions)
      +-+---------------- 1 ----------------
        | Exception Group Traceback (most recent call last):
        |   File "<stdin>", line 2, in <module>
        | ExceptionGroup: eg (1 sub-exception)
        +-+---------------- 1 ----------------
          | ValueError: a
          +------------------------------------
        |
        | During handling of the above exception, another exception occurred:
        |
        | Traceback (most recent call last):
        |   File "<stdin>", line 4, in <module>
        | KeyError: 'x'
        +---------------- 2 ----------------
        | Exception Group Traceback (most recent call last):
        |   File "<stdin>", line 2, in <module>
        | ExceptionGroup: eg (1 sub-exception)
        +-+---------------- 1 ----------------
          | TypeError: b
          +------------------------------------
    >>>
  4. andriilahuta commented on Apr 17, 2023

    @andriilahuta
    andriilahuta
    on Apr 17, 2023
    Author
    More actions

    @sunmy2019 thanks for the docs pointer. It is a bit confusing behavior for me, since I can't always be sure what I'm actually raising. But I guess we can close this then?

    Reacted by sunmy2019 and Furkan Onder
  5. carljm commented on Apr 17, 2023

    @carljm
    carljm
    on Apr 17, 2023
    Member
    More actions

    I don't think that the issue in the OP here clearly matches any example shown in the PEP. The key factor in the PEP example:

    >>> try:
    ...     raise ExceptionGroup("eg", [ValueError('a'), TypeError('b')])
    ... except* ValueError:
    ...     raise KeyError('x')
    

    is that the raised exception group includes both a ValueError (will be caught by the except* ValueError) and a TypeError (is not caught and thus must be propagated.) It is the latter TypeError that means the newly raised KeyError "needs to be combined with other propagated exceptions" (the TypeError), and thus a new ExceptionGroup is created for that.

    In the OP example:

    try:
        raise ExceptionGroup('', [TypeError(2)])
    except* TypeError:
        raise ValueError(3)
    

    the original exception group contains only a TypeError, which is caught by except* TypeError. So there are no remaining uncaught exceptions that must propagate along with the newly raised ValueError. So according to the wording in the PEP:

    Rather, the exception is raised as is, and if it needs to be combined with other propagated exceptions, it becomes a direct child of the new exception group created for that

    it is surprising (to me -- not an expert in the ExceptionGroup feature by any means) that a new ExceptionGroup would be created containing just the newly-raised ValueError.

    The documentation says about this case:

    Any remaining exceptions that were not handled by any except* clause are re-raised at the end, combined into an exception group along with all exceptions that were raised from within except* clauses.

    This wording is more ambiguous than the wording in the PEP, and leaves open the possibility that a new exception group should always be created, even if we are raising just a single exception and there were no "remaining exceptions" to propagate.

    So it is possible this is intended behavior, but it doesn't seem at all clear. I think we need input from @iritkatriel here.

  6. iritkatriel
    added a commit that references this issue on Apr 21, 2023

    pythongh-103590: do not wrap a single exception raised from a try-exc…

    17a1311
  7. iritkatriel commented on Apr 21, 2023

    @iritkatriel
    iritkatriel
    on Apr 21, 2023
    Member
    More actions

    I agree that the wording of the PEP implies that wrapping in an exception group should not happen unless it is necessary, and it is not necessary when there is only one exception.

    I don't remember why I implemented it this way (with unit tests asserting this behaviour, no less). I'm going to assume that it was a simple mistake and make a PR to fix it. Will ask @gvanrossum for a second option.

  8. iritkatriel
    closed this as completedin #103665on Apr 27, 2023
  9. iritkatriel
    added 4 commits that reference this issue on Apr 27, 2023

    gh-103590: do not wrap a single exception raised from a try-except* (#…

    63842bd

    pythongh-103590: do not wrap a single exception raised from a try-exc…

    2713e5a

    [3.11] gh-103590: do not wrap a single exception raised from a try-ex…

    5386730

    gh-103590: mention that the change is included in 3.11.4 and clarify …

    9f9e001
  10. meili-bors
    added a commit that references this issue on Jul 4, 2023

    Merge #793

    7a2724d
  11. bmwiedemann
    added a commit that references this issue on Jul 6, 2023

    Update python-exceptiongroup to version 1.1.2 / rev 6 via SR 1096944

    2ff3327
  12. meili-bors
    added a commit that references this issue on Sep 4, 2023

    Merge #837

    797c19a
  13. meili-bors
    added a commit that references this issue on Dec 1, 2023

    Merge #893

    226f14d
  14. mkjpryor
    added a commit that references this issue on Apr 19, 2024

    Bump exceptiongroup from 1.2.0 to 1.2.1 (#76)

    4c84722
  15. github-actions
    added a commit that references this issue on Apr 21, 2024

    Bump exceptiongroup from 1.2.0 to 1.2.1 (#1045)

    49fccf3
  16. meili-bors
    added a commit that references this issue on May 1, 2024

    Merge #953

    b78b726
  17. shaldengeki
    added a commit that references this issue on Jun 6, 2024

    Bump exceptiongroup from 1.2.0 to 1.2.1 in /src/python (#106)

    99d4e81
  18. ansibuddy
    added a commit that references this issue on Jul 14, 2024

    Bump the dependencies group across 1 directory with 17 updates (#4254)

    00f24c5
  19. shaldengeki
    added a commit that references this issue on Jul 15, 2024

    Bump exceptiongroup from 1.2.1 to 1.2.2 (#234)

    06961a5
  20. mkjpryor
    added a commit that references this issue on Jul 19, 2024

    Bump exceptiongroup from 1.2.1 to 1.2.2 (#111)

    b521ece
  21. meili-bors
    added a commit that references this issue on Aug 1, 2024

    Merge #999

    d0f63c1
  22. github-actions
    added 2 commits that reference this issue on Aug 21, 2024

    Bump exceptiongroup from 1.1.2 to 1.2.2 (#8812)

    39abb92

    Bump exceptiongroup from 1.1.2 to 1.2.2 (#8861)

    4cdbf01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.