Title: typing.py: builtin LRU caches worsen leaks that exist in other code · Issue #98253 · python/cpython · GitHub
Open Graph Title: typing.py: builtin LRU caches worsen leaks that exist in other code · Issue #98253 · python/cpython
X Title: typing.py: builtin LRU caches worsen leaks that exist in other code · Issue #98253 · python/cpython
Description: Bug report I would like to report a refleak issue involving typing.py. The issue is that it internally uses LRU caches to cache certain type-related lookups, and these caches are not cleaned up when the Python interpreter shuts down. Thi...
Open Graph Description: Bug report I would like to report a refleak issue involving typing.py. The issue is that it internally uses LRU caches to cache certain type-related lookups, and these caches are not cleaned up whe...
X Description: Bug report I would like to report a refleak issue involving typing.py. The issue is that it internally uses LRU caches to cache certain type-related lookups, and these caches are not cleaned up whe...
Opengraph URL: https://github.com/python/cpython/issues/98253
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"typing.py: builtin LRU caches worsen leaks that exist in other code","articleBody":"# Bug report\r\n\r\nI would like to report a refleak issue involving `typing.py`. The issue is that it internally uses LRU caches to cache certain type-related lookups, and these caches are not cleaned up when the Python interpreter shuts down. This causes leaks that impede software development and debugging of refleaks in general.\r\n\r\nThis specific part of `typing.py` has already once been identified as a source of refleaks by @gvanrossum (context: https://bugs.python.org/issue28649).\r\n\r\nThe following provides a small reproducer via a trivial package (https://github.com/wjakob/typing_repro) that exposes a class named `A` using `nanobind`. Why `nanobind`? It is extremely paranoid about any leaks involving bound types, functions, and instances, and prints warning messages to tell the user about this after the interpreter has shut down (it performs checks following finalization using `Py_AtExit()`).\r\n\r\npreparation:\r\n```bash\r\n$ pip install git+https://github.com/wjakob/typing_repro\r\n```\r\n\r\nReproducer:\r\n```python\r\nfrom typing_repro import A\r\n\r\nimport pandas\r\nimport typing\r\n\r\ndef test(t: typing.Optional[A] = None):\r\n print(t)\r\n```\r\nRunning this yields\r\n```\r\nnanobind: leaked 1 types! \r\n - leaked type \"A\" \r\nnanobind: leaked 2 functions!\r\n - leaked function \"add\"\r\n - leaked function \"__init__\"\r\nnanobind: this is likely caused by a reference counting issue in the binding code.\r\n```\r\nNote the import of `pandas`, which serves the role of a bigger package that uses the `typing` module and thereby populates the LRU caches. `torch` (PyTorch) or `tensorflow` also cause the issue, as does `markupsafe`, others likely affected as well.\r\n\r\n**EDIT**: The problem that is common to all of these packages is that they leak some of their own types. For example, by `Py_INCREF`ing references to heap types within extension modules. Because these types use `typing.py` and thereby reference the LRU caches (which are never cleaned up), it causes a flurry of refleaks that cascade into other packages.\r\n\r\nRemoving the `test()` function or removing the type annotation fixes the issue. The problem is that declaration causes cache entries to be created that are never cleaned up, even when the interpreter finalizes.\r\n\r\nThere is another way to avoid the issue: at the bottom of the script, insert\r\n```\r\nfor f in typing._cleanups:\r\n f()\r\n```\r\nwhich clears the LRU caches in `typing.py`. Poof, errors gone. This leads me to suggest the following simple fix, to be added at the end of `typing.py`:\r\n\r\n```\r\ndef _cleanup_handler():\r\n for f in _cleanups:\r\n f()\r\n\r\nimport atexit as _atexit\r\n_atexit.register(_cleanup_handler)\r\n```\r\n\r\nThis will clear the caches and ensure that interpreter finalization can avoid those type annotation-related leaks.\r\n\r\n# Your environment\r\n\r\n- CPython versions tested on: 3.8.10 and 3.10.;7\r\n- Operating system and architecture: Linux and macOS\n\n\u003c!-- gh-pr-number: gh-98591 --\u003e\n* PR: gh-98591\n\u003c!-- /gh-pr-number --\u003e\n","author":{"url":"https://github.com/wjakob","@type":"Person","name":"wjakob"},"datePublished":"2022-10-13T22:18:52.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":19},"url":"https://github.com/98253/cpython/issues/98253"}
| 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:3df4f18f-1338-78c2-648a-735a49e72202 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | E9F8:260922:A11F7C:D756CB:696991AF |
| html-safe-nonce | f67e1b5366529ca71e5ad1c7bd0e19eda09c01790816bed278b3bdd3acc155f4 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFOUY4OjI2MDkyMjpBMTFGN0M6RDc1NkNCOjY5Njk5MUFGIiwidmlzaXRvcl9pZCI6Ijg4ODk2ODc1OTQwODEyOTI3MTkiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 9c8f0ed733ad15b0d031f401b6bc2c9301f633e5d32b8715d5b8acee57003bf5 |
| hovercard-subject-tag | issue:1408489622 |
| 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/98253/issue_layout |
| twitter:image | https://opengraph.githubassets.com/a87e7f36c329e31c6c7825610d69b86749ae6dac0184988eda4a4f1ec0f9f6b9/python/cpython/issues/98253 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/a87e7f36c329e31c6c7825610d69b86749ae6dac0184988eda4a4f1ec0f9f6b9/python/cpython/issues/98253 |
| og:image:alt | Bug report I would like to report a refleak issue involving typing.py. The issue is that it internally uses LRU caches to cache certain type-related lookups, and these caches are not cleaned up whe... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | wjakob |
| hostname | github.com |
| expected-hostname | github.com |
| None | 3542e147982176a7ebaa23dfb559c8af16f721c03ec560c68c56b64a0f35e751 |
| 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 | af80af7cc9e3de9c336f18b208a600950a3c187c |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width