Total Complexity | 2 |
Total Lines | 26 |
Duplicated Lines | 0 % |
Changes | 0 |
1 | """Utility class for generating instances from attribute names.""" |
||
2 | |||
3 | import sys |
||
4 | import typing |
||
5 | import weakref |
||
6 | |||
7 | T = typing.TypeVar("T") # pylint: disable=invalid-name |
||
8 | |||
9 | ATTRIBUTE_CONSTRUCTORS: typing.MutableMapping = weakref.WeakKeyDictionary() |
||
10 | ATTRIBUTE_CACHE: typing.MutableMapping = weakref.WeakKeyDictionary() |
||
11 | |||
12 | |||
13 | class AttributeConstructor(typing.Generic[T]): |
||
14 | """An object that converts attribute access to constructor calls.""" |
||
15 | |||
16 | __slots__ = ("__weakref__",) |
||
17 | |||
18 | def __init__(self, constructor: typing.Callable[[str], T]): |
||
19 | ATTRIBUTE_CONSTRUCTORS[self] = constructor |
||
20 | ATTRIBUTE_CACHE[self] = {} |
||
21 | |||
22 | def __getattribute__(self, name: str) -> T: |
||
23 | name = sys.intern(name) |
||
24 | return ATTRIBUTE_CACHE[self].setdefault( |
||
25 | name, ATTRIBUTE_CONSTRUCTORS[self](name) |
||
26 | ) |
||
27 |