| 24 | |
| 25 | |
| 26 | class SetOnceProperty(Generic[T]): |
| 27 | def __init__(self, wrapper=None): |
| 28 | self._wrapper = wrapper |
| 29 | |
| 30 | def __set_name__(self, owner, name: str): |
| 31 | self._name = f"_{name}" |
| 32 | |
| 33 | def __get__(self, obj, owner=None) -> T: |
| 34 | # if obj is None: |
| 35 | # return self |
| 36 | return getattr(obj, self._name) |
| 37 | |
| 38 | def __set__(self, obj, value): |
| 39 | try: |
| 40 | object.__getattribute__(obj, self._name) |
| 41 | except AttributeError: |
| 42 | if self._wrapper is not None: |
| 43 | value = self._wrapper(value) |
| 44 | setattr(obj, self._name, value) |
| 45 | return |
| 46 | raise AttributeError("trying to overwrite read-only property") |
| 47 | |
| 48 | def __delete___(self, obj): |
| 49 | raise AttributeError("trying to delete read-only property") |
| 50 | |
| 51 | |
| 52 | def with_optional_kwargs(decorator): |