Skip to content

Lib/inspect.py: Avoid wild replacement in formatannotation #96073

Closed
@iyume

Description

@iyume

Bug report

Source:

cpython/Lib/inspect.py

Lines 1449 to 1458 in 91afe66

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:

class A:
    pass

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))

Metadata

Metadata

Assignees

Labels

type-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions