Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

__exit__ silences the active exception #47082

Closed
ddvoinikov mannequin opened this issue May 12, 2008 · 10 comments
Closed

__exit__ silences the active exception #47082

ddvoinikov mannequin opened this issue May 12, 2008 · 10 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs) release-blocker type-bug An unexpected behavior, bug, or error

Comments

@ddvoinikov
Copy link
Mannequin

ddvoinikov mannequin commented May 12, 2008

BPO 2833
Nosy @birkenfeld, @amauryfa, @pitrou, @benjaminp
Superseder
  • bpo-3021: Lexical exception handlers
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2008-06-11.16:04:44.920>
    created_at = <Date 2008-05-12.07:06:53.021>
    labels = ['interpreter-core', 'type-bug', 'release-blocker']
    title = '__exit__ silences the active exception'
    updated_at = <Date 2008-06-11.16:04:44.893>
    user = 'https://bugs.python.org/ddvoinikov'

    bugs.python.org fields:

    activity = <Date 2008-06-11.16:04:44.893>
    actor = 'benjamin.peterson'
    assignee = 'none'
    closed = True
    closed_date = <Date 2008-06-11.16:04:44.920>
    closer = 'benjamin.peterson'
    components = ['Interpreter Core']
    creation = <Date 2008-05-12.07:06:53.021>
    creator = 'ddvoinikov'
    dependencies = []
    files = []
    hgrepos = []
    issue_num = 2833
    keywords = []
    message_count = 10.0
    messages = ['66713', '66724', '66775', '66791', '66794', '66811', '66812', '67302', '67600', '67991']
    nosy_count = 6.0
    nosy_names = ['georg.brandl', 'amaury.forgeotdarc', 'Rhamphoryncus', 'pitrou', 'benjamin.peterson', 'ddvoinikov']
    pr_nums = []
    priority = 'release blocker'
    resolution = 'fixed'
    stage = None
    status = 'closed'
    superseder = '3021'
    type = 'behavior'
    url = 'https://bugs.python.org/issue2833'
    versions = ['Python 3.0']

    @ddvoinikov
    Copy link
    Mannequin Author

    ddvoinikov mannequin commented May 12, 2008

    If a context manager is used within exception handling block, the active
    exception is silenced after the context block completes and __exit__ exits.

    try:
    raise Exception("foo")
    except:
    with SomeContextManager():
    pass
    raise # in Py2.5 throws 'foo', in Py3.0 fails with RuntimeError

    @ddvoinikov ddvoinikov mannequin added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error labels May 12, 2008
    @amauryfa
    Copy link
    Member

    This problem was introduced by r62847.

    @amauryfa
    Copy link
    Member

    Note that the problem is not related to "with", but with nested
    exception handlers:

    try:
    raise Exception("foo")
    except:
    try: pass
    except: pass
    raise # in Py2.5 throws 'foo', in Py3.0 fails with RuntimeError

    OTOH, python has always had poor support for nested exceptions; tried
    with python24 and python25::

    try:
    raise Exception("foo")
    except:
    try: raise KeyError("caught")
    except KeyError: pass
    raise # reraise the KeyError...

    This does not happen if the two lines with KeyError are moved in another
    function.

    @pitrou
    Copy link
    Member

    pitrou commented May 13, 2008

    I've just discovered that the patch in r62847 doesn't clean up the
    exception state if the except clause does not mention a local variable,
    e.g. "except MyException" instead of "except MyException as e".

    @birkenfeld
    Copy link
    Member

    Raising priority.

    @pitrou
    Copy link
    Member

    pitrou commented May 14, 2008

    As Amaury said, lexically nested exception handlers make re-raising
    behaviour buggy. In Py3k, a workaround is to instead write:

    try:
    raise Exception("foo")
    except Exception as :
    try: raise KeyError("caught")
    except KeyError: pass
    raise e

    With the slight inconvenience that the "raise e" line will be appended
    to the original traceback.

    If we want bare "raise" statements to work as expected after a nested
    exception handler, we'll need to add proper exception stacking, for
    example by adding the exception value as a member of PyTryBlock. The
    effect on performance should also be measured.

    @pitrou
    Copy link
    Member

    pitrou commented May 14, 2008

    Small typo in the snippet above, this should obviously read:

    try:
    raise Exception("foo")
    except Exception as e:
    try: raise KeyError("caught")
    except KeyError: pass
    raise e

    @pitrou
    Copy link
    Member

    pitrou commented May 24, 2008

    Just found another funny example. This one fails also before r62847.

    def except_yield():
        try:
            raise Exception("foo")
        except:
            yield 1
            raise
    list(except_yield())

    In Py3k (with or without r62487), we get "RuntimeError: No active
    exception to reraise".
    In Python 2.5, we get "TypeError: exceptions must be classes, instances,
    or strings (deprecated), not NoneType".

    @pitrou
    Copy link
    Member

    pitrou commented Jun 1, 2008

    A clean solution to both bpo-2507 and bpo-2833 is now proposed in bpo-3021.

    @benjaminp
    Copy link
    Contributor

    Fixed in r64121.

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    interpreter-core (Objects, Python, Grammar, and Parser dirs) release-blocker type-bug An unexpected behavior, bug, or error
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants