|
6 | 6 | from typing_extensions import Final, Literal |
7 | 7 |
|
8 | 8 | import mypy.plugin # To avoid circular imports. |
| 9 | +from mypy.applytype import apply_generic_arguments |
9 | 10 | from mypy.checker import TypeChecker |
10 | 11 | from mypy.errorcodes import LITERAL_REQ |
11 | 12 | from mypy.expandtype import expand_type |
|
24 | 25 | Decorator, |
25 | 26 | Expression, |
26 | 27 | FuncDef, |
| 28 | + IndexExpr, |
27 | 29 | JsonDict, |
28 | 30 | LambdaExpr, |
29 | 31 | ListExpr, |
|
35 | 37 | SymbolTableNode, |
36 | 38 | TempNode, |
37 | 39 | TupleExpr, |
| 40 | + TypeApplication, |
38 | 41 | TypeInfo, |
39 | 42 | TypeVarExpr, |
40 | 43 | Var, |
@@ -664,6 +667,26 @@ def _parse_converter( |
664 | 667 | from mypy.checkmember import type_object_type # To avoid import cycle. |
665 | 668 |
|
666 | 669 | converter_type = type_object_type(converter_expr.node, ctx.api.named_type) |
| 670 | + elif ( |
| 671 | + isinstance(converter_expr, IndexExpr) |
| 672 | + and isinstance(converter_expr.analyzed, TypeApplication) |
| 673 | + and isinstance(converter_expr.base, RefExpr) |
| 674 | + and isinstance(converter_expr.base.node, TypeInfo) |
| 675 | + ): |
| 676 | + # The converter is a generic type. |
| 677 | + from mypy.checkmember import type_object_type # To avoid import cycle. |
| 678 | + |
| 679 | + converter_type = type_object_type(converter_expr.base.node, ctx.api.named_type) |
| 680 | + if isinstance(converter_type, CallableType): |
| 681 | + converter_type = apply_generic_arguments( |
| 682 | + converter_type, |
| 683 | + converter_expr.analyzed.types, |
| 684 | + ctx.api.msg.incompatible_typevar_value, |
| 685 | + converter_type, |
| 686 | + ) |
| 687 | + else: |
| 688 | + converter_type = None |
| 689 | + |
667 | 690 | if isinstance(converter_expr, LambdaExpr): |
668 | 691 | # TODO: should we send a fail if converter_expr.min_args > 1? |
669 | 692 | converter_info.init_type = AnyType(TypeOfAny.unannotated) |
|
0 commit comments