Shouldn't fields of generic dataclasses be specialized in inheritance?

Hello all.

I noticed the following behaviour today. Consider a dataclass with Generic type:

from dataclasses import dataclass, fields
from typing import Generic, TypeVar

@dataclass
class Foo(Generic[T]):
    value: T

now suppose I inherit from a specialized version of Foo:

@dataclass
class Bar(Foo[str]):
    pass

I expected the value field of the class Bar to have type str, but when I try to create a value Bar(5), I have no complaints from mypy and when I check in type using the fields function, the type in the Field definition still ~T:

> fields(Foo)[0]
Field(name='value',type=~T,default=<dataclasses._MISSING_TYPE object at 0x7f72c88e9400>,default_factory=<dataclasses._MISSING_TYPE object at 0x7f72c88e9400>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),kw_only=False,_field_type=_FIELD)

> fields(Foo)[0].type
~T

Is this the expected behaviour? I suggest that when the type is specialized with the Foo[str] call, there’s a specialization of the types internally in the dataclass.

Does that make sense?

I think your expectations do make sense.

I’m not surprised that the fields information doesn’t work that way. It would need some implementation in stdlib dataclass

I’m a little bit surprised that it doesn’t work for mypy.
The pyright type checker does complain about the Bar(5)

1 Like