You could use make_dataclass
to create X
on the fly:
X = make_dataclass('X', [('i', int), ('s', str)])
x = X(i=42, s="text")
asdict(x)
# {'i': 42, 's': 'text'}
Or as a derived class:
@dataclass
class X:
i: int
x = X(i=42)
x.__class__ = make_dataclass('Y', fields=[('s', str)], bases=(X,))
x.s="text"
asdict(x)
# {'i': 42, 's': 'text'}