diff --git a/mypy/stubgen.py b/mypy/stubgen.py index 881686adc5ed..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,13 +100,16 @@ IndexExpr, IntExpr, LambdaExpr, + ListComprehension, ListExpr, MemberExpr, MypyFile, NameExpr, OpExpr, OverloadedFuncDef, + SetComprehension, SetExpr, + SliceExpr, StarExpr, Statement, StrExpr, @@ -355,6 +362,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 +379,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 +398,31 @@ 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") + + def visit_comparison_expr(self, o: ComparisonExpr) -> str: + return self._visit_unsupported_expr(o) + + 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]: finder = DefinitionFinder() diff --git a/test-data/unit/stubgen.test b/test-data/unit/stubgen.test index bf17c34b99a7..2c3ad3a4028d 100644 --- a/test-data/unit/stubgen.test +++ b/test-data/unit/stubgen.test @@ -4269,6 +4269,35 @@ 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)]) + 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]) + 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) + 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]) + 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.