Created
September 23, 2025 15:29
-
-
Save PyroAVR/122cb25146cae7dae6b648a1e50457ee to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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