add
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user