mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-07-19 00:20:32 +03:00
nixos-render-docs: add Freezable class
for most of our data classes we can use dataclasses.dataclass with frozen=True or even plain named tuples. the TOC structure we'll need to generate proper navigation links is most easily represented and used as a cyclic structure though, and for that we can use neither. if we want to make the TOC structures immutable (which seems like a good idea) we'll need a hack of *some* kind, and this hack seems like the least intrusive.
This commit is contained in:
parent
2ab8e742a5
commit
a7c25bb01f
1 changed files with 21 additions and 0 deletions
|
@ -0,0 +1,21 @@
|
|||
from typing import Any
|
||||
|
||||
_frozen_classes: dict[type, type] = {}
|
||||
|
||||
# make a derived class freezable (ie, disallow modifications).
|
||||
# we do this by changing the class of an instance at runtime when freeze()
|
||||
# is called, providing a derived class that is exactly the same except
|
||||
# for a __setattr__ that raises an error when called. this beats having
|
||||
# a field for frozenness and an unconditional __setattr__ that checks this
|
||||
# field because it does not insert anything into the class dict.
|
||||
class Freezeable:
|
||||
def freeze(self) -> None:
|
||||
cls = type(self)
|
||||
if not (frozen := _frozen_classes.get(cls)):
|
||||
def __setattr__(instance: Any, n: str, v: Any) -> None:
|
||||
raise TypeError(f'{cls.__name__} is frozen')
|
||||
frozen = type(cls.__name__, (cls,), {
|
||||
'__setattr__': __setattr__,
|
||||
})
|
||||
_frozen_classes[cls] = frozen
|
||||
self.__class__ = frozen
|
Loading…
Add table
Add a link
Reference in a new issue