bpo-25782: avoid hang in PyErr_SetObject when current exception has a… by iritkatriel · Pull Request #27626 · python/cpython (original) (raw)

Maybe it would be nice to have a test case with a longer cycle? As in

def test_no_hang_on_context_chain_cycle2(self):
    class A(Exception):
        pass
    class B(Exception):
        pass
    class C(Exception):
        pass
    class D(Exception):
        pass
    class E(Exception):
        pass
    
    # Context cycle:
    #             +-----------+
    #             V           |
    # E --> D --> C --> B --> A
    with self.assertRaises(E):
        try:
            raise A()
        except A as _a:
            a = _a
            try:
                raise B()
            except B as _b:
                b = _b
                try:
                    raise C()
                except C as _c:
                    c = _c
                    a.__context__ = c
                    try:
                        raise D()
                    except D as _d:
                        d = _d
                        e = E()
                        raise e

    # Finish without breaking the cycle
    self.assertIs(e.__context__, d)
    self.assertIs(d.__context__, c)
    self.assertIs(c.__context__, b)
    self.assertIs(b.__context__, a)
    self.assertIs(a.__context__, c)

Also, would it be good to check that the traceback doesn't get stuck in a loop when printing? I tried it, and it terminates as you'd hope, but it's unclear to me why that's the case.