141deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake"""Weak reference support for Python.
241deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
341deb1efc2f969b58e49af669cc20d15ccdb04c6Fred DrakeThis module is an implementation of PEP 205:
441deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
5ba08f072d29f2108503a97bf495315e072ae7787Alexandre Vassalottihttp://www.python.org/dev/peps/pep-0205/
641deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake"""
741deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
8bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake# Naming convention: Variables named "wr" are weak reference objects;
9bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake# they are called this instead of "ref" to avoid name collisions with
10bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake# the module-global ref() function imported from _weakref.
11bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake
1241deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drakeimport UserDict
1341deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
1433ad28b68dd6caadc1e6cb8f917665d6270e7b25Andrew M. Kuchlingfrom _weakref import (
1533ad28b68dd6caadc1e6cb8f917665d6270e7b25Andrew M. Kuchling     getweakrefcount,
1633ad28b68dd6caadc1e6cb8f917665d6270e7b25Andrew M. Kuchling     getweakrefs,
1733ad28b68dd6caadc1e6cb8f917665d6270e7b25Andrew M. Kuchling     ref,
1833ad28b68dd6caadc1e6cb8f917665d6270e7b25Andrew M. Kuchling     proxy,
1933ad28b68dd6caadc1e6cb8f917665d6270e7b25Andrew M. Kuchling     CallableProxyType,
2033ad28b68dd6caadc1e6cb8f917665d6270e7b25Andrew M. Kuchling     ProxyType,
2133ad28b68dd6caadc1e6cb8f917665d6270e7b25Andrew M. Kuchling     ReferenceType)
2241deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
23222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónssonfrom _weakrefset import WeakSet, _IterationGuard
24e6410c536c9dca5a3a7899888c071f41a1767291Michael Foord
25e029242d5cfb8a3879bdc7324db4449e6a8451cfFred Drakefrom exceptions import ReferenceError
26e029242d5cfb8a3879bdc7324db4449e6a8451cfFred Drake
27e029242d5cfb8a3879bdc7324db4449e6a8451cfFred Drake
2841deb1efc2f969b58e49af669cc20d15ccdb04c6Fred DrakeProxyTypes = (ProxyType, CallableProxyType)
2941deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
309a9d219f07656a9f1eb6f8beb2a9e2ee462b77f8Fred Drake__all__ = ["ref", "proxy", "getweakrefcount", "getweakrefs",
3188f801d40944960f5bc7e0b8631674371a100f90Brett Cannon           "WeakKeyDictionary", "ReferenceError", "ReferenceType", "ProxyType",
32e6410c536c9dca5a3a7899888c071f41a1767291Michael Foord           "CallableProxyType", "ProxyTypes", "WeakValueDictionary", 'WeakSet']
3341deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
34bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake
355e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwisclass WeakValueDictionary(UserDict.UserDict):
36bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake    """Mapping class that references values weakly.
3741deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
38bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake    Entries in the dictionary will be discarded when no strong
39bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake    reference to the value exists anymore
40bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake    """
4141deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake    # We inherit the constructor without worrying about the input
4241deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake    # dictionary; since it uses our .update() method, we get the right
439d2c85dec7262475b83d45fdb53651c9c069e1cbFred Drake    # checks (if the other dictionary is a WeakValueDictionary,
449d2c85dec7262475b83d45fdb53651c9c069e1cbFred Drake    # objects are unwrapped on the way out, and we always wrap on the
459d2c85dec7262475b83d45fdb53651c9c069e1cbFred Drake    # way in).
4641deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
47f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka    def __init__(*args, **kw):
48f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka        if not args:
49f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka            raise TypeError("descriptor '__init__' of 'WeakValueDictionary' "
50f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka                            "object needs an argument")
51f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka        self = args[0]
52f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka        args = args[1:]
53f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka        if len(args) > 1:
54f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka            raise TypeError('expected at most 1 arguments, got %d' % len(args))
550a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake        def remove(wr, selfref=ref(self)):
560a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake            self = selfref()
570a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake            if self is not None:
58222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                if self._iterating:
59222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                    self._pending_removals.append(wr.key)
60222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                else:
61222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                    del self.data[wr.key]
620a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake        self._remove = remove
63222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        # A list of keys to be removed
64222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        self._pending_removals = []
65222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        self._iterating = set()
669166e1a24ac7b15776ffd38e436fa51a9b002674Georg Brandl        UserDict.UserDict.__init__(self, *args, **kw)
670a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake
68222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson    def _commit_removals(self):
69222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        l = self._pending_removals
70222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        d = self.data
71222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        # We shouldn't encounter any KeyError, because this method should
72222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        # always be called *before* mutating the dict.
73222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        while l:
74222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            del d[l.pop()]
75222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson
7641deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake    def __getitem__(self, key):
774fd06e0170aa75e4873b73f733bfd3f3de19d967Fred Drake        o = self.data[key]()
7841deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        if o is None:
7941deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake            raise KeyError, key
8041deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        else:
8141deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake            return o
8241deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
83222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson    def __delitem__(self, key):
84222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        if self._pending_removals:
85222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            self._commit_removals()
86222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        del self.data[key]
87222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson
8861146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger    def __contains__(self, key):
8961146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger        try:
9061146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger            o = self.data[key]()
9161146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger        except KeyError:
9261146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger            return False
9361146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger        return o is not None
9461146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger
9561146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger    def has_key(self, key):
9661146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger        try:
9761146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger            o = self.data[key]()
9861146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger        except KeyError:
9961146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger            return False
10061146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger        return o is not None
10161146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger
10241deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake    def __repr__(self):
1039d2c85dec7262475b83d45fdb53651c9c069e1cbFred Drake        return "<WeakValueDictionary at %s>" % id(self)
10441deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
10541deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake    def __setitem__(self, key, value):
106222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        if self._pending_removals:
107222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            self._commit_removals()
1080a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake        self.data[key] = KeyedRef(value, self._remove, key)
10941deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
110222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson    def clear(self):
111222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        if self._pending_removals:
112222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            self._commit_removals()
113222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        self.data.clear()
114222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson
11541deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake    def copy(self):
1169d2c85dec7262475b83d45fdb53651c9c069e1cbFred Drake        new = WeakValueDictionary()
117bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake        for key, wr in self.data.items():
118bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake            o = wr()
11941deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake            if o is not None:
12041deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake                new[key] = o
1219d2c85dec7262475b83d45fdb53651c9c069e1cbFred Drake        return new
12241deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
123775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou    __copy__ = copy
124775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou
125775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou    def __deepcopy__(self, memo):
126775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou        from copy import deepcopy
127775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou        new = self.__class__()
128775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou        for key, wr in self.data.items():
129775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou            o = wr()
130775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou            if o is not None:
131775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou                new[deepcopy(key, memo)] = o
132775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou        return new
133775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou
1341d9e4b7de3d15007d5b9e7ac4b38f5e158d3c840Fred Drake    def get(self, key, default=None):
13541deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        try:
136bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake            wr = self.data[key]
13741deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        except KeyError:
13841deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake            return default
13941deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        else:
140bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake            o = wr()
14141deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake            if o is None:
14241deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake                # This should only happen
14341deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake                return default
14441deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake            else:
14541deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake                return o
14641deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
14741deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake    def items(self):
148312a5dc539b583abcbbf006942a4ceead9b9172bFred Drake        L = []
149bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake        for key, wr in self.data.items():
150bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake            o = wr()
15141deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake            if o is not None:
152312a5dc539b583abcbbf006942a4ceead9b9172bFred Drake                L.append((key, o))
15341deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        return L
15441deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
155101209d44ce063cd04fd6793d94991f8e6688428Fred Drake    def iteritems(self):
156222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        with _IterationGuard(self):
157222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            for wr in self.data.itervalues():
158222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                value = wr()
159222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                if value is not None:
160222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                    yield wr.key, value
161101209d44ce063cd04fd6793d94991f8e6688428Fred Drake
162101209d44ce063cd04fd6793d94991f8e6688428Fred Drake    def iterkeys(self):
163222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        with _IterationGuard(self):
164222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            for k in self.data.iterkeys():
165222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                yield k
16661146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger
167222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson    __iter__ = iterkeys
168101209d44ce063cd04fd6793d94991f8e6688428Fred Drake
169017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake    def itervaluerefs(self):
170017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        """Return an iterator that yields the weak references to the values.
171017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake
172017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        The references are not guaranteed to be 'live' at the time
173017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        they are used, so the result of calling the references needs
174017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        to be checked before being used.  This can be used to avoid
175017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        creating references that will cause the garbage collector to
176017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        keep the values around longer than needed.
177017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake
178017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        """
179222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        with _IterationGuard(self):
180222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            for wr in self.data.itervalues():
181222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                yield wr
182017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake
183101209d44ce063cd04fd6793d94991f8e6688428Fred Drake    def itervalues(self):
184222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        with _IterationGuard(self):
185222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            for wr in self.data.itervalues():
186222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                obj = wr()
187222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                if obj is not None:
188222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                    yield obj
189101209d44ce063cd04fd6793d94991f8e6688428Fred Drake
19041deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake    def popitem(self):
191222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        if self._pending_removals:
192222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            self._commit_removals()
19341deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        while 1:
194bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake            key, wr = self.data.popitem()
195bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake            o = wr()
19641deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake            if o is not None:
19741deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake                return key, o
19841deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
1992c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger    def pop(self, key, *args):
200222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        if self._pending_removals:
201222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            self._commit_removals()
2022c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger        try:
2032c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger            o = self.data.pop(key)()
2042c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger        except KeyError:
2052c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger            if args:
2062c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger                return args[0]
2072c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger            raise
2082c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger        if o is None:
2092c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger            raise KeyError, key
2102c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger        else:
2112c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger            return o
2122c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger
21380ce6dd5642025f5cdf0ba5556f08df0803f5636Walter Dörwald    def setdefault(self, key, default=None):
21441deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        try:
215bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake            wr = self.data[key]
21641deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        except KeyError:
217222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            if self._pending_removals:
218222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                self._commit_removals()
2190a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake            self.data[key] = KeyedRef(default, self._remove, key)
22041deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake            return default
22141deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        else:
222bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake            return wr()
22341deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
224f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka    def update(*args, **kwargs):
225f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka        if not args:
226f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka            raise TypeError("descriptor 'update' of 'WeakValueDictionary' "
227f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka                            "object needs an argument")
228f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka        self = args[0]
229f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka        args = args[1:]
230f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka        if len(args) > 1:
231f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka            raise TypeError('expected at most 1 arguments, got %d' % len(args))
232f522bbc9c27d5602b4d0a8287e6f383ba2399f51Serhiy Storchaka        dict = args[0] if args else None
233222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        if self._pending_removals:
234222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            self._commit_removals()
23541deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        d = self.data
23631017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger        if dict is not None:
23731017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger            if not hasattr(dict, "items"):
23831017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger                dict = type({})(dict)
23931017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger            for key, o in dict.items():
2400a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake                d[key] = KeyedRef(o, self._remove, key)
24131017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger        if len(kwargs):
24231017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger            self.update(kwargs)
24341deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
244017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake    def valuerefs(self):
245017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        """Return a list of weak references to the values.
246017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake
247017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        The references are not guaranteed to be 'live' at the time
248017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        they are used, so the result of calling the references needs
249017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        to be checked before being used.  This can be used to avoid
250017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        creating references that will cause the garbage collector to
251017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        keep the values around longer than needed.
252017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake
253017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        """
254017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        return self.data.values()
255017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake
25641deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake    def values(self):
25741deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        L = []
258bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake        for wr in self.data.values():
259bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake            o = wr()
26041deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake            if o is not None:
26141deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake                L.append(o)
26241deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake        return L
26341deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
2640a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake
2650a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drakeclass KeyedRef(ref):
2660a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake    """Specialized reference that includes a key corresponding to the value.
2670a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake
2680a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake    This is used in the WeakValueDictionary to avoid having to create
2690a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake    a function object for each key stored in the mapping.  A shared
2700a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake    callback object can use the 'key' attribute of a KeyedRef instead
2710a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake    of getting a reference to the key from an enclosing scope.
2720a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake
2730a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake    """
2740a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake
2750a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake    __slots__ = "key",
2760a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake
2770a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake    def __new__(type, ob, callback, key):
2780a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake        self = ref.__new__(type, ob, callback)
2790a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake        self.key = key
2800a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake        return self
2810a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake
2820a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake    def __init__(self, ob, callback, key):
2830a4dd390bf653128de8bc2e99da64967c8cdf86eFred Drake        super(KeyedRef,  self).__init__(ob, callback)
284746fe0fae5442403c64be34b87609601166e97c8Fred Drake
28541deb1efc2f969b58e49af669cc20d15ccdb04c6Fred Drake
2865e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwisclass WeakKeyDictionary(UserDict.UserDict):
287bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake    """ Mapping class that references keys weakly.
288bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake
289bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake    Entries in the dictionary will be discarded when there is no
290bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake    longer a strong reference to the key. This can be used to
291bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake    associate additional data with an object owned by other parts of
292bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake    an application without adding attributes to those objects. This
293bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake    can be especially useful with objects that override attribute
294bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake    accesses.
295bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake    """
2965e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis
2975e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis    def __init__(self, dict=None):
2985e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        self.data = {}
299746fe0fae5442403c64be34b87609601166e97c8Fred Drake        def remove(k, selfref=ref(self)):
300746fe0fae5442403c64be34b87609601166e97c8Fred Drake            self = selfref()
301746fe0fae5442403c64be34b87609601166e97c8Fred Drake            if self is not None:
302222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                if self._iterating:
303222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                    self._pending_removals.append(k)
304222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                else:
305222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                    del self.data[k]
3065e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        self._remove = remove
307222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        # A list of dead weakrefs (keys to be removed)
308222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        self._pending_removals = []
309222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        self._iterating = set()
310222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        if dict is not None:
311222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            self.update(dict)
312222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson
313222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson    def _commit_removals(self):
314222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        # NOTE: We don't need to call this method before mutating the dict,
315222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        # because a dead weakref never compares equal to a live weakref,
316222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        # even if they happened to refer to equal objects.
317222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        # However, it means keys may already have been removed.
318222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        l = self._pending_removals
319222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        d = self.data
320222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        while l:
321222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            try:
322222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                del d[l.pop()]
323222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            except KeyError:
324222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                pass
3255e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis
326b663a2ccbdd9bbd9a13f0cea743af709c53ec0c1Fred Drake    def __delitem__(self, key):
327886128f4f8b30b7e3623418eab063a3a8dd3495cTim Peters        del self.data[ref(key)]
328b663a2ccbdd9bbd9a13f0cea743af709c53ec0c1Fred Drake
3295e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis    def __getitem__(self, key):
3305e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        return self.data[ref(key)]
3315e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis
3325e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis    def __repr__(self):
3335e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        return "<WeakKeyDictionary at %s>" % id(self)
3345e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis
3355e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis    def __setitem__(self, key, value):
3365e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        self.data[ref(key, self._remove)] = value
3375e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis
3385e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis    def copy(self):
3395e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        new = WeakKeyDictionary()
3405e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        for key, value in self.data.items():
3415e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis            o = key()
3425e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis            if o is not None:
3435e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis                new[o] = value
3449d2c85dec7262475b83d45fdb53651c9c069e1cbFred Drake        return new
3455e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis
346775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou    __copy__ = copy
347775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou
348775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou    def __deepcopy__(self, memo):
349775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou        from copy import deepcopy
350775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou        new = self.__class__()
351775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou        for key, value in self.data.items():
352775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou            o = key()
353775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou            if o is not None:
354775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou                new[o] = deepcopy(value, memo)
355775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou        return new
356775fd66d7bd74cdedef536ff4f8c134ba718678fAntoine Pitrou
3571d9e4b7de3d15007d5b9e7ac4b38f5e158d3c840Fred Drake    def get(self, key, default=None):
3585e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        return self.data.get(ref(key),default)
3595e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis
3601d9e4b7de3d15007d5b9e7ac4b38f5e158d3c840Fred Drake    def has_key(self, key):
3613bae7ddf8e63889b185235f85a6695bc05d59059Fred Drake        try:
3623bae7ddf8e63889b185235f85a6695bc05d59059Fred Drake            wr = ref(key)
3633bae7ddf8e63889b185235f85a6695bc05d59059Fred Drake        except TypeError:
3643bae7ddf8e63889b185235f85a6695bc05d59059Fred Drake            return 0
36554f0222547b1e92cd018ef132307a6f793dc9505Raymond Hettinger        return wr in self.data
3661d9e4b7de3d15007d5b9e7ac4b38f5e158d3c840Fred Drake
36754f0222547b1e92cd018ef132307a6f793dc9505Raymond Hettinger    def __contains__(self, key):
36854f0222547b1e92cd018ef132307a6f793dc9505Raymond Hettinger        try:
36954f0222547b1e92cd018ef132307a6f793dc9505Raymond Hettinger            wr = ref(key)
37054f0222547b1e92cd018ef132307a6f793dc9505Raymond Hettinger        except TypeError:
37154f0222547b1e92cd018ef132307a6f793dc9505Raymond Hettinger            return 0
37254f0222547b1e92cd018ef132307a6f793dc9505Raymond Hettinger        return wr in self.data
373c411dbaeee29dba87d5432a92fe76ea65d8e25f0Tim Peters
3745e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis    def items(self):
3755e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        L = []
3765e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        for key, value in self.data.items():
3775e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis            o = key()
3785e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis            if o is not None:
3795e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis                L.append((o, value))
3805e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        return L
3815e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis
382101209d44ce063cd04fd6793d94991f8e6688428Fred Drake    def iteritems(self):
383222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        with _IterationGuard(self):
384222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            for wr, value in self.data.iteritems():
385222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                key = wr()
386222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                if key is not None:
387222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                    yield key, value
388101209d44ce063cd04fd6793d94991f8e6688428Fred Drake
389017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake    def iterkeyrefs(self):
390017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        """Return an iterator that yields the weak references to the keys.
391017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake
392017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        The references are not guaranteed to be 'live' at the time
393017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        they are used, so the result of calling the references needs
394017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        to be checked before being used.  This can be used to avoid
395017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        creating references that will cause the garbage collector to
396017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        keep the keys around longer than needed.
397017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake
398017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        """
399222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        with _IterationGuard(self):
400222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            for wr in self.data.iterkeys():
401222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                yield wr
402017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake
403101209d44ce063cd04fd6793d94991f8e6688428Fred Drake    def iterkeys(self):
404222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        with _IterationGuard(self):
405222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            for wr in self.data.iterkeys():
406222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                obj = wr()
407222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                if obj is not None:
408222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                    yield obj
40961146790992e0a00b76a6bf6ecc9e53289a1ecd7Raymond Hettinger
410222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson    __iter__ = iterkeys
411101209d44ce063cd04fd6793d94991f8e6688428Fred Drake
412101209d44ce063cd04fd6793d94991f8e6688428Fred Drake    def itervalues(self):
413222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson        with _IterationGuard(self):
414222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson            for value in self.data.itervalues():
415222b284911d1d4057f2034c41aa810693fc64f02Kristján Valur Jónsson                yield value
416101209d44ce063cd04fd6793d94991f8e6688428Fred Drake
417017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake    def keyrefs(self):
418017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        """Return a list of weak references to the keys.
419017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake
420017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        The references are not guaranteed to be 'live' at the time
421017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        they are used, so the result of calling the references needs
422017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        to be checked before being used.  This can be used to avoid
423017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        creating references that will cause the garbage collector to
424017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        keep the keys around longer than needed.
425017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake
426017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        """
427017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake        return self.data.keys()
428017e68c413be6262eb1e71b0f0c5676d6db33a43Fred Drake
4291d9e4b7de3d15007d5b9e7ac4b38f5e158d3c840Fred Drake    def keys(self):
4301d9e4b7de3d15007d5b9e7ac4b38f5e158d3c840Fred Drake        L = []
431bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake        for wr in self.data.keys():
432bd7f818c508248e12f88e51198cb5e9b861dacbfFred Drake            o = wr()
4331d9e4b7de3d15007d5b9e7ac4b38f5e158d3c840Fred Drake            if o is not None:
4341d9e4b7de3d15007d5b9e7ac4b38f5e158d3c840Fred Drake                L.append(o)
4351d9e4b7de3d15007d5b9e7ac4b38f5e158d3c840Fred Drake        return L
4361d9e4b7de3d15007d5b9e7ac4b38f5e158d3c840Fred Drake
4375e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis    def popitem(self):
4385e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        while 1:
4395e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis            key, value = self.data.popitem()
4405e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis            o = key()
4415e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis            if o is not None:
4425e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis                return o, value
4435e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis
4442c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger    def pop(self, key, *args):
4452c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger        return self.data.pop(ref(key), *args)
4462c2d322884ee72077a256ec3cd0aa9ce3580eedcRaymond Hettinger
44780ce6dd5642025f5cdf0ba5556f08df0803f5636Walter Dörwald    def setdefault(self, key, default=None):
4485e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        return self.data.setdefault(ref(key, self._remove),default)
4495e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis
45031017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger    def update(self, dict=None, **kwargs):
4515e1633365d8a48e96dd4f42c4e7c8729bc62c26dMartin v. Löwis        d = self.data
45231017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger        if dict is not None:
45331017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger            if not hasattr(dict, "items"):
45431017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger                dict = type({})(dict)
45531017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger            for key, value in dict.items():
45631017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger                d[ref(key, self._remove)] = value
45731017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger        if len(kwargs):
45831017aed36a5c5b0e4b16ca58bea09c9ce360134Raymond Hettinger            self.update(kwargs)
459