1import unittest 2import shelve 3import glob 4from test import support 5from collections.abc import MutableMapping 6from test.test_dbm import dbm_iterator 7 8def L1(s): 9 return s.decode("latin-1") 10 11class byteskeydict(MutableMapping): 12 "Mapping that supports bytes keys" 13 14 def __init__(self): 15 self.d = {} 16 17 def __getitem__(self, key): 18 return self.d[L1(key)] 19 20 def __setitem__(self, key, value): 21 self.d[L1(key)] = value 22 23 def __delitem__(self, key): 24 del self.d[L1(key)] 25 26 def __len__(self): 27 return len(self.d) 28 29 def iterkeys(self): 30 for k in self.d.keys(): 31 yield k.encode("latin-1") 32 33 __iter__ = iterkeys 34 35 def keys(self): 36 return list(self.iterkeys()) 37 38 def copy(self): 39 return byteskeydict(self.d) 40 41 42class TestCase(unittest.TestCase): 43 44 fn = "shelftemp.db" 45 46 def tearDown(self): 47 for f in glob.glob(self.fn+"*"): 48 support.unlink(f) 49 50 def test_close(self): 51 d1 = {} 52 s = shelve.Shelf(d1, protocol=2, writeback=False) 53 s['key1'] = [1,2,3,4] 54 self.assertEqual(s['key1'], [1,2,3,4]) 55 self.assertEqual(len(s), 1) 56 s.close() 57 self.assertRaises(ValueError, len, s) 58 try: 59 s['key1'] 60 except ValueError: 61 pass 62 else: 63 self.fail('Closed shelf should not find a key') 64 65 def test_ascii_file_shelf(self): 66 s = shelve.open(self.fn, protocol=0) 67 try: 68 s['key1'] = (1,2,3,4) 69 self.assertEqual(s['key1'], (1,2,3,4)) 70 finally: 71 s.close() 72 73 def test_binary_file_shelf(self): 74 s = shelve.open(self.fn, protocol=1) 75 try: 76 s['key1'] = (1,2,3,4) 77 self.assertEqual(s['key1'], (1,2,3,4)) 78 finally: 79 s.close() 80 81 def test_proto2_file_shelf(self): 82 s = shelve.open(self.fn, protocol=2) 83 try: 84 s['key1'] = (1,2,3,4) 85 self.assertEqual(s['key1'], (1,2,3,4)) 86 finally: 87 s.close() 88 89 def test_in_memory_shelf(self): 90 d1 = byteskeydict() 91 with shelve.Shelf(d1, protocol=0) as s: 92 s['key1'] = (1,2,3,4) 93 self.assertEqual(s['key1'], (1,2,3,4)) 94 d2 = byteskeydict() 95 with shelve.Shelf(d2, protocol=1) as s: 96 s['key1'] = (1,2,3,4) 97 self.assertEqual(s['key1'], (1,2,3,4)) 98 99 self.assertEqual(len(d1), 1) 100 self.assertEqual(len(d2), 1) 101 self.assertNotEqual(d1.items(), d2.items()) 102 103 def test_mutable_entry(self): 104 d1 = byteskeydict() 105 with shelve.Shelf(d1, protocol=2, writeback=False) as s: 106 s['key1'] = [1,2,3,4] 107 self.assertEqual(s['key1'], [1,2,3,4]) 108 s['key1'].append(5) 109 self.assertEqual(s['key1'], [1,2,3,4]) 110 111 d2 = byteskeydict() 112 with shelve.Shelf(d2, protocol=2, writeback=True) as s: 113 s['key1'] = [1,2,3,4] 114 self.assertEqual(s['key1'], [1,2,3,4]) 115 s['key1'].append(5) 116 self.assertEqual(s['key1'], [1,2,3,4,5]) 117 118 self.assertEqual(len(d1), 1) 119 self.assertEqual(len(d2), 1) 120 121 def test_keyencoding(self): 122 d = {} 123 key = 'Pöp' 124 # the default keyencoding is utf-8 125 shelve.Shelf(d)[key] = [1] 126 self.assertIn(key.encode('utf-8'), d) 127 # but a different one can be given 128 shelve.Shelf(d, keyencoding='latin-1')[key] = [1] 129 self.assertIn(key.encode('latin-1'), d) 130 # with all consequences 131 s = shelve.Shelf(d, keyencoding='ascii') 132 self.assertRaises(UnicodeEncodeError, s.__setitem__, key, [1]) 133 134 def test_writeback_also_writes_immediately(self): 135 # Issue 5754 136 d = {} 137 key = 'key' 138 encodedkey = key.encode('utf-8') 139 with shelve.Shelf(d, writeback=True) as s: 140 s[key] = [1] 141 p1 = d[encodedkey] # Will give a KeyError if backing store not updated 142 s['key'].append(2) 143 p2 = d[encodedkey] 144 self.assertNotEqual(p1, p2) # Write creates new object in store 145 146 def test_with(self): 147 d1 = {} 148 with shelve.Shelf(d1, protocol=2, writeback=False) as s: 149 s['key1'] = [1,2,3,4] 150 self.assertEqual(s['key1'], [1,2,3,4]) 151 self.assertEqual(len(s), 1) 152 self.assertRaises(ValueError, len, s) 153 try: 154 s['key1'] 155 except ValueError: 156 pass 157 else: 158 self.fail('Closed shelf should not find a key') 159 160 def test_default_protocol(self): 161 with shelve.Shelf({}) as s: 162 self.assertEqual(s._protocol, 3) 163 164from test import mapping_tests 165 166class TestShelveBase(mapping_tests.BasicTestMappingProtocol): 167 fn = "shelftemp.db" 168 counter = 0 169 def __init__(self, *args, **kw): 170 self._db = [] 171 mapping_tests.BasicTestMappingProtocol.__init__(self, *args, **kw) 172 type2test = shelve.Shelf 173 def _reference(self): 174 return {"key1":"value1", "key2":2, "key3":(1,2,3)} 175 def _empty_mapping(self): 176 if self._in_mem: 177 x= shelve.Shelf(byteskeydict(), **self._args) 178 else: 179 self.counter+=1 180 x= shelve.open(self.fn+str(self.counter), **self._args) 181 self._db.append(x) 182 return x 183 def tearDown(self): 184 for db in self._db: 185 db.close() 186 self._db = [] 187 if not self._in_mem: 188 for f in glob.glob(self.fn+"*"): 189 support.unlink(f) 190 191class TestAsciiFileShelve(TestShelveBase): 192 _args={'protocol':0} 193 _in_mem = False 194class TestBinaryFileShelve(TestShelveBase): 195 _args={'protocol':1} 196 _in_mem = False 197class TestProto2FileShelve(TestShelveBase): 198 _args={'protocol':2} 199 _in_mem = False 200class TestAsciiMemShelve(TestShelveBase): 201 _args={'protocol':0} 202 _in_mem = True 203class TestBinaryMemShelve(TestShelveBase): 204 _args={'protocol':1} 205 _in_mem = True 206class TestProto2MemShelve(TestShelveBase): 207 _args={'protocol':2} 208 _in_mem = True 209 210def test_main(): 211 for module in dbm_iterator(): 212 support.run_unittest( 213 TestAsciiFileShelve, 214 TestBinaryFileShelve, 215 TestProto2FileShelve, 216 TestAsciiMemShelve, 217 TestBinaryMemShelve, 218 TestProto2MemShelve, 219 TestCase 220 ) 221 222if __name__ == "__main__": 223 test_main() 224