# Copyright: 2005-2009 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# Author(s): Brian Harring (ferringb@gentoo.org)

__all__ = ["Mapping", "MutableMapping", "UserDict", "ProtectedDict",
	"LazyLoad", "slot_dict_class"]

import sys
import weakref

class Mapping(object):
	"""
	In python-3.0, the UserDict.DictMixin class has been replaced by
	Mapping and MutableMapping from the collections module, but 2to3
	doesn't currently account for this change:

	    http://bugs.python.org/issue2876

	As a workaround for the above issue, use this class as a substitute
	for UserDict.DictMixin so that code converted via 2to3 will run.
	"""

	__slots__ = ()

	def __iter__(self):
		return iter(self.keys())

	def keys(self):
		return list(self.__iter__())

	def __contains__(self, key):
		try:
			value = self[key]
		except KeyError:
			return False
		return True

	def iteritems(self):
		for k in self:
			yield (k, self[k])

	def iterkeys(self):
		return self.__iter__()

	def itervalues(self):
		for _, v in self.items():
			yield v

	def values(self):
		return [v for _, v in self.iteritems()]

	def items(self):
		return list(self.iteritems())

	def get(self, key, default=None):
		try:
			return self[key]
		except KeyError:
			return default

	def __repr__(self):
		return repr(dict(self.items()))

	def __len__(self):
		return len(list(self))

	if sys.hexversion >= 0x3000000:
		items = iteritems
		keys = __iter__
		values = itervalues

class MutableMapping(Mapping):
	"""
	A mutable vesion of the Mapping class.
	"""

	__slots__ = ()

	def clear(self):
		for key in list(self):
			del self[key]

	def setdefault(self, key, default=None):
		try:
			return self[key]
		except KeyError:
			self[key] = default
		return default

	def pop(self, key, *args):
		if len(args) > 1:
			raise TypeError("pop expected at most 2 arguments, got " + \
				repr(1 + len(args)))
		try:
			value = self[key]
		except KeyError:
			if args:
				return args[0]
			raise
		del self[key]
		return value

	def popitem(self):
		try:
			k, v = next(iter(self.items()))
		except StopIteration:
			raise KeyError('container is empty')
		del self[k]
		return (k, v)

	def update(self, *args, **kwargs):
		if len(args) > 1:
			raise TypeError(
				"expected at most 1 positional argument, got " + \
				repr(len(args)))
		other = None
		if args:
			other = args[0]
		if other is None:
			pass
		elif hasattr(other, 'iteritems'):
			# Use getattr to avoid interference from 2to3.
			for k, v in getattr(other, 'iteritems')():
				self[k] = v
		elif hasattr(other, 'items'):
			# Use getattr to avoid interference from 2to3.
			for k, v in getattr(other, 'items')():
				self[k] = v
		elif hasattr(other, 'keys'):
			for k in other.keys():
				self[k] = other[k]
		else:
			for k, v in other:
				self[k] = v
		if kwargs:
			self.update(kwargs)

class UserDict(MutableMapping):
	"""
	Use this class as a substitute for UserDict.UserDict so that
	code converted via 2to3 will run:

	     http://bugs.python.org/issue2876
	"""

	__slots__ = ('data',)

	def __init__(self, *args, **kwargs):

		self.data = {}

		if len(args) > 1:
			raise TypeError(
				"expected at most 1 positional argument, got " + \
				repr(len(args)))

		if args:
			self.update(args[0])

		if kwargs:
			self.update(kwargs)

	def __repr__(self):
		return repr(self.data)

	def __contains__(self, key):
		return key in self.data

	def __iter__(self):
		return iter(self.data)

	def __len__(self):
		return len(self.data)

	def __getitem__(self, key):
		return self.data[key]

	def __setitem__(self, key, item):
		self.data[key] = item

	def __delitem__(self, key):
		del self.data[key]

	def clear(self):
		self.data.clear()

	if sys.hexversion >= 0x3000000:
		keys = __iter__

class OrderedDict(UserDict):

	__slots__ = ('_order',)

	def __init__(self, *args, **kwargs):
		self._order = []
		UserDict.__init__(self, *args, **kwargs)

	def __iter__(self):
		return iter(self._order)

	def __setitem__(self, key, item):
		new_key = key not in self
		UserDict.__setitem__(self, key, item)
		if new_key:
			self._order.append(key)

	def __delitem__(self, key):
		UserDict.__delitem__(self, key)
		self._order.remove(key)

	def clear(self):
		UserDict.clear(self)
		del self._order[:]

	if sys.hexversion >= 0x3000000:
		keys = __iter__

class ProtectedDict(MutableMapping):
	"""
	given an initial dict, this wraps that dict storing changes in a secondary dict, protecting
	the underlying dict from changes
	"""
	__slots__=("orig","new","blacklist")

	def __init__(self, orig):
		self.orig = orig
		self.new = {}
		self.blacklist = {}


	def __setitem__(self, key, val):
		self.new[key] = val
		if key in self.blacklist:
			del self.blacklist[key]


	def __getitem__(self, key):
		if key in self.new:
			return self.new[key]
		if key in self.blacklist:
			raise KeyError(key)
		return self.orig[key]


	def __delitem__(self, key):
		if key in self.new:
			del self.new[key]
		elif key in self.orig:
			if key not in self.blacklist:
				self.blacklist[key] = True
				return
		raise KeyError(key)
			

	def __iter__(self):
		for k in self.new:
			yield k
		for k in self.orig:
			if k not in self.blacklist and k not in self.new:
				yield k

	def __contains__(self, key):
		return key in self.new or (key not in self.blacklist and key in self.orig)

	if sys.hexversion >= 0x3000000:
		keys = __iter__

class LazyLoad(Mapping):
	"""
	Lazy loading of values for a dict
	"""
	__slots__=("pull", "d")

	def __init__(self, pull_items_func, initial_items=[]):
		self.d = {}
		for k, v in initial_items:
			self.d[k] = v
		self.pull = pull_items_func

	def __getitem__(self, key):
		if key in self.d:
			return self.d[key]
		elif self.pull != None:
			self.d.update(self.pull())
			self.pull = None
		return self.d[key]

	def __iter__(self):
		if self.pull is not None:
			self.d.update(self.pull())
			self.pull = None
		return iter(self.d)

	def __contains__(self, key):
		if key in self.d:
			return True
		elif self.pull != None:
			self.d.update(self.pull())
			self.pull = None
		return key in self.d

	if sys.hexversion >= 0x3000000:
		keys = __iter__

_slot_dict_classes = weakref.WeakValueDictionary()

def slot_dict_class(keys, prefix="_val_"):
	"""
	Generates mapping classes that behave similar to a dict but store values
	as object attributes that are allocated via __slots__. Instances of these
	objects have a smaller memory footprint than a normal dict object.

	@param keys: Fixed set of allowed keys
	@type keys: Iterable
	@param prefix: a prefix to use when mapping
		attribute names from keys
	@type prefix: String
	@rtype: SlotDict
	@return: A class that constructs SlotDict instances
		having the specified keys.
	"""
	if isinstance(keys, frozenset):
		keys_set = keys
	else:
		keys_set = frozenset(keys)
	v = _slot_dict_classes.get((keys_set, prefix))
	if v is None:

		class SlotDict(object):

			allowed_keys = keys_set
			_prefix = prefix
			__slots__ = ("__weakref__",) + \
				tuple(prefix + k for k in allowed_keys)

			def __init__(self, *args, **kwargs):

				if len(args) > 1:
					raise TypeError(
						"expected at most 1 positional argument, got " + \
						repr(len(args)))

				if args:
					self.update(args[0])

				if kwargs:
					self.update(kwargs)

			def __iter__(self):
				for k, v in self.iteritems():
					yield k

			def __len__(self):
				l = 0
				for i in self.iteritems():
					l += 1
				return l

			def keys(self):
				return list(self)

			def iteritems(self):
				prefix = self._prefix
				for k in self.allowed_keys:
					try:
						yield (k, getattr(self, prefix + k))
					except AttributeError:
						pass

			def items(self):
				return list(self.iteritems())

			def itervalues(self):
				for k, v in self.iteritems():
					yield v

			def values(self):
				return list(self.itervalues())

			def __delitem__(self, k):
				try:
					delattr(self, self._prefix + k)
				except AttributeError:
					raise KeyError(k)

			def __setitem__(self, k, v):
				setattr(self, self._prefix + k, v)

			def setdefault(self, key, default=None):
				try:
					return self[key]
				except KeyError:
					self[key] = default
				return default

			def update(self, *args, **kwargs):
				if len(args) > 1:
					raise TypeError(
						"expected at most 1 positional argument, got " + \
						repr(len(args)))
				other = None
				if args:
					other = args[0]
				if other is None:
					pass
				elif hasattr(other, 'iteritems'):
					# Use getattr to avoid interference from 2to3.
					for k, v in getattr(other, 'iteritems')():
						self[k] = v
				elif hasattr(other, 'items'):
					# Use getattr to avoid interference from 2to3.
					for k, v in getattr(other, 'items')():
						self[k] = v
				elif hasattr(other, 'keys'):
					for k in other.keys():
						self[k] = other[k]
				else:
					for k, v in other:
						self[k] = v
				if kwargs:
					self.update(kwargs)

			def __getitem__(self, k):
				try:
					return getattr(self, self._prefix + k)
				except AttributeError:
					raise KeyError(k)

			def get(self, key, default=None):
				try:
					return self[key]
				except KeyError:
					return default

			def __contains__(self, k):
				return hasattr(self, self._prefix + k)

			def pop(self, key, *args):
				if len(args) > 1:
					raise TypeError(
						"pop expected at most 2 arguments, got " + \
						repr(1 + len(args)))
				try:
					value = self[key]
				except KeyError:
					if args:
						return args[0]
					raise
				del self[key]
				return value

			def popitem(self):
				try:
					k, v = self.iteritems().next()
				except StopIteration:
					raise KeyError('container is empty')
				del self[k]
				return (k, v)

			def copy(self):
				c = self.__class__()
				c.update(self)
				return c

			def clear(self):
				for k in self.allowed_keys:
					try:
						delattr(self, self._prefix + k)
					except AttributeError:
						pass

			def __str__(self):
				return str(dict(self.iteritems()))

			def __repr__(self):
				return repr(dict(self.iteritems()))

			if sys.hexversion >= 0x3000000:
				items = iteritems
				keys = __iter__
				values = itervalues

		v = SlotDict
		_slot_dict_classes[v.allowed_keys] = v
	return v
