(self)
| 564 | @threading_helper.reap_threads |
| 565 | @threading_helper.requires_working_threading() |
| 566 | def test_current_exceptions(self): |
| 567 | import threading |
| 568 | import traceback |
| 569 | |
| 570 | # Spawn a thread that blocks at a known place. Then the main |
| 571 | # thread does sys._current_frames(), and verifies that the frames |
| 572 | # returned make sense. |
| 573 | g_raised = threading.Event() |
| 574 | leave_g = threading.Event() |
| 575 | thread_info = [] # the thread's id |
| 576 | |
| 577 | def f123(): |
| 578 | g456() |
| 579 | |
| 580 | def g456(): |
| 581 | thread_info.append(threading.get_ident()) |
| 582 | while True: |
| 583 | try: |
| 584 | raise ValueError("oops") |
| 585 | except ValueError: |
| 586 | g_raised.set() |
| 587 | if leave_g.wait(timeout=support.LONG_TIMEOUT): |
| 588 | break |
| 589 | |
| 590 | t = threading.Thread(target=f123) |
| 591 | t.start() |
| 592 | g_raised.wait(timeout=support.LONG_TIMEOUT) |
| 593 | |
| 594 | try: |
| 595 | self.assertEqual(len(thread_info), 1) |
| 596 | thread_id = thread_info[0] |
| 597 | |
| 598 | d = sys._current_exceptions() |
| 599 | for tid in d: |
| 600 | self.assertIsInstance(tid, int) |
| 601 | self.assertGreater(tid, 0) |
| 602 | |
| 603 | main_id = threading.get_ident() |
| 604 | self.assertIn(main_id, d) |
| 605 | self.assertIn(thread_id, d) |
| 606 | self.assertEqual(None, d.pop(main_id)) |
| 607 | |
| 608 | # Verify that the captured thread frame is blocked in g456, called |
| 609 | # from f123. This is a little tricky, since various bits of |
| 610 | # threading.py are also in the thread's call stack. |
| 611 | exc_value = d.pop(thread_id) |
| 612 | stack = traceback.extract_stack(exc_value.__traceback__.tb_frame) |
| 613 | for i, (filename, lineno, funcname, sourceline) in enumerate(stack): |
| 614 | if funcname == "f123": |
| 615 | break |
| 616 | else: |
| 617 | self.fail("didn't find f123() on thread's call stack") |
| 618 | |
| 619 | self.assertEqual(sourceline, "g456()") |
| 620 | |
| 621 | # And the next record must be for g456(). |
| 622 | filename, lineno, funcname, sourceline = stack[i+1] |
| 623 | self.assertEqual(funcname, "g456") |
nothing calls this directly
no test coverage detected