mirror of
https://github.com/python/cpython.git
synced 2025-09-08 18:01:44 +00:00
PEP 205, Weak References -- initial checkin.
This commit is contained in:
parent
2de7471d69
commit
41deb1efc2
9 changed files with 1158 additions and 4 deletions
117
Lib/weakref.py
Normal file
117
Lib/weakref.py
Normal file
|
@ -0,0 +1,117 @@
|
|||
"""Weak reference support for Python.
|
||||
|
||||
This module is an implementation of PEP 205:
|
||||
|
||||
http://python.sourceforge.net/peps/pep-0205.html
|
||||
"""
|
||||
|
||||
import UserDict
|
||||
|
||||
from _weakref import \
|
||||
getweakrefcount, \
|
||||
getweakrefs, \
|
||||
ref, \
|
||||
proxy, \
|
||||
ReferenceError, \
|
||||
CallableProxyType, \
|
||||
ProxyType, \
|
||||
ReferenceType
|
||||
|
||||
ProxyTypes = (ProxyType, CallableProxyType)
|
||||
|
||||
|
||||
def mapping(dict=None):
|
||||
return WeakDictionary(dict)
|
||||
|
||||
|
||||
class WeakDictionary(UserDict.UserDict):
|
||||
|
||||
# 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 WeakDictionary, 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 "<WeakDictionary 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 = WeakDictionary()
|
||||
for key, ref in self.data.items():
|
||||
o = ref()
|
||||
if o is not None:
|
||||
new[key] = o
|
||||
|
||||
def get(self, key, default):
|
||||
try:
|
||||
ref = self.data[key]
|
||||
except KeyError:
|
||||
return default
|
||||
else:
|
||||
o = ref()
|
||||
if o is None:
|
||||
# This should only happen
|
||||
return default
|
||||
else:
|
||||
return o
|
||||
|
||||
def items(self):
|
||||
L = self.data.items()
|
||||
for i in range(len(L)):
|
||||
key, ref = L[i]
|
||||
o = ref()
|
||||
if o is not None:
|
||||
L[i] = key, o
|
||||
return L
|
||||
|
||||
def popitem(self):
|
||||
while 1:
|
||||
key, ref = self.data.popitem()
|
||||
o = ref()
|
||||
if o is not None:
|
||||
return key, o
|
||||
|
||||
def setdefault(self, key, default):
|
||||
try:
|
||||
ref = self.data[key]
|
||||
except KeyError:
|
||||
def remove(o, data=self.data, key=key):
|
||||
del data[key]
|
||||
ref = ref(default, remove)
|
||||
self.data[key] = ref
|
||||
return default
|
||||
else:
|
||||
return ref()
|
||||
|
||||
def update(self, dict):
|
||||
d = self.data
|
||||
L = []
|
||||
for key, o in dict.items():
|
||||
def remove(o, data=d, key=key):
|
||||
del data[key]
|
||||
L.append(key, ref(o, remove))
|
||||
for key, r in L:
|
||||
d[key] = r
|
||||
|
||||
def values(self):
|
||||
L = []
|
||||
for ref in self.data.values():
|
||||
o = ref()
|
||||
if o is not None:
|
||||
L.append(o)
|
||||
return L
|
||||
|
||||
|
||||
# no longer needed
|
||||
del UserDict
|
Loading…
Add table
Add a link
Reference in a new issue