Spaces:
Running
Running
| from collections import defaultdict | |
| class DuplicatedNameError(NameError): | |
| pass | |
| class NameScope(object): | |
| def __init__(self): | |
| self._useset = set(['']) | |
| self._basenamemap = defaultdict(int) | |
| def is_used(self, name): | |
| return name in self._useset | |
| def register(self, name, deduplicate=False): | |
| if deduplicate: | |
| name = self.deduplicate(name) | |
| elif self.is_used(name): | |
| raise DuplicatedNameError(name) | |
| self._useset.add(name) | |
| return name | |
| def deduplicate(self, name): | |
| basename = name | |
| while self.is_used(name): | |
| ident = self._basenamemap[basename] + 1 | |
| self._basenamemap[basename] = ident | |
| name = "{0}.{1}".format(basename, ident) | |
| return name | |
| def get_child(self): | |
| return type(self)(parent=self) | |
| class _StrCaching(object): | |
| def _clear_string_cache(self): | |
| try: | |
| del self.__cached_str | |
| except AttributeError: | |
| pass | |
| def __str__(self): | |
| try: | |
| return self.__cached_str | |
| except AttributeError: | |
| s = self.__cached_str = self._to_string() | |
| return s | |
| class _StringReferenceCaching(object): | |
| def get_reference(self): | |
| try: | |
| return self.__cached_refstr | |
| except AttributeError: | |
| s = self.__cached_refstr = self._get_reference() | |
| return s | |
| class _HasMetadata(object): | |
| def set_metadata(self, name, node): | |
| """ | |
| Attach unnamed metadata *node* to the metadata slot *name* of this | |
| value. | |
| """ | |
| self.metadata[name] = node | |
| def _stringify_metadata(self, leading_comma=False): | |
| if self.metadata: | |
| buf = [] | |
| if leading_comma: | |
| buf.append("") | |
| buf += ["!{0} {1}".format(k, v.get_reference()) | |
| for k, v in self.metadata.items()] | |
| return ', '.join(buf) | |
| else: | |
| return '' | |