AbstractData is not a dataclass, but it effectively assumes that any concrete subclass is such:
|
class AbstractData: |
|
"""Abstract data class.""" |
|
|
|
def __init__( |
|
self, data: dict[tuple[QubitId, int] | QubitId, npt.NDArray] | None = None |
|
): |
|
self.data = data if data is not None else {} |
|
|
|
def __getitem__(self, qubit: QubitId | tuple[QubitId, int]): |
|
"""Access data attribute member.""" |
|
return self.data[qubit] |
|
|
|
@property |
|
def params(self) -> dict: |
|
"""Convert non-arrays attributes into dict.""" |
|
global_dict = asdict(self) |
|
if hasattr(self, "data"): |
|
global_dict.pop("data") |
|
return global_dict |
Indeed, asdict() fails when it is called on something which is not a dataclass
In [1]: from dataclasses import dataclass, asdict
In [2]: class A:
...: def __init__(self, a: int) -> None:
...: self.a = a
...:
In [4]: a = A(3)
In [5]: asdict(a)
...
TypeError: asdict() should be called on dataclass instances
But, at the same time, if @dataclass is used, when __init__ is defined, you may obtain an attributed supported by the constructor, which is not traced by the dataclass structure:
In [6]: @dataclass
...: class A:
...: def __init__(self, a: int) -> None:
...: self.a = a
...:
In [7]: a = A(3)
In [8]: asdict(a)
Out[8]: {}
In [9]: a.a
Out[9]: 3
In practice, this forces to redefine the .data attribute in each subclass, despite being standardized and used in the AbstractData methods. Which is redundant and inconsistent.
It is not really worth to address this issue separately from #1301. At this point, it is just better to complete the transition, and consistently move to Pydantic.
However, since this is quite bug-prone, better to track on its own, until it will not be solved in any way.
AbstractDatais not a dataclass, but it effectively assumes that any concrete subclass is such:qibocal/src/qibocal/auto/operation.py
Lines 101 to 119 in 0a5078a
Indeed,
asdict()fails when it is called on something which is not adataclassBut, at the same time, if
@dataclassis used, when__init__is defined, you may obtain an attributed supported by the constructor, which is not traced by the dataclass structure:In practice, this forces to redefine the
.dataattribute in each subclass, despite being standardized and used in theAbstractDatamethods. Which is redundant and inconsistent.It is not really worth to address this issue separately from #1301. At this point, it is just better to complete the transition, and consistently move to Pydantic.
However, since this is quite bug-prone, better to track on its own, until it will not be solved in any way.