importlib_resources
importlib_resources copied to clipboard
Replace `inspect` usage with common CPython stdlib pattern
Part of #326.
This is the biggest source of import time and hopefully the least controversial to replace; based on local testing, replacing this improves it by ~30% on supported CPython versions and PyPy3.10.
This replaces the expensive inspect import and inspect.stack() usage with an expanded version of a frame inspection pattern used in the CPython standard library.
It's a bit more code, but it's a fairly reasonable amount considering it does the following:
- Has various fast paths.
- Chooses the fastest working method of inspection at first call to avoid needing to choose again in the future.
- Provides robust support for several alternate Python implementations that don't have many, if any, accessible stack frames.
- Obviously, avoids an expensive import.
References:
- https://github.com/python/cpython/blob/e2476398ee9911b6b0b80e3ca182647805fde81f/Lib/enum.py#L871-L879
- https://github.com/python/cpython/blob/e2476398ee9911b6b0b80e3ca182647805fde81f/Lib/doctest.py#L228-L234
- https://github.com/python/cpython/blob/e2476398ee9911b6b0b80e3ca182647805fde81f/Lib/dataclasses.py#L1625-L1632
- https://github.com/python/cpython/blob/e2476398ee9911b6b0b80e3ca182647805fde81f/Lib/typing.py#L1840-L1849
- https://github.com/taleinat/python-stdlib-sentinels/blob/410273e40bdbd1b58a63cebefdf8abcce6c620e3/sentinels/sentinels.py#L95-L124
This can be slimmed down (as evidenced by the stdlib's version), but I figured I'd start with the most robust version.