mirror of
https://github.com/python/cpython.git
synced 2025-08-25 19:24:42 +00:00
SF patch #667730: More DictMixin
* Adds missing pop() methods to weakref.py * Expands test suite to broaden coverage of objects with a mapping interface. Contributed by Sebastien Keim.
This commit is contained in:
parent
42182ebaf6
commit
2c2d322884
6 changed files with 222 additions and 4 deletions
|
@ -185,10 +185,28 @@ class StatAttributeTests(unittest.TestCase):
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
from test_userdict import TestMappingProtocol
|
||||||
|
|
||||||
|
class EnvironTests(TestMappingProtocol):
|
||||||
|
"""check that os.environ object conform to mapping protocol"""
|
||||||
|
_tested_class = None
|
||||||
|
def _reference(self):
|
||||||
|
return {"KEY1":"VALUE1", "KEY2":"VALUE2", "KEY3":"VALUE3"}
|
||||||
|
def _empty_mapping(self):
|
||||||
|
os.environ.clear()
|
||||||
|
return os.environ
|
||||||
|
def setUp(self):
|
||||||
|
self.__save = dict(os.environ)
|
||||||
|
os.environ.clear()
|
||||||
|
def tearDown(self):
|
||||||
|
os.environ.clear()
|
||||||
|
os.environ.update(self.__save)
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
suite = unittest.TestSuite()
|
suite = unittest.TestSuite()
|
||||||
suite.addTest(unittest.makeSuite(TemporaryFileTests))
|
suite.addTest(unittest.makeSuite(TemporaryFileTests))
|
||||||
suite.addTest(unittest.makeSuite(StatAttributeTests))
|
suite.addTest(unittest.makeSuite(StatAttributeTests))
|
||||||
|
suite.addTest(unittest.makeSuite(EnvironTests))
|
||||||
run_suite(suite)
|
run_suite(suite)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -43,9 +43,54 @@ class TestCase(unittest.TestCase):
|
||||||
self.assertEqual(len(d1), 1)
|
self.assertEqual(len(d1), 1)
|
||||||
self.assertNotEqual(d1, d2)
|
self.assertNotEqual(d1, d2)
|
||||||
|
|
||||||
def test_main():
|
from test_userdict import TestMappingProtocol
|
||||||
test_support.run_unittest(TestCase)
|
|
||||||
|
|
||||||
|
class TestShelveBase(TestMappingProtocol):
|
||||||
|
fn = "shelftemp.db"
|
||||||
|
counter = 0
|
||||||
|
def __init__(self, *args, **kw):
|
||||||
|
self._db = []
|
||||||
|
TestMappingProtocol.__init__(self, *args, **kw)
|
||||||
|
_tested_class = shelve.Shelf
|
||||||
|
def _reference(self):
|
||||||
|
return {"key1":"value1", "key2":2, "key3":(1,2,3)}
|
||||||
|
def _empty_mapping(self):
|
||||||
|
if self._in_mem:
|
||||||
|
x= shelve.Shelf({}, binary = self._binary)
|
||||||
|
else:
|
||||||
|
self.counter+=1
|
||||||
|
x= shelve.open(self.fn+str(self.counter), binary=self._binary)
|
||||||
|
self._db.append(x)
|
||||||
|
return x
|
||||||
|
def tearDown(self):
|
||||||
|
for db in self._db:
|
||||||
|
db.close()
|
||||||
|
self._db = []
|
||||||
|
if not self._in_mem:
|
||||||
|
for f in glob.glob(self.fn+"*"):
|
||||||
|
os.unlink(f)
|
||||||
|
|
||||||
|
class TestAsciiFileShelve(TestShelveBase):
|
||||||
|
_binary = False
|
||||||
|
_in_mem = False
|
||||||
|
class TestBinaryFileShelve(TestShelveBase):
|
||||||
|
_binary = True
|
||||||
|
_in_mem = False
|
||||||
|
class TestAsciiMemShelve(TestShelveBase):
|
||||||
|
_binary = False
|
||||||
|
_in_mem = True
|
||||||
|
class TestBinaryMemShelve(TestShelveBase):
|
||||||
|
_binary = True
|
||||||
|
_in_mem = True
|
||||||
|
|
||||||
|
def test_main():
|
||||||
|
suite = unittest.TestSuite()
|
||||||
|
suite.addTest(unittest.makeSuite(TestAsciiFileShelve))
|
||||||
|
suite.addTest(unittest.makeSuite(TestBinaryFileShelve))
|
||||||
|
suite.addTest(unittest.makeSuite(TestAsciiMemShelve))
|
||||||
|
suite.addTest(unittest.makeSuite(TestBinaryMemShelve))
|
||||||
|
suite.addTest(unittest.makeSuite(TestCase))
|
||||||
|
test_support.run_suite(suite)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
test_main()
|
test_main()
|
||||||
|
|
|
@ -4,6 +4,123 @@ import test.test_support, unittest
|
||||||
|
|
||||||
import UserDict
|
import UserDict
|
||||||
|
|
||||||
|
class TestMappingProtocol(unittest.TestCase):
|
||||||
|
# This base class can be used to check that an object conforms to the
|
||||||
|
# mapping protocol
|
||||||
|
|
||||||
|
# Functions that can be useful to override to adapt to dictionary
|
||||||
|
# semantics
|
||||||
|
_tested_class = dict # which class is being tested
|
||||||
|
|
||||||
|
def _reference(self):
|
||||||
|
"""Return a dictionary of values which are invariant by storage
|
||||||
|
in the object under test."""
|
||||||
|
return {1:2, "key1":"value1", "key2":(1,2,3)}
|
||||||
|
def _empty_mapping(self):
|
||||||
|
"""Return an empty mapping object"""
|
||||||
|
return self._tested_class()
|
||||||
|
def _full_mapping(self, data):
|
||||||
|
"""Return a mapping object with the value contained in data
|
||||||
|
dictionary"""
|
||||||
|
x = self._empty_mapping()
|
||||||
|
for key, value in data.items():
|
||||||
|
x[key] = value
|
||||||
|
return x
|
||||||
|
|
||||||
|
def __init__(self, *args, **kw):
|
||||||
|
unittest.TestCase.__init__(self, *args, **kw)
|
||||||
|
self.reference = self._reference().copy()
|
||||||
|
key, value = self.reference.popitem()
|
||||||
|
self.other = {key:value}
|
||||||
|
|
||||||
|
def test_read(self):
|
||||||
|
# Test for read only operations on mapping
|
||||||
|
p = self._empty_mapping()
|
||||||
|
p1 = dict(p) #workaround for singleton objects
|
||||||
|
d = self._full_mapping(self.reference)
|
||||||
|
if d is p:
|
||||||
|
p = p1
|
||||||
|
#Indexing
|
||||||
|
for key, value in self.reference.items():
|
||||||
|
self.assertEqual(d[key], value)
|
||||||
|
knownkey = self.other.keys()[0]
|
||||||
|
self.failUnlessRaises(KeyError, lambda:d[knownkey])
|
||||||
|
#len
|
||||||
|
self.assertEqual(len(p), 0)
|
||||||
|
self.assertEqual(len(d), len(self.reference))
|
||||||
|
#has_key
|
||||||
|
for k in self.reference:
|
||||||
|
self.assert_(d.has_key(k))
|
||||||
|
self.assert_(k in d)
|
||||||
|
for k in self.other:
|
||||||
|
self.failIf(d.has_key(k))
|
||||||
|
self.failIf(k in d)
|
||||||
|
#cmp
|
||||||
|
self.assertEqual(cmp(p,p), 0)
|
||||||
|
self.assertEqual(cmp(d,d), 0)
|
||||||
|
self.assertEqual(cmp(p,d), -1)
|
||||||
|
self.assertEqual(cmp(d,p), 1)
|
||||||
|
#__non__zero__
|
||||||
|
if p: self.fail("Empty mapping must compare to False")
|
||||||
|
if not d: self.fail("Full mapping must compare to True")
|
||||||
|
# keys(), items(), iterkeys() ...
|
||||||
|
def check_iterandlist(iter, lst, ref):
|
||||||
|
self.assert_(hasattr(iter, 'next'))
|
||||||
|
self.assert_(hasattr(iter, '__iter__'))
|
||||||
|
x = list(iter)
|
||||||
|
x.sort()
|
||||||
|
lst.sort()
|
||||||
|
ref.sort()
|
||||||
|
self.assert_(x==lst==ref)
|
||||||
|
check_iterandlist(d.iterkeys(), d.keys(), self.reference.keys())
|
||||||
|
check_iterandlist(iter(d), d.keys(), self.reference.keys())
|
||||||
|
check_iterandlist(d.itervalues(), d.values(), self.reference.values())
|
||||||
|
check_iterandlist(d.iteritems(), d.items(), self.reference.items())
|
||||||
|
#get
|
||||||
|
key, value = d.iteritems().next()
|
||||||
|
knownkey, knownvalue = self.other.iteritems().next()
|
||||||
|
self.assertEqual(d.get(key, knownvalue), value)
|
||||||
|
self.assertEqual(d.get(knownkey, knownvalue), knownvalue)
|
||||||
|
self.failIf(knownkey in d)
|
||||||
|
|
||||||
|
def test_write(self):
|
||||||
|
# Test for write operations on mapping
|
||||||
|
p = self._empty_mapping()
|
||||||
|
#Indexing
|
||||||
|
for key, value in self.reference.items():
|
||||||
|
p[key] = value
|
||||||
|
self.assertEqual(p[key], value)
|
||||||
|
for key in self.reference.keys():
|
||||||
|
del p[key]
|
||||||
|
self.failUnlessRaises(KeyError, lambda:p[key])
|
||||||
|
p = self._empty_mapping()
|
||||||
|
#update
|
||||||
|
p.update(self.reference)
|
||||||
|
self.assertEqual(dict(p), self.reference)
|
||||||
|
d = self._full_mapping(self.reference)
|
||||||
|
#setdefaullt
|
||||||
|
key, value = d.iteritems().next()
|
||||||
|
knownkey, knownvalue = self.other.iteritems().next()
|
||||||
|
self.assertEqual(d.setdefault(key, knownvalue), value)
|
||||||
|
self.assertEqual(d[key], value)
|
||||||
|
self.assertEqual(d.setdefault(knownkey, knownvalue), knownvalue)
|
||||||
|
self.assertEqual(d[knownkey], knownvalue)
|
||||||
|
#pop
|
||||||
|
self.assertEqual(d.pop(knownkey), knownvalue)
|
||||||
|
self.failIf(knownkey in d)
|
||||||
|
self.assertRaises(KeyError, d.pop, knownkey)
|
||||||
|
default = 909
|
||||||
|
d[knownkey] = knownvalue
|
||||||
|
self.assertEqual(d.pop(knownkey, default), knownvalue)
|
||||||
|
self.failIf(knownkey in d)
|
||||||
|
self.assertEqual(d.pop(knownkey, default), default)
|
||||||
|
#popitem
|
||||||
|
key, value = d.popitem()
|
||||||
|
self.failIf(key in d)
|
||||||
|
self.assertEqual(value, self.reference[key])
|
||||||
|
p=self._empty_mapping()
|
||||||
|
self.assertRaises(KeyError, p.popitem)
|
||||||
|
|
||||||
d0 = {}
|
d0 = {}
|
||||||
d1 = {"one": 1}
|
d1 = {"one": 1}
|
||||||
d2 = {"one": 1, "two": 2}
|
d2 = {"one": 1, "two": 2}
|
||||||
|
@ -11,7 +128,9 @@ d3 = {"one": 1, "two": 3, "three": 5}
|
||||||
d4 = {"one": None, "two": None}
|
d4 = {"one": None, "two": None}
|
||||||
d5 = {"one": 1, "two": 1}
|
d5 = {"one": 1, "two": 1}
|
||||||
|
|
||||||
class UserDictTest(unittest.TestCase):
|
class UserDictTest(TestMappingProtocol):
|
||||||
|
_tested_class = UserDict.IterableUserDict
|
||||||
|
|
||||||
def test_all(self):
|
def test_all(self):
|
||||||
# Test constructors
|
# Test constructors
|
||||||
u = UserDict.UserDict()
|
u = UserDict.UserDict()
|
||||||
|
@ -182,7 +301,9 @@ class SeqDict(UserDict.DictMixin):
|
||||||
def keys(self):
|
def keys(self):
|
||||||
return list(self.keylist)
|
return list(self.keylist)
|
||||||
|
|
||||||
class UserDictMixinTest(unittest.TestCase):
|
class UserDictMixinTest(TestMappingProtocol):
|
||||||
|
_tested_class = SeqDict
|
||||||
|
|
||||||
def test_all(self):
|
def test_all(self):
|
||||||
## Setup test and verify working of the test class
|
## Setup test and verify working of the test class
|
||||||
|
|
||||||
|
@ -275,6 +396,7 @@ class UserDictMixinTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
suite = unittest.TestSuite()
|
suite = unittest.TestSuite()
|
||||||
|
suite.addTest(unittest.makeSuite(TestMappingProtocol))
|
||||||
suite.addTest(unittest.makeSuite(UserDictTest))
|
suite.addTest(unittest.makeSuite(UserDictTest))
|
||||||
suite.addTest(unittest.makeSuite(UserDictMixinTest))
|
suite.addTest(unittest.makeSuite(UserDictMixinTest))
|
||||||
test.test_support.run_suite(suite)
|
test.test_support.run_suite(suite)
|
||||||
|
|
|
@ -517,11 +517,28 @@ class MappingTestCase(TestBase):
|
||||||
self.assert_(len(d) == 1)
|
self.assert_(len(d) == 1)
|
||||||
self.assert_(d.items() == [('something else', o2)])
|
self.assert_(d.items() == [('something else', o2)])
|
||||||
|
|
||||||
|
from test_userdict import TestMappingProtocol
|
||||||
|
|
||||||
|
class WeakValueDictionaryTestCase(TestMappingProtocol):
|
||||||
|
"""Check that WeakValueDictionary class conforms to the mapping protocol"""
|
||||||
|
__ref = {"key1":Object(1), "key2":Object(2), "key3":Object(3)}
|
||||||
|
_tested_class = weakref.WeakValueDictionary
|
||||||
|
def _reference(self):
|
||||||
|
return self.__ref.copy()
|
||||||
|
|
||||||
|
class WeakKeyDictionaryTestCase(TestMappingProtocol):
|
||||||
|
"""Check that WeakKeyDictionary class conforms to the mapping protocol"""
|
||||||
|
__ref = {Object("key1"):1, Object("key2"):2, Object("key3"):3}
|
||||||
|
_tested_class = weakref.WeakKeyDictionary
|
||||||
|
def _reference(self):
|
||||||
|
return self.__ref.copy()
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
suite = unittest.TestSuite()
|
suite = unittest.TestSuite()
|
||||||
suite.addTest(unittest.makeSuite(ReferencesTestCase))
|
suite.addTest(unittest.makeSuite(ReferencesTestCase))
|
||||||
suite.addTest(unittest.makeSuite(MappingTestCase))
|
suite.addTest(unittest.makeSuite(MappingTestCase))
|
||||||
|
suite.addTest(unittest.makeSuite(WeakValueDictionaryTestCase))
|
||||||
|
suite.addTest(unittest.makeSuite(WeakKeyDictionaryTestCase))
|
||||||
test_support.run_suite(suite)
|
test_support.run_suite(suite)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,18 @@ class WeakValueDictionary(UserDict.UserDict):
|
||||||
if o is not None:
|
if o is not None:
|
||||||
return key, o
|
return key, o
|
||||||
|
|
||||||
|
def pop(self, key, *args):
|
||||||
|
try:
|
||||||
|
o = self.data.pop(key)()
|
||||||
|
except KeyError:
|
||||||
|
if args:
|
||||||
|
return args[0]
|
||||||
|
raise
|
||||||
|
if o is None:
|
||||||
|
raise KeyError, key
|
||||||
|
else:
|
||||||
|
return o
|
||||||
|
|
||||||
def setdefault(self, key, default):
|
def setdefault(self, key, default):
|
||||||
try:
|
try:
|
||||||
wr = self.data[key]
|
wr = self.data[key]
|
||||||
|
@ -225,6 +237,9 @@ class WeakKeyDictionary(UserDict.UserDict):
|
||||||
if o is not None:
|
if o is not None:
|
||||||
return o, value
|
return o, value
|
||||||
|
|
||||||
|
def pop(self, key, *args):
|
||||||
|
return self.data.pop(ref(key), *args)
|
||||||
|
|
||||||
def setdefault(self, key, default):
|
def setdefault(self, key, default):
|
||||||
return self.data.setdefault(ref(key, self._remove),default)
|
return self.data.setdefault(ref(key, self._remove),default)
|
||||||
|
|
||||||
|
|
|
@ -281,6 +281,7 @@ Bob Kahn
|
||||||
Tamito Kajiyama
|
Tamito Kajiyama
|
||||||
Jacob Kaplan-Moss
|
Jacob Kaplan-Moss
|
||||||
Lou Kates
|
Lou Kates
|
||||||
|
Sebastien Keim
|
||||||
Randall Kern
|
Randall Kern
|
||||||
Robert Kern
|
Robert Kern
|
||||||
Magnus Kessler
|
Magnus Kessler
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue