(cls)
| 540 | |
| 541 | @classmethod |
| 542 | def _exitfunc(cls): |
| 543 | # At shutdown invoke finalizers for which atexit is true. |
| 544 | # This is called once all other non-daemonic threads have been |
| 545 | # joined. |
| 546 | reenable_gc = False |
| 547 | try: |
| 548 | if cls._registry: |
| 549 | import gc |
| 550 | if gc.isenabled(): |
| 551 | reenable_gc = True |
| 552 | gc.disable() |
| 553 | pending = None |
| 554 | while True: |
| 555 | if pending is None or finalize._dirty: |
| 556 | pending = cls._select_for_exit() |
| 557 | finalize._dirty = False |
| 558 | if not pending: |
| 559 | break |
| 560 | f = pending.pop() |
| 561 | try: |
| 562 | # gc is disabled, so (assuming no daemonic |
| 563 | # threads) the following is the only line in |
| 564 | # this function which might trigger creation |
| 565 | # of a new finalizer |
| 566 | f() |
| 567 | except Exception: |
| 568 | sys.excepthook(*sys.exc_info()) |
| 569 | assert f not in cls._registry |
| 570 | finally: |
| 571 | # prevent any more finalizers from executing during shutdown |
| 572 | finalize._shutdown = True |
| 573 | if reenable_gc: |
| 574 | gc.enable() |
nothing calls this directly
no test coverage detected