|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"""A simple attribute dictionary used for representing configuration options.""" |
|
|
|
from __future__ import absolute_import |
|
from __future__ import division |
|
from __future__ import print_function |
|
from __future__ import unicode_literals |
|
|
|
|
|
class AttrDict(dict): |
|
|
|
IMMUTABLE = '__immutable__' |
|
|
|
def __init__(self, *args, **kwargs): |
|
super().__init__(*args, **kwargs) |
|
self.__dict__[AttrDict.IMMUTABLE] = False |
|
|
|
def __getattr__(self, name): |
|
if name in self.__dict__: |
|
return self.__dict__[name] |
|
elif name in self: |
|
return self[name] |
|
else: |
|
raise AttributeError(name) |
|
|
|
def __setattr__(self, name, value): |
|
if not self.__dict__[AttrDict.IMMUTABLE]: |
|
if name in self.__dict__: |
|
self.__dict__[name] = value |
|
else: |
|
self[name] = value |
|
else: |
|
raise AttributeError( |
|
'Attempted to set "{}" to "{}", but AttrDict is immutable'.format(name, value) |
|
) |
|
|
|
def immutable(self, is_immutable): |
|
"""Set immutability to is_immutable and recursively apply the setting |
|
to all nested AttrDicts. |
|
""" |
|
self.__dict__[AttrDict.IMMUTABLE] = is_immutable |
|
|
|
for v in self.__dict__.values(): |
|
if isinstance(v, AttrDict): |
|
v.immutable(is_immutable) |
|
for v in self.values(): |
|
if isinstance(v, AttrDict): |
|
v.immutable(is_immutable) |
|
|
|
def is_immutable(self): |
|
return self.__dict__[AttrDict.IMMUTABLE] |
|
|