CfgNode represents an internal node in the configuration tree. It's a simple dict-like container that allows for attribute-based access to keys.
| 9 | |
| 10 | |
| 11 | class CfgNode(dict): |
| 12 | """ |
| 13 | CfgNode represents an internal node in the configuration tree. It's a simple |
| 14 | dict-like container that allows for attribute-based access to keys. |
| 15 | """ |
| 16 | def __init__(self, init_dict=None, key_list=None, new_allowed=False): |
| 17 | # Recursively convert nested dictionaries in init_dict into CfgNodes |
| 18 | init_dict = {} if init_dict is None else init_dict |
| 19 | key_list = [] if key_list is None else key_list |
| 20 | for k, v in init_dict.items(): |
| 21 | if type(v) is dict: |
| 22 | # Convert dict to CfgNode |
| 23 | init_dict[k] = CfgNode(v, key_list=key_list + [k]) |
| 24 | super(CfgNode, self).__init__(init_dict) |
| 25 | |
| 26 | def __getattr__(self, name): |
| 27 | if name in self: |
| 28 | return self[name] |
| 29 | else: |
| 30 | raise AttributeError(name) |
| 31 | |
| 32 | def __setattr__(self, name, value): |
| 33 | self[name] = value |
| 34 | |
| 35 | def __str__(self): |
| 36 | def _indent(s_, num_spaces): |
| 37 | s = s_.split("\n") |
| 38 | if len(s) == 1: |
| 39 | return s_ |
| 40 | first = s.pop(0) |
| 41 | s = [(num_spaces * " ") + line for line in s] |
| 42 | s = "\n".join(s) |
| 43 | s = first + "\n" + s |
| 44 | return s |
| 45 | |
| 46 | r = "" |
| 47 | s = [] |
| 48 | for k, v in sorted(self.items()): |
| 49 | seperator = "\n" if isinstance(v, CfgNode) else " " |
| 50 | attr_str = "{}:{}{}".format(str(k), seperator, str(v)) |
| 51 | attr_str = _indent(attr_str, 2) |
| 52 | s.append(attr_str) |
| 53 | r += "\n".join(s) |
| 54 | return r |
| 55 | |
| 56 | def __repr__(self): |
| 57 | return "{}({})".format(self.__class__.__name__, |
| 58 | super(CfgNode, self).__repr__()) |
| 59 | |
| 60 | |
| 61 | def load_cfg_from_cfg_file(file): |
no outgoing calls
no test coverage detected