Defer inspect import to reduce import time by ~25%#1547
Open
KRRT7 wants to merge 2 commits intopython-attrs:mainfrom
Open
Defer inspect import to reduce import time by ~25%#1547KRRT7 wants to merge 2 commits intopython-attrs:mainfrom
KRRT7 wants to merge 2 commits intopython-attrs:mainfrom
Conversation
Move `import inspect` from module level in `_compat.py` and `_make.py` into the functions that use it. Lazy-load `converters` and `validators` submodules from `attr/__init__.py` and `attrs/__init__.py` since they trigger class building (which invokes inspect) at import time. inspect is only used in three places, all at class-build time: - _compat._AnnotationExtractor.__init__() for signature extraction - _make.py line 709 for __attrs_pre_init__ arg detection - _make.py line 931 for cached_property return annotations Benchmark (Python 3.13, PYTHONDONTWRITEBYTECODE=1, 50 runs): - Before: 85.0ms ± 20.4ms - After: 64.7ms ± 12.0ms - Improvement: ~20ms (24%) All 1385 tests pass.
for more information, see https://pre-commit.ci
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
import inspectfrom module level to first use in_compat.pyand_make.pyconvertersandvalidatorssubmodules fromattr/__init__.pyandattrs/__init__.pyWhy
inspectcosts ~12ms to import (it pulls inast,re,enum,dis,tokenize) but is only used in three places, all at class-build time — never at module scope:_compat.py_AnnotationExtractor.__init__()inspect.signature()for converter type extraction_make.pyinspect.signature()for__attrs_pre_init__arg detection_make.pyinspect.signature()forcached_propertyreturn annotationsThe eager import of
inspectis triggered atimport attrtime becauseattr/__init__.pyeagerly importsvalidators, which uses@attrs()to define validator classes at module level, which triggers class building →Converter()→_AnnotationExtractor()→import inspect.By deferring
inspectinto the methods that use it and lazy-loadingconverters/validators, theinspectimport is deferred until the first attrs class is actually built by user code.Changes
_compat.py: Remove module-levelimport inspect, add it inside_AnnotationExtractor.__init__(),get_first_param_type(), andget_return_type()_make.py: Remove module-levelimport inspect, add it inside the two methods that use it (lines 709, 931)attr/__init__.py: Moveconvertersandvalidatorsfrom eager import to lazy-load via existing__getattr__attrs/__init__.py: Same lazy-load forconvertersandvalidatorsBenchmark
Controlled environment — Azure Standard_D2s_v5, Intel Xeon Platinum 8370C @ 2.80GHz, Python 3.13.13, Ubuntu 24.04, 100 runs, 10 warmup via hyperfine:
Reproduce with hyperfine
Requires hyperfine.
Reproduce with
-X importtimeTest plan
test_packaging.pydue to dev version string parsing — same on main)attr.validatorsandattr.convertersstill accessible via lazy loadinspectstill imported before any attrs class is built (deferred, not removed)