Reputation: 3535
I created a dataclass Foo
, which accepts any type that can be converted to int
:
import dataclasses
@dataclasses.dataclass
class Foo:
a: int
def __post_init__(self):
# Here `self.a` is converted to int, so this class accepts any type that can be converted to int
self.a = int(self.a)
# mypy error: Argument 1 to "Foo" has incompatible type "str"; expected "int",
foo = Foo("1")
print(foo)
print(foo.a + 2)
Output:
Foo(a=1)
3
However, mypy reports the below error:
error: Argument 1 to "Foo" has incompatible type "str"; expected "int"
If I fix the type of Foo.a
to Union[str, int]
, mypy reports another error:
error: Unsupported operand types for + ("str" and "int")
How to write a dataclass whose type of the field and the init argument are different?
Upvotes: 6
Views: 1697
Reputation: 281843
You want to decouple the a
field from the a
argument that __init__
takes. This would essentially require both an
a: InitVar[Union[SupportsInt, str]]
and an
a: int = field(init=False)
one to describe the __init__
argument, and one to describe the field. You can't do that, though. An InitVar and a field can't have the same name.
Your best option is to not use a dataclass, but if you're absolutely determined to do things that way, you'll have to write your own __init__
:
@dataclasses.dataclass
class Foo:
a: int
def __init__(self, a: typing.Union[typing.SupportsInt, str]):
self.a = int(a)
Upvotes: 5