git.fiddlerwoaroof.com
libs/type_dict.py
3d5a515d
 import collections
 import copy
 
 class TypeDict(collections.MutableMapping):
 	def __init__(self, *args, **kw):
 		if '__default' in kw:
 			self.default = kw.pop('__default')
 
 		self.store = dict(args)
 		self.store.update(kw)
 
 	def get_store(self, cls):
 		cur = self.store
 		bases = cls.__bases__
 		if bases:
 			head, tail = bases[0], bases[1:]
 			while tail:
 				cur = self.store.setdefault(head, {})
 				head, tail = tail[0], tail[1:]
 		return cur
 
 	def __getitem__(self, cls):
 		store = self.get_store(cls)
 		try:
 			print store
 			return store[cls]
 		except KeyError:
 			if hasattr(self, 'default'):
 				return copy.copy(self.default)
 			else:
 				raise
 
 	def __setitem__(self, cls, value):
 		store = self.get_store(cls)
 		store[cls] = value
 	def __delitem__(self, cls):
 		store = self.get_store(cls)
 		del store[cls]
 
 	def __iter__(self):
 		return TypeDictIterator(self)
 	def __len__(self):
 		return len(self.slots)
 
 class _Null: pass
 
 class TypeDictIterator(collections.Iterator):
 	def __init__(self, dct):
 		self.dct = dct
 		self.dcts = [dct]
 		self.iters = [iter(dct)]
 		self.cur = self.iters[-1]
 
 	def next(self):
 		result = _Null
 		try: result = self.cur.next()
 		except StopIteration:
 			self.iters.pop()
 			self.dcts.pop()
 			if self.iters:
 				self.cur = self.iters[-1]
 				result = self.cur.next()
 			else:
 				raise StopIteration
 
 		if result in self.dcts[-1] and self.dcts[-1][result]:
 			self.iters.append(iter(self.dcts[-1][result]))
 			self.cur = self.iters[-1]
 
 		return result