| 98 | |
| 99 | |
| 100 | class Interceptor(object): |
| 101 | def __init__(self, |
| 102 | name, # type: str |
| 103 | default, # type: Any |
| 104 | hook, # type: Callable[..., Any] |
| 105 | args=None, # type: Optional[List[Any]] |
| 106 | kargs=None # type: Optional[Dict[str, Any]] |
| 107 | ): |
| 108 | # type: (...) -> None |
| 109 | self.name = name |
| 110 | self.intname = "_intercepted_%s" % name |
| 111 | self.default = default |
| 112 | self.hook = hook |
| 113 | self.args = args if args is not None else [] |
| 114 | self.kargs = kargs if kargs is not None else {} |
| 115 | |
| 116 | def __get__(self, obj, typ=None): |
| 117 | # type: (Conf, Optional[type]) -> Any |
| 118 | if not hasattr(obj, self.intname): |
| 119 | setattr(obj, self.intname, self.default) |
| 120 | return getattr(obj, self.intname) |
| 121 | |
| 122 | @staticmethod |
| 123 | def set_from_hook(obj, name, val): |
| 124 | # type: (Conf, str, bool) -> None |
| 125 | int_name = "_intercepted_%s" % name |
| 126 | setattr(obj, int_name, val) |
| 127 | |
| 128 | def __set__(self, obj, val): |
| 129 | # type: (Conf, Any) -> None |
| 130 | old = getattr(obj, self.intname, self.default) |
| 131 | val = self.hook(self.name, val, old, *self.args, **self.kargs) |
| 132 | setattr(obj, self.intname, val) |
| 133 | |
| 134 | |
| 135 | def _readonly(name): |