Files
ccxt_with_mt5/ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py
lz_db 0fab423a18 add
2025-11-16 12:31:03 +08:00

60 lines
2.1 KiB
Python

from __future__ import annotations
from dataclasses import dataclass, fields, make_dataclass
from typing import Dict, Optional, Tuple
@dataclass(frozen=True, eq=False)
class TupleDataclass:
"""
Dataclass that behaves like a tuple at the same time. Used when data has defined order and names.
For instance in case of named tuples or function responses.
"""
# getattr is called when attribute is not found in object. For instance when using object.unknown_attribute.
# This way pyright will know that there might be some arguments it doesn't know about and will stop complaining
# about some fields that don't exist statically.
def __getattr__(self, item):
# This should always fail - only attributes that don't exist end up in here.
# We use __getattribute__ to get the native error.
return super().__getattribute__(item)
def __getitem__(self, item: int):
field = fields(self)[item]
return getattr(self, field.name)
def __iter__(self):
return (getattr(self, field.name) for field in fields(self))
def as_tuple(self) -> Tuple:
"""
Creates a regular tuple from TupleDataclass.
"""
return tuple(self)
def as_dict(self) -> Dict:
"""
Creates a regular dict from TupleDataclass.
"""
return {field.name: getattr(self, field.name) for field in fields(self)}
# Added for backward compatibility with previous implementation based on NamedTuple
def _asdict(self):
return self.as_dict()
def __eq__(self, other):
if isinstance(other, TupleDataclass):
return self.as_tuple() == other.as_tuple()
return self.as_tuple() == other
@staticmethod
def from_dict(data: Dict, *, name: Optional[str] = None) -> TupleDataclass:
result_class = make_dataclass(
name or "TupleDataclass",
fields=[(key, type(value)) for key, value in data.items()],
bases=(TupleDataclass,),
frozen=True,
eq=False,
)
return result_class(**data)