"""Weak reference support for Python.

This module is an implementation of PEP 205:

http://python.sourceforge.net/peps/pep-0205.html
"""

# Naming convention: Variables named "wr" are weak reference objects;
# they are called this instead of "ref" to avoid name collisions with
# the module-global ref() function imported from _weakref.

import UserDict

from _weakref import \
     getweakrefcount, \
     getweakrefs, \
     ref, \
     proxy, \
     ReferenceError, \
     CallableProxyType, \
     ProxyType, \
     ReferenceType

ProxyTypes = (ProxyType, CallableProxyType)

__all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
           "WeakKeyDictionary", "ReferenceType", "ProxyType",
           "CallableProxyType", "ProxyTypes", "WeakValueDictionary"]


class WeakValueDictionary(UserDict.UserDict):
    """Mapping class that references values weakly.

    Entries in the dictionary will be discarded when no strong
    reference to the value exists anymore
    """
    # We inherit the constructor without worrying about the input
    # dictionary; since it uses our .update() method, we get the right
    # checks (if the other dictionary is a WeakValueDictionary,
    # objects are unwrapped on the way out, and we always wrap on the
    # way in).

    def __getitem__(self, key):
        o = self.data.get(key)()
        if o is None:
            raise KeyError, key
        else:
            return o

    def __repr__(self):
        return "<WeakValueDictionary at %s>" % id(self)

    def __setitem__(self, key, value):
        def remove(o, data=self.data, key=key):
            del data[key]
        self.data[key] = ref(value, remove)

    def copy(self):
        new = WeakValueDictionary()
        for key, wr in self.data.items():
            o = wr()
            if o is not None:
                new[key] = o
        return new

    def get(self, key, default=None):
        try:
            wr = self.data[key]
        except KeyError:
            return default
        else:
            o = wr()
            if o is None:
                # This should only happen
                return default
            else:
                return o

    def items(self):
        L = []
        for key, wr in self.data.items():
            o = wr()
            if o is not None:
                L.append((key, o))
        return L

    def iteritems(self):
        return WeakValuedItemIterator(self)

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

    def itervalues(self):
        return WeakValuedValueIterator(self)

    def popitem(self):
        while 1:
            key, wr = self.data.popitem()
            o = wr()
            if o is not None:
                return key, o

    def setdefault(self, key, default):
        try:
            wr = self.data[key]
        except KeyError:
            def remove(o, data=self.data, key=key):
                del data[key]
            self.data[key] = ref(default, remove)
            return default
        else:
            return wr()

    def update(self, dict):
        d = self.data
        for key, o in dict.items():
            def remove(o, data=d, key=key):
                del data[key]
            d[key] = ref(o, remove)

    def values(self):
        L = []
        for wr in self.data.values():
            o = wr()
            if o is not None:
                L.append(o)
        return L


class WeakKeyDictionary(UserDict.UserDict):
    """ Mapping class that references keys weakly.

    Entries in the dictionary will be discarded when there is no
    longer a strong reference to the key. This can be used to
    associate additional data with an object owned by other parts of
    an application without adding attributes to those objects. This
    can be especially useful with objects that override attribute
    accesses.
    """

    def __init__(self, dict=None):
        self.data = {}
        if dict is not None: self.update(dict)
        def remove(k, data=self.data):
            del data[k]
        self._remove = remove

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

    def __repr__(self):
        return "<WeakKeyDictionary at %s>" % id(self)

    def __setitem__(self, key, value):
        self.data[ref(key, self._remove)] = value

    def copy(self):
        new = WeakKeyDictionary()
        for key, value in self.data.items():
            o = key()
            if o is not None:
                new[o] = value
        return new

    def get(self, key, default=None):
        return self.data.get(ref(key),default)

    def has_key(self, key):
        return self.data.has_key(ref(key))

    def items(self):
        L = []
        for key, value in self.data.items():
            o = key()
            if o is not None:
                L.append((o, value))
        return L

    def iteritems(self):
        return WeakKeyedItemIterator(self)

    def iterkeys(self):
        return WeakKeyedKeyIterator(self)
    __iter__ = iterkeys

    def itervalues(self):
        return self.data.itervalues()

    def keys(self):
        L = []
        for wr in self.data.keys():
            o = wr()
            if o is not None:
                L.append(o)
        return L

    def popitem(self):
        while 1:
            key, value = self.data.popitem()
            o = key()
            if o is not None:
                return o, value

    def setdefault(self, key, default):
        return self.data.setdefault(ref(key, self._remove),default)

    def update(self, dict):
        d = self.data
        for key, value in dict.items():
            d[ref(key, self._remove)] = value


class BaseIter:
    def __iter__(self):
        return self


class WeakKeyedKeyIterator(BaseIter):
    def __init__(self, weakdict):
        self._next = weakdict.data.iterkeys().next

    def next(self):
        while 1:
            wr = self._next()
            obj = wr()
            if obj is not None:
                return obj


class WeakKeyedItemIterator(BaseIter):
    def __init__(self, weakdict):
        self._next = weakdict.data.iteritems().next

    def next(self):
        while 1:
            wr, value = self._next()
            key = wr()
            if key is not None:
                return key, value


class WeakValuedValueIterator(BaseIter):
    def __init__(self, weakdict):
        self._next = weakdict.data.itervalues().next

    def next(self):
        while 1:
            wr = self._next()
            obj = wr()
            if obj is not None:
                return obj


class WeakValuedItemIterator(BaseIter):
    def __init__(self, weakdict):
        self._next = weakdict.data.iteritems().next

    def next(self):
        while 1:
            key, wr = self._next()
            value = wr()
            if value is not None:
                return key, value


# no longer needed
del UserDict
