• Kirill Smelkov's avatar
    golang: Fix defer exception chaining for regular exceptions raised from under @func · 06cac90b
    Kirill Smelkov authored
    Defer support for exception chaining on Python2 (see bb9a94c3 "golang:
    Teach defer to chain exceptions (PEP 3134) even on Python2") simulates
    PEP 3134 by manually setting and chaining exc .__context__, .__cause__
    and .__traceback__: if exceptions are thrown by several deferred
    functions they are linked into exception chain via .__context__
    attribute. Defer support in @func also makes sure that any exception
    that comes out of a function has all those PEP 3134 attributes and
    presets them to their default values if exception object did not have
    them initially. In particular .__context__ is preset to None for first
    raised exception.
    
    There was a logic error in chaining handling: .__context__ was glued to
    previously raised exception only if current exception object did not
    have .__context__ attribute at all. And this was failing to chain them
    if current exception was raised from under another function wrapped in
    @func, because GoFrame wrapping that function makes sure to set
    curexc.__context__=None and oops - it was not changed later.
    
    -> Fix chaining implementation by gluing .__context__ either if there is
    no such attribute in current exception, or if .__context__ is None.
    
    This is correct to do since .__context__, by its definition, represents
    implicitly / automatically chained exceptions - contrary to .__cause__
    which is explicitly set and would be incorrect to automatically change
    from None to something. We also know that the end result is the same as
    Python3 behaviour since updated tests (see bellow) pass OK also when run
    under Python3 where exceptions chaining is implemented by Python runtime
    natively.
    
    Update test_defer_excchain() in golang_test.py, which verifies how
    raised exceptions are chained.
    
    No need to update testprog/golang_test_defer_excchain.{py,txt} since the
    test there verifies that our traceback dumper is correctly hooked into
    Python interpreter - where we know that exceptions are already chained
    correctly and we verify only that automatic traceback dump takes this
    chaining into account.
    
    Fixes: bb9a94c3 (golang: Teach defer to chain exceptions (PEP 3134) even on Python2)
    06cac90b
golang_test.py 42.8 KB