-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Open
Labels
bugmypy got something wrongmypy got something wrong
Description
Bug Report
Unable to overload new method with generic input
To Reproduce
How can I type hint my __new__ implementation using a generic input?
So I have a class that can store str or decimal.Decimal instances, and it subclasses the input str or decimal.Decimal class.
This code works in mypy and python:
from __future__ import annotations
import typing
import typing_extensions
import decimal
import random
T = typing.TypeVar('T', str, decimal.Decimal)
class StrOrDecimal(typing.Generic[T]):
@typing.overload
def __new__(cls, arg: decimal.Decimal) -> StrOrDecimalTyped.Decimal.StrOrDecimal[decimal.Decimal]:
...
@typing.overload
def __new__(cls, arg: str) -> StrOrDecimalTyped.Str.StrOrDecimal[str]:
...
# def __new__(cls, arg: typing.Union[str, decimal.Decimal]): does not work
def __new__(cls, arg): # works
if isinstance(arg, decimal.Decimal):
return super(cls, StrOrDecimalTyped.Decimal.StrOrDecimal).__new__(StrOrDecimalTyped.Decimal.StrOrDecimal, arg)
if isinstance(arg, str):
return super(cls, StrOrDecimalTyped.Str.StrOrDecimal).__new__(StrOrDecimalTyped.Str.StrOrDecimal, arg)
raise ValueError('Invalid value')
_StrOrDecimal = StrOrDecimal
# needed for mypy
class StrOrDecimalTyped:
class Str:
class StrOrDecimal(_StrOrDecimal[T], str):
pass
class Decimal:
class StrOrDecimal(_StrOrDecimal[T], decimal.Decimal):
pass
a_val = 'a'
a = StrOrDecimal(a_val)
print(a)
b_val = decimal.Decimal('1.2')
b = StrOrDecimal(b_val)
print(b)
choices: typing.List[typing.Union[str, decimal.Decimal]] = [a_val, b_val]
c_val = random.choice(choices)
c = StrOrDecimal(c_val)
try:
reveal_type(a)
reveal_type(b)
reveal_type(c)
except NameError:
typing_extensions.reveal_type(a)
typing_extensions.reveal_type(b)
typing_extensions.reveal_type(c)
But if I use either of these signatures:
def __new__(cls, arg: typing.Union[str, decimal.Decimal]):
def __new__(cls, arg: T):
I get this error:
generic.py:19: error: Argument 1 to "__new__" of "StrOrDecimal" has incompatible type "Type[generic.StrOrDecimalTyped.Decimal.StrOrDecimal[Any]]"; expected "Type[generic.StrOrDecimal[T]]"
How can I fix it?
Expected Behavior
I expect to be able to use T as the input type
Actual Behavior
Mypy throws the above error
Your Environment
- Mypy version used:
- Mypy command-line flags:
- Mypy configuration options from
mypy.ini(and other config files): - Python version used:
ArthurBook
Metadata
Metadata
Assignees
Labels
bugmypy got something wrongmypy got something wrong