Skip to content

Instantly share code, notes, and snippets.

@PyroAVR
Created September 23, 2025 15:29
Show Gist options
  • Select an option

  • Save PyroAVR/122cb25146cae7dae6b648a1e50457ee to your computer and use it in GitHub Desktop.

Select an option

Save PyroAVR/122cb25146cae7dae6b648a1e50457ee to your computer and use it in GitHub Desktop.
import dataclasses
from dataclasses import dataclass
from typing import ClassVar
class RenamedTo:
"""
beyond here there be dragons
A descriptor supporting default factories like dataclasses.field(), which
stores a name separate from the name in the Python source code for the
field.
"""
def __init__(self, name, *, default_factory = None):
# name to be emitted in serialization
self._serialized_name = name
# private name
self._name = None
self._owner = None
self._default = default_factory
def __set_name__(self, owner, name):
self._owner = owner
self._name = '_' + name
def __get__(self, obj, objtype=None):
if obj is None:
return self
return getattr(obj, self._name)
def __set__(self, obj, value):
if value == self:
value = self._default() if self._default is not None else None
setattr(obj, self._name, value)
@property
def name(self):
return self._serialized_name
@dataclass
class RenamingExample:
name: ClassVar[str] = "example-class-variable"
@property
def classname(self):
"""
Returns the class name in the "name" property of all subclasses.
"""
return type(self).name
def parameters(self):
"""
Convenience method to obtain a dictionary of all parameters with their
serialized names.
"""
r = dict()
for cls in type(self).mro()[:-1]:
for name in (x.name for x in dataclasses.fields(cls)):
attr = getattr(cls, name)
if isinstance(attr, RenamedTo):
r[attr.name] = getattr(self, name)
else:
r[name] = getattr(self, name)
return r
def to_dict(self):
"""
Example serialization function
"""
r = {'class': self.name}
r.update(self.parameters())
return r
@dataclass
class SubclassRenamingExample(RenamingExample):
name = "subclass"
# allows use of keywords...
_type: str = RenamedTo('type')
# ... and spaces!
python_name: list = RenamedTo('Serialized Name', default_factory = list)
def main():
x = SubclassRenamingExample("subclass1")
y = SubclassRenamingExample("subclass1", [1, 2, 3])
print(x.to_dict())
print(y.to_dict())
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment