(cls)
| 640 | |
| 641 | @classmethod |
| 642 | def _exitfunc(cls): |
| 643 | # At shutdown invoke finalizers for which atexit is true. |
| 644 | # This is called once all other non-daemonic threads have been |
| 645 | # joined. |
| 646 | reenable_gc = False |
| 647 | try: |
| 648 | if cls._registry: |
| 649 | import gc |
| 650 | if gc.isenabled(): |
| 651 | reenable_gc = True |
| 652 | gc.disable() |
| 653 | pending = None |
| 654 | while True: |
| 655 | if pending is None or finalize._dirty: |
| 656 | pending = cls._select_for_exit() |
| 657 | finalize._dirty = False |
| 658 | if not pending: |
| 659 | break |
| 660 | f = pending.pop() |
| 661 | try: |
| 662 | # gc is disabled, so (assuming no daemonic |
| 663 | # threads) the following is the only line in |
| 664 | # this function which might trigger creation |
| 665 | # of a new finalizer |
| 666 | f() |
| 667 | except Exception: |
| 668 | sys.excepthook(*sys.exc_info()) |
| 669 | assert f not in cls._registry |
| 670 | finally: |
| 671 | # prevent any more finalizers from executing during shutdown |
| 672 | finalize._shutdown = True |
| 673 | if reenable_gc: |
| 674 | gc.enable() |
nothing calls this directly
no test coverage detected