From 0eaa652f44486b50c36125ade49507606d8283bf Mon Sep 17 00:00:00 2001 From: STerliakov Date: Sat, 5 Apr 2025 20:10:07 +0200 Subject: [PATCH 1/3] Support more constructs in stubgen AliasPrinter --- mypy/stubgen.py | 29 +++++++++++++++++++++++++++++ test-data/unit/stubgen.test | 28 ++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/mypy/stubgen.py b/mypy/stubgen.py index 881686adc5ed..e5148d19d6b5 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -103,6 +103,7 @@ OpExpr, OverloadedFuncDef, SetExpr, + SliceExpr, StarExpr, Statement, StrExpr, @@ -355,6 +356,9 @@ def visit_tuple_expr(self, node: TupleExpr) -> str: def visit_list_expr(self, node: ListExpr) -> str: return f"[{', '.join(n.accept(self) for n in node.items)}]" + def visit_set_expr(self, node: SetExpr) -> str: + return f"{{{', '.join(n.accept(self) for n in node.items)}}}" + def visit_dict_expr(self, o: DictExpr) -> str: dict_items = [] for key, value in o.items: @@ -369,6 +373,18 @@ def visit_ellipsis(self, node: EllipsisExpr) -> str: def visit_op_expr(self, o: OpExpr) -> str: return f"{o.left.accept(self)} {o.op} {o.right.accept(self)}" + def visit_unary_expr(self, o: UnaryExpr, /) -> str: + return f"{o.op}{o.expr.accept(self)}" + + def visit_slice_expr(self, o: SliceExpr, /) -> str: + blocks = [ + o.begin_index.accept(self) if o.begin_index is not None else "", + o.end_index.accept(self) if o.end_index is not None else "", + ] + if o.stride is not None: + blocks.append(o.stride.accept(self)) + return ":".join(blocks) + def visit_star_expr(self, o: StarExpr) -> str: return f"*{o.expr.accept(self)}" @@ -376,6 +392,19 @@ def visit_lambda_expr(self, o: LambdaExpr) -> str: # TODO: Required for among other things dataclass.field default_factory return self.stubgen.add_name("_typeshed.Incomplete") + def _visit_unsupported_expr(self, o: object) -> str: + # Something we do not understand. + return self.stubgen.add_name("_typeshed.Incomplete") + + visit_comparison_expr = _visit_unsupported_expr + visit_cast_expr = _visit_unsupported_expr + visit_conditional_expr = _visit_unsupported_expr + + visit_list_comprehension = _visit_unsupported_expr + visit_set_comprehension = _visit_unsupported_expr + visit_dictionary_comprehension = _visit_unsupported_expr + visit_generator_expr = _visit_unsupported_expr + def find_defined_names(file: MypyFile) -> set[str]: finder = DefinitionFinder() diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index bf17c34b99a7..16f1b172ae41 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -4269,6 +4269,34 @@ class Y(missing.Base): generated_kwargs: float generated_kwargs_: float +[case testDataclassAliasPrinterVariations_semanal] +from dataclasses import dataclass, field + +@dataclass +class X: + a: int = field(default=-1) + b: set[int] = field(default={0}) + c: list[int] = field(default=[x for x in range(5)]) + c: list[int] = field(default={x: x for x in range(5)}) + e: tuple[int, int] = field(default=(1, 2, 3)[1:]) + f: tuple[int, int] = field(default=(1, 2, 3)[:2]) + g: tuple[int, int] = field(default=(1, 2, 3)[::2]) + h: tuple[int] = field(default=(1, 2, 3)[1::2]) + +[out] +from _typeshed import Incomplete +from dataclasses import dataclass, field + +@dataclass +class X: + a: int = field(default=-1) + b: set[int] = field(default={0}) + c: list[int] = field(default=Incomplete) + e: tuple[int, int] = field(default=(1, 2, 3)[1:]) + f: tuple[int, int] = field(default=(1, 2, 3)[:2]) + g: tuple[int, int] = field(default=(1, 2, 3)[::2]) + h: tuple[int] = field(default=(1, 2, 3)[1::2]) + [case testDataclassTransform] # dataclass_transform detection only works with semantic analysis. # Test stubgen doesn't break too badly without it. From 2297c4da8c8aeb4bc4d071e827403d12a2250e05 Mon Sep 17 00:00:00 2001 From: STerliakov Date: Sat, 5 Apr 2025 20:29:56 +0200 Subject: [PATCH 2/3] mypyc does not understand method assignments? --- mypy/stubgen.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/mypy/stubgen.py b/mypy/stubgen.py index e5148d19d6b5..93a83077daf7 100755 --- a/mypy/stubgen.py +++ b/mypy/stubgen.py @@ -78,17 +78,21 @@ Block, BytesExpr, CallExpr, + CastExpr, ClassDef, ComparisonExpr, ComplexExpr, + ConditionalExpr, Decorator, DictExpr, + DictionaryComprehension, EllipsisExpr, Expression, ExpressionStmt, FloatExpr, FuncBase, FuncDef, + GeneratorExpr, IfStmt, Import, ImportAll, @@ -96,12 +100,14 @@ IndexExpr, IntExpr, LambdaExpr, + ListComprehension, ListExpr, MemberExpr, MypyFile, NameExpr, OpExpr, OverloadedFuncDef, + SetComprehension, SetExpr, SliceExpr, StarExpr, @@ -396,14 +402,26 @@ def _visit_unsupported_expr(self, o: object) -> str: # Something we do not understand. return self.stubgen.add_name("_typeshed.Incomplete") - visit_comparison_expr = _visit_unsupported_expr - visit_cast_expr = _visit_unsupported_expr - visit_conditional_expr = _visit_unsupported_expr + def visit_comparison_expr(self, o: ComparisonExpr) -> str: + return self._visit_unsupported_expr(o) - visit_list_comprehension = _visit_unsupported_expr - visit_set_comprehension = _visit_unsupported_expr - visit_dictionary_comprehension = _visit_unsupported_expr - visit_generator_expr = _visit_unsupported_expr + def visit_cast_expr(self, o: CastExpr) -> str: + return self._visit_unsupported_expr(o) + + def visit_conditional_expr(self, o: ConditionalExpr) -> str: + return self._visit_unsupported_expr(o) + + def visit_list_comprehension(self, o: ListComprehension) -> str: + return self._visit_unsupported_expr(o) + + def visit_set_comprehension(self, o: SetComprehension) -> str: + return self._visit_unsupported_expr(o) + + def visit_dictionary_comprehension(self, o: DictionaryComprehension) -> str: + return self._visit_unsupported_expr(o) + + def visit_generator_expr(self, o: GeneratorExpr) -> str: + return self._visit_unsupported_expr(o) def find_defined_names(file: MypyFile) -> set[str]: From e3680ce169e31a5c7d268e022eb1501e93f6fdba Mon Sep 17 00:00:00 2001 From: STerliakov Date: Sat, 5 Apr 2025 20:54:57 +0200 Subject: [PATCH 3/3] Fix duplicated name in test --- test-data/unit/stubgen.test | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index 16f1b172ae41..2c3ad3a4028d 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -4277,7 +4277,7 @@ class X: a: int = field(default=-1) b: set[int] = field(default={0}) c: list[int] = field(default=[x for x in range(5)]) - c: list[int] = field(default={x: x for x in range(5)}) + d: dict[int, int] = field(default={x: x for x in range(5)}) e: tuple[int, int] = field(default=(1, 2, 3)[1:]) f: tuple[int, int] = field(default=(1, 2, 3)[:2]) g: tuple[int, int] = field(default=(1, 2, 3)[::2]) @@ -4292,6 +4292,7 @@ class X: a: int = field(default=-1) b: set[int] = field(default={0}) c: list[int] = field(default=Incomplete) + d: dict[int, int] = field(default=Incomplete) e: tuple[int, int] = field(default=(1, 2, 3)[1:]) f: tuple[int, int] = field(default=(1, 2, 3)[:2]) g: tuple[int, int] = field(default=(1, 2, 3)[::2])