From 5b46f1c4baeb6271cbf3fc4ab57f8d78b0232e3f Mon Sep 17 00:00:00 2001 From: sobolevn Date: Mon, 12 Aug 2024 19:40:32 +0300 Subject: [PATCH] [stubgen] Fix crash on literal class-level keywords (#17663) Closes https://github.com/python/mypy/issues/17661 --- mypy/stubgen.py | 22 ++++++++++++++++++++-- test-data/unit/stubgen.test | 10 ++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/mypy/stubgen.py b/mypy/stubgen.py index f4a418838161..14417f55545e 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -305,9 +305,26 @@ def visit_name_expr(self, node: NameExpr) -> str: def visit_member_expr(self, o: MemberExpr) -> str: return self._visit_ref_expr(o) - def visit_str_expr(self, node: StrExpr) -> str: + def _visit_literal_node( + self, node: StrExpr | BytesExpr | IntExpr | FloatExpr | ComplexExpr + ) -> str: return repr(node.value) + def visit_str_expr(self, node: StrExpr) -> str: + return self._visit_literal_node(node) + + def visit_bytes_expr(self, node: BytesExpr) -> str: + return f"b{self._visit_literal_node(node)}" + + def visit_int_expr(self, node: IntExpr) -> str: + return self._visit_literal_node(node) + + def visit_float_expr(self, node: FloatExpr) -> str: + return self._visit_literal_node(node) + + def visit_complex_expr(self, node: ComplexExpr) -> str: + return self._visit_literal_node(node) + def visit_index_expr(self, node: IndexExpr) -> str: base_fullname = self.stubgen.get_fullname(node.base) if base_fullname == "typing.Union": @@ -805,7 +822,8 @@ def get_base_types(self, cdef: ClassDef) -> list[str]: for name, value in cdef.keywords.items(): if name == "metaclass": continue # handled separately - base_types.append(f"{name}={value.accept(p)}") + processed_value = value.accept(p) or "..." # at least, don't crash + base_types.append(f"{name}={processed_value}") return base_types def get_class_decorators(self, cdef: ClassDef) -> list[str]: diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index 94d0edb2ae37..fe0538159aa3 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -4405,3 +4405,13 @@ Y = int | None Z = Incomplete W = int | str | None R = type[int | str] | None + +[case testClassInheritanceWithKeywordsConstants] +class Test(Whatever, a=1, b='b', c=True, d=1.5, e=None, f=1j, g=b'123'): ... +[out] +class Test(Whatever, a=1, b='b', c=True, d=1.5, e=None, f=1j, g=b'123'): ... + +[case testClassInheritanceWithKeywordsDynamic] +class Test(Whatever, keyword=SomeName * 2, attr=SomeName.attr): ... +[out] +class Test(Whatever, keyword=SomeName * 2, attr=SomeName.attr): ...