Lib/inspect.py: Avoid wild replacement in formatannotation
Bug report
Source:
| def formatannotation(annotation, base_module=None): | |
| if getattr(annotation, '__module__', None) == 'typing': | |
| return repr(annotation).replace('typing.', '') | |
| if isinstance(annotation, types.GenericAlias): | |
| return str(annotation) | |
| if isinstance(annotation, type): | |
| if annotation.__module__ in ('builtins', base_module): | |
| return annotation.__qualname__ | |
| return annotation.__module__+'.'+annotation.__qualname__ | |
| return repr(annotation) |
An error replacement happens in:
repr(annotation).replace('typing.', '')
Suppose that I define a class or Protocol under foo/typing.py:
Then Union[int, A] will turn to Union[int, foo.A], but expected result is Union[int, foo.typing.A]
Any module with suffix like xxtyping will be replaced, such as nptyping.
Solution
Replace the line to:
def repl(match): text = match.group() if text.startswith('typing.'): return text[len('typing.'):] return text return re.sub(r'[\w\.]+', repl, repr(annotation))