Title: Some pre-finalization callbacks can create other callbacks · Issue #136003 · python/cpython · GitHub
Open Graph Title: Some pre-finalization callbacks can create other callbacks · Issue #136003 · python/cpython
X Title: Some pre-finalization callbacks can create other callbacks · Issue #136003 · python/cpython
Description: Bug report Bug description: Currently, "pre-finalization" (callbacks executed while the interpreter is still fully intact) looks like this: cpython/Python/pylifecycle.c Lines 2023 to 2038 in 642e5df wait_for_thread_shutdown(tstate); // M...
Open Graph Description: Bug report Bug description: Currently, "pre-finalization" (callbacks executed while the interpreter is still fully intact) looks like this: cpython/Python/pylifecycle.c Lines 2023 to 2038 in 642e5d...
X Description: Bug report Bug description: Currently, "pre-finalization" (callbacks executed while the interpreter is still fully intact) looks like this: cpython/Python/pylifecycle.c Lines 2023 to 2038...
Opengraph URL: https://github.com/python/cpython/issues/136003
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Some pre-finalization callbacks can create other callbacks","articleBody":"# Bug report\n\n### Bug description:\n\nCurrently, \"pre-finalization\" (callbacks executed while the interpreter is still fully intact) looks like this:\n\nhttps://github.com/python/cpython/blob/642e5dfc74310d15bb81f8e94167590380a5fbfb/Python/pylifecycle.c#L2023-L2038\n\nThreads are joined first, then pending calls are executed, and finally atexit callbacks are executed. The problem is that any of these three can create one another, such as a pending call creating a thread, or an atexit handler scheduling a pending call. The best way to demonstrate this is by creating a new thread inside of an atexit callback:\n\n```python\nimport atexit\nimport threading\nimport time\n\n\ndef run():\n print(24)\n time.sleep(1)\n print(42)\n\n@atexit.register\ndef start_thread():\n threading.Thread(target=run).start()\n```\n\nOn 3.13+ (and probably earlier), you'll get one of these three outputs:\n\n1. `24` is printed.\n2. Nothing is printed.\n3. A fatal error occurs due to the stdout lock being unavailable.\n\nThis is because the thread created is incorrectly non-daemon, because the call to `threading._shutdown` (which should join it) has already happened.\n\n@ericsnowcurrently, I discussed this with you at the PyCon sprints. I think we came to the agreement that the best way to fix this is by looping until all three of them execute no callbacks.\n\n### CPython versions tested on:\n\nCPython main branch\n\n### Operating systems tested on:\n\nLinux\n\n\u003c!-- gh-linked-prs --\u003e\n### Linked PRs\n* gh-136004\n* gh-139129\n* gh-139225\n\u003c!-- /gh-linked-prs --\u003e\n","author":{"url":"https://github.com/ZeroIntensity","@type":"Person","name":"ZeroIntensity"},"datePublished":"2025-06-26T22:43:00.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":8},"url":"https://github.com/136003/cpython/issues/136003"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:7e00ef68-0cc4-d97e-1ade-55ce9311c59e |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 8852:4D95E:EFBE06:151754C:696A26E2 |
| html-safe-nonce | 2e3c8b4d2597d4fc26b0edec35a06d8962c244543b2c6fd5e303f37f0966c0bb |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4ODUyOjREOTVFOkVGQkUwNjoxNTE3NTRDOjY5NkEyNkUyIiwidmlzaXRvcl9pZCI6IjgwNDUwMjI3MzQxOTEzMDY0NjYiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | a26e02819ed5181d8b84e598067b3c82b697bd40fc2df3c612d6b7c51a0f6c26 |
| hovercard-subject-tag | issue:3180667722 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/python/cpython/136003/issue_layout |
| twitter:image | https://opengraph.githubassets.com/739db407445b5b99363d0a8e323cda306178ed54d963df76e5f6d9bcff6f7e4e/python/cpython/issues/136003 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/739db407445b5b99363d0a8e323cda306178ed54d963df76e5f6d9bcff6f7e4e/python/cpython/issues/136003 |
| og:image:alt | Bug report Bug description: Currently, "pre-finalization" (callbacks executed while the interpreter is still fully intact) looks like this: cpython/Python/pylifecycle.c Lines 2023 to 2038 in 642e5d... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | ZeroIntensity |
| hostname | github.com |
| expected-hostname | github.com |
| None | a1022f03e4f0d91ea173e4e5dac892c982e0588c62f1ce56121d755a320a3569 |
| turbo-cache-control | no-preview |
| go-import | github.com/python/cpython git https://github.com/python/cpython.git |
| octolytics-dimension-user_id | 1525981 |
| octolytics-dimension-user_login | python |
| octolytics-dimension-repository_id | 81598961 |
| octolytics-dimension-repository_nwo | python/cpython |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 81598961 |
| octolytics-dimension-repository_network_root_nwo | python/cpython |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | f472b8e6c7b3fdd5d0354972a3f4c516289bf0be |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width