Skip to content

Commit 54d582d

Browse files
committed
Also add support for generic types as converters
1 parent befa170 commit 54d582d

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

mypy/plugins/attrs.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from typing_extensions import Final, Literal
77

88
import mypy.plugin # To avoid circular imports.
9+
from mypy.applytype import apply_generic_arguments
910
from mypy.checker import TypeChecker
1011
from mypy.errorcodes import LITERAL_REQ
1112
from mypy.expandtype import expand_type
@@ -24,6 +25,7 @@
2425
Decorator,
2526
Expression,
2627
FuncDef,
28+
IndexExpr,
2729
JsonDict,
2830
LambdaExpr,
2931
ListExpr,
@@ -35,6 +37,7 @@
3537
SymbolTableNode,
3638
TempNode,
3739
TupleExpr,
40+
TypeApplication,
3841
TypeInfo,
3942
TypeVarExpr,
4043
Var,
@@ -664,6 +667,26 @@ def _parse_converter(
664667
from mypy.checkmember import type_object_type # To avoid import cycle.
665668

666669
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+
667690
if isinstance(converter_expr, LambdaExpr):
668691
# TODO: should we send a fail if converter_expr.min_args > 1?
669692
converter_info.init_type = AnyType(TypeOfAny.unannotated)

test-data/unit/check-attr.test

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -509,12 +509,9 @@ class Other(Generic[T]):
509509
def __init__(self, x: T) -> None:
510510
pass
511511

512-
def other_converter(x: Callable[..., T]) -> Other[Callable[..., T]]:
513-
return Other(x)
514-
515512
@attr.s(auto_attribs=True)
516513
class B(Generic[T]):
517-
x: Other[Callable[..., T]] = attr.ib(converter=other_converter)
514+
x: Other[Callable[..., T]] = attr.ib(converter=Other[Callable[..., T]])
518515

519516
b1 = B(get_int)
520517
reveal_type(b1) # N: Revealed type is "__main__.B[builtins.int]"

0 commit comments

Comments
 (0)