diff --git a/mypy/stubdoc.py b/mypy/stubdoc.py index 7c8751bbd6ed..3dc2c7212e20 100644 --- a/mypy/stubdoc.py +++ b/mypy/stubdoc.py @@ -17,7 +17,7 @@ Sig: _TypeAlias = Tuple[str, str] -_TYPE_RE: Final = re.compile(r"^[a-zA-Z_][\w\[\], ]*(\.[a-zA-Z_][\w\[\], ]*)*$") +_TYPE_RE: Final = re.compile(r"^[a-zA-Z_][\w\[\]\(\), ]*(\.[a-zA-Z_][\w\[\]\(\), ]*)*$") _ARG_NAME_RE: Final = re.compile(r"\**[A-Za-z_][A-Za-z0-9_]*$") @@ -206,6 +206,11 @@ def add_token(self, token: tokenize.TokenInfo) -> None: self.reset() return self.ret_type = self.accumulator + m = re.match( + r"^[A-Za-z_][A-Za-z0-9_]*\.((ItemsView|KeysView|ValuesView).+)$", self.ret_type + ) + if m is not None: + self.ret_type = m.group(1) self.accumulator = "" self.state.pop() diff --git a/mypy/stubgenc.py b/mypy/stubgenc.py index 4fc9f8c6fdfa..7149c3e37c66 100755 --- a/mypy/stubgenc.py +++ b/mypy/stubgenc.py @@ -38,6 +38,10 @@ "Optional", "Tuple", "Union", + "Annotated", + "KeysView", + "ItemsView", + "ValuesView", ) @@ -252,7 +256,16 @@ def add_typing_import(output: list[str]) -> list[str]: if any(re.search(r"\b%s\b" % name, line) for line in output): names.append(name) if names: + if "Annotated" in names: + names.append("TYPE_CHECKING") + output = [ + "if TYPE_CHECKING:", + " if FixedSize not in vars():", + " def FixedSize(value):", + " pass", + ] + output return [f"from typing import {', '.join(names)}", ""] + output + else: return output.copy() @@ -268,8 +281,10 @@ def get_members(obj: object) -> list[tuple[str, Any]]: value = getattr(obj, name) except AttributeError: continue - else: - results.append((name, value)) + if inspect.isclass(value) and not value.__name__.isidentifier(): + # like `KeysView[str]` + continue + results.append((name, value)) return results