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