gh-137855: Lazy import inspect module in dataclasses#144387
Open
danielhollas wants to merge 3 commits intopython:mainfrom
Open
gh-137855: Lazy import inspect module in dataclasses#144387danielhollas wants to merge 3 commits intopython:mainfrom
inspect module in dataclasses#144387danielhollas wants to merge 3 commits intopython:mainfrom
Conversation
danielhollas
commented
Feb 2, 2026
|
|
||
| # If this is a wrapped function, unwrap it. | ||
| member = inspect.unwrap(member) | ||
| if not isinstance(member, type) and hasattr(member, '__wrapped__'): |
Contributor
Author
There was a problem hiding this comment.
This check was copied from the while loop in inspect.unwrap
Contributor
Author
|
Deferring the call to $ ./python -m cProfile -m _colorize | head 20
5604 function calls (5484 primitive calls) in 0.007 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
9/1 0.004 0.000 0.007 0.007 {built-in method builtins.exec}
1 0.000 0.000 0.007 0.007 <string>:1(<module>)
1 0.000 0.000 0.007 0.007 <frozen runpy>:199(run_module)
1 0.000 0.000 0.007 0.007 <frozen runpy>:65(_run_code)
1 0.000 0.000 0.007 0.007 _colorize.py:1(<module>)
7 0.000 0.000 0.006 0.001 dataclasses.py:1432(wrap)
7 0.000 0.000 0.006 0.001 dataclasses.py:986(_process_class)
7 0.000 0.000 0.004 0.001 dataclasses.py:478(add_fns_to_class)
4 0.000 0.000 0.001 0.000 inspect.py:3343(signature)
4 0.000 0.000 0.001 0.000 inspect.py:3056(from_callable)
12/4 0.000 0.000 0.001 0.000 inspect.py:2437(_signature_from_callable)
4 0.000 0.000 0.001 0.000 inspect.py:2331(_signature_from_function)
71/11 0.000 0.000 0.000 0.000 annotationlib.py:907(get_annotations)
8 0.000 0.000 0.000 0.000 dataclasses.py:541(__annotate__)
17/9 0.000 0.000 0.000 0.000 annotationlib.py:1114(_get_and_call_annotate) |
| # If this is a wrapped function, unwrap it. | ||
| member = inspect.unwrap(member) | ||
| if not isinstance(member, type) and hasattr(member, '__wrapped__'): | ||
| # TODO: Make this top-level lazy import once PEP810 lands |
Member
There was a problem hiding this comment.
PEP 810 is landing in 3.15, there is no point in adding an intermediate stage here, we can wait a few weeks.
| # See https://bugs.python.org/issue32929#msg312829 for an if-statement | ||
| # version of this table. | ||
|
|
||
| class AutoDocstring: |
Contributor
There was a problem hiding this comment.
I'm not sure we should add a new top-level entity here (despite it seems useful).
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.
inspectmodule is slow to import (see #117865) and is dragging down dataclasses with it.There are currently only two uses of
inspectin dataclasses, but they are a bit tricky to inline since they are on a direct code path when the@dataclassdecorator is executed.inspect.signatureis used to autogenerate class docstring (if one is not provided already)inspect.unwrapis used in a rather esoteric code path only for slotted classes, added in gh-90562: Improve zero argument support forsuper()in dataclasses whenslots=True#124692)For 1. I have used a descriptor protocol to generate the
__doc__attribute on demand (this is my first time messing with descriptors, apologies if I overlooked something).For 2. can be defferred by calling the unwrap functions only when really necessary (and hopefully this path is not common)
Benchmarks
./python -Ximporttime -c "import dataclasses"Before
After
Overall seems to be a solid 20-30% improvement.
TODO (if things done here seem acceptable):
ensure_lazy_importstest fixture