Problems encountered in handling inheritance
WhenMelancholy opened this issue · 2 comments
WhenMelancholy commented
A minimal code example for reproducibility:
from dataclasses import dataclass, field
from typing import Type, Optional, Literal, Tuple, Any
import hydra_zen as zen
@dataclass
class A:
x = 1
@dataclass
class B(A):
son: Tuple[A, ...] = field(default_factory=tuple)
conf = zen.just(
B(
son=(A(), A()),
)
)
print(to_yaml(conf))
Expected output:
_target_: __main__.B
son:
- _target_: __main__.A
- _target_: __main__.A
Actual output:
ValidationError: Invalid type assigned: Builds_A is not a subclass of A. value:
full_key: son[0]
reference_type=Tuple[A, ...]
object_type=list
Additional explanation: If the code is written in the way below, the problem can be avoided, but it would lose the advantages brought by type checking.
@dataclass
class B(A):
son: Tuple[Any, ...] = field(default_factory=tuple)
rsokl commented
It might take me a while to look into this, and I suspect that a fix may be too messy. Here is a hack that you can do in the meantime:
from dataclasses import dataclass, field
from typing import Type, Optional, Literal, Tuple, Any, TYPE_CHECKING
from typing_extensions import TypeAlias
import hydra_zen as zen
@dataclass
class A:
x :int = 1
TypeA: TypeAlias = A if TYPE_CHECKING else Any
@dataclass
class B(A):
son: Tuple[TypeA, ...] = field(default_factory=tuple)
conf = zen.just(
B(
son=(A(), A()),
)
)
print(to_yaml(conf))
This lets the type checkers see A
and keeps Hydra's runtime checks from blocking you.
rsokl commented
Closing this as I don't anticipate being able to find a solution for this and I think the above proposed work around is a reasonable one.