Repository navigation
Annotations of _colorize.FancyCompleter dataclass are funky #148406
Description
Bug report
Bug description:
There's no easy way to describe this, but the recently added FancyCompleter dataclass` annotations are perhaps too fancy 😅
>>> import _colorize, pprint
>>> pprint.pprint(_colorize.FancyCompleter.__annotations__)
{'NoneType': '\x1b[1;32m',
'bool': '\x1b[1;32m',
'builtin_function_or_method': '\x1b[1;32m',
'bytes': '\x1b[1;32m',
'complex': '\x1b[1;32m',
'float': '\x1b[1;32m',
'function': '\x1b[1;32m',
'int': '\x1b[1;32m',
'method': '\x1b[1;32m',
'method_descriptor': '\x1b[1;32m',
'method_wrapper': '\x1b[1;32m',
'module': '\x1b[1;32m',
'str': '\x1b[1;32m',
'type': '\x1b[1;32m',
'wrapper_descriptor': '\x1b[1;32m'}The problem is the following attribute
str: str = ANSIColors.BOLD_GREEN
Removing this attribute results in expected behaviour
>>> import _colorize, pprint
>>> pprint.pprint(_colorize.FancyCompleter.__annotations__)
{'NoneType': <class 'str'>,
'bool': <class 'str'>,
'builtin_function_or_method': <class 'str'>,
'bytes': <class 'str'>,
'complex': <class 'str'>,
'float': <class 'str'>,
'function': <class 'str'>,
'int': <class 'str'>,
'method': <class 'str'>,
'method_descriptor': <class 'str'>,
'method_wrapper': <class 'str'>,
'module': <class 'str'>,
'type': <class 'str'>,
'wrapper_descriptor': <class 'str'>}
It looks like the overwriting of the str type is an expected behaviour of the annotation scopes.
Quoting from @JelleZijlstra 's blog about implementing PEP 695 - https://jellezijlstra.github.io/pep695.html
When Alias is evaluated, we’ll expect to resolve T from a cell variable (created by the annotation scope for the class’s type parameters), so we use LOAD_CLASSDICT_OR_DEREF, and int from the builtins, so we use LOAD_CLASSDICT_OR_GLOBAL. But in both cases, we need to account for the possibility that the class namespace was modified to inject a value for T or int before we evaluate the value of the type alias; that is why we need to first look at classdict.
I am not sure what is the best non-hacky solution here.
A hacky solution could be to use a different attribute name (e.g. string) and special-case the code in PyREPL that uses FancyCompleter. Happy to submit a PR unless somebody else has a better idea.
CPython versions tested on:
CPython main branch
Operating systems tested on:
Linux
Activity
JelleZijlstra commentedon Apr 11, 2026
An easy workaround would be to
import builtinsand then usebuiltins.strin the annotations for this class.picnixz commentedon Apr 11, 2026
Yeah, I think it's better to use
builtins.strhere or justfrom builtins import str as _str. One reason is that havingtype(something).__name__as a field is better for the mental model.mpkocher commentedon Apr 11, 2026
_colorizeis a private module and it doesn't have a public interface.I believe
_colorizeneeds to go through the PEP process before people should be start using it. Until the requirements are defined, it's difficult to discuss the current design.I think the design should lean more on leveraging types. But without requirements, it is hard to discuss the pros and cons of different approaches.
https://gist.github.com/mpkocher/8df5a9364cd9ec2cd6189dfee60192cb
DavidCEllis commentedon Apr 13, 2026
This is off topic. These incorrect annotations are causing an import performance issue for modules that already use
_colorize. A recent PR made dataclasses importreonly if needed for string annotations, these incorrect annotations mean that_colorizeis triggering this import unnecessarily.Discussion about the design should happen elsewhere.
mpkocher commentedon Apr 13, 2026
Sounds good. Thanks for clarifying.
gh-148406: Fix annotations of _colorize.FancyCompleter (#148408)
pythongh-148406: Fix annotations of _colorize.FancyCompleter (python#…