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 s = shelve.Shelf(d1, protocol=0) 92 s['key1'] = (1,2,3,4) 93 self.assertEqual(s['key1'], (1,2,3,4)) 94 s.close() 95 d2 = byteskeydict() 96 s = shelve.Shelf(d2, protocol=1) 97 s['key1'] = (1,2,3,4) 98 self.assertEqual(s['key1'], (1,2,3,4)) 99 s.close() 100 101 self.assertEqual(len(d1), 1) 102 self.assertEqual(len(d2), 1) 103 self.assertNotEqual(d1.items(), d2.items()) 104 105 def test_mutable_entry(self): 106 d1 = byteskeydict() 107 s = shelve.Shelf(d1, protocol=2, writeback=False) 108 s['key1'] = [1,2,3,4] 109 self.assertEqual(s['key1'], [1,2,3,4]) 110 s['key1'].append(5) 111 self.assertEqual(s['key1'], [1,2,3,4]) 112 s.close() 113 114 d2 = byteskeydict() 115 s = shelve.Shelf(d2, protocol=2, writeback=True) 116 s['key1'] = [1,2,3,4] 117 self.assertEqual(s['key1'], [1,2,3,4]) 118 s['key1'].append(5) 119 self.assertEqual(s['key1'], [1,2,3,4,5]) 120 s.close() 121 122 self.assertEqual(len(d1), 1) 123 self.assertEqual(len(d2), 1) 124 125 def test_keyencoding(self): 126 d = {} 127 key = 'Pöp' 128 # the default keyencoding is utf-8 129 shelve.Shelf(d)[key] = [1] 130 self.assertIn(key.encode('utf-8'), d) 131 # but a different one can be given 132 shelve.Shelf(d, keyencoding='latin-1')[key] = [1] 133 self.assertIn(key.encode('latin-1'), d) 134 # with all consequences 135 s = shelve.Shelf(d, keyencoding='ascii') 136 self.assertRaises(UnicodeEncodeError, s.__setitem__, key, [1]) 137 138 def test_writeback_also_writes_immediately(self): 139 # Issue 5754 140 d = {} 141 key = 'key' 142 encodedkey = key.encode('utf-8') 143 s = shelve.Shelf(d, writeback=True) 144 s[key] = [1] 145 p1 = d[encodedkey] # Will give a KeyError if backing store not updated 146 s['key'].append(2) 147 s.close() 148 p2 = d[encodedkey] 149 self.assertNotEqual(p1, p2) # Write creates new object in store 150 151 def test_with(self): 152 d1 = {} 153 with shelve.Shelf(d1, protocol=2, writeback=False) as s: 154 s['key1'] = [1,2,3,4] 155 self.assertEqual(s['key1'], [1,2,3,4]) 156 self.assertEqual(len(s), 1) 157 self.assertRaises(ValueError, len, s) 158 try: 159 s['key1'] 160 except ValueError: 161 pass 162 else: 163 self.fail('Closed shelf should not find a key') 164 165 def test_default_protocol(self): 166 with shelve.Shelf({}) as s: 167 self.assertEqual(s._protocol, 3) 168 169from test import mapping_tests 170 171class TestShelveBase(mapping_tests.BasicTestMappingProtocol): 172 fn = "shelftemp.db" 173 counter = 0 174 def __init__(self, *args, **kw): 175 self._db = [] 176 mapping_tests.BasicTestMappingProtocol.__init__(self, *args, **kw) 177 type2test = shelve.Shelf 178 def _reference(self): 179 return {"key1":"value1", "key2":2, "key3":(1,2,3)} 180 def _empty_mapping(self): 181 if self._in_mem: 182 x= shelve.Shelf(byteskeydict(), **self._args) 183 else: 184 self.counter+=1 185 x= shelve.open(self.fn+str(self.counter), **self._args) 186 self._db.append(x) 187 return x 188 def tearDown(self): 189 for db in self._db: 190 db.close() 191 self._db = [] 192 if not self._in_mem: 193 for f in glob.glob(self.fn+"*"): 194 support.unlink(f) 195 196class TestAsciiFileShelve(TestShelveBase): 197 _args={'protocol':0} 198 _in_mem = False 199class TestBinaryFileShelve(TestShelveBase): 200 _args={'protocol':1} 201 _in_mem = False 202class TestProto2FileShelve(TestShelveBase): 203 _args={'protocol':2} 204 _in_mem = False 205class TestAsciiMemShelve(TestShelveBase): 206 _args={'protocol':0} 207 _in_mem = True 208class TestBinaryMemShelve(TestShelveBase): 209 _args={'protocol':1} 210 _in_mem = True 211class TestProto2MemShelve(TestShelveBase): 212 _args={'protocol':2} 213 _in_mem = True 214 215def test_main(): 216 for module in dbm_iterator(): 217 support.run_unittest( 218 TestAsciiFileShelve, 219 TestBinaryFileShelve, 220 TestProto2FileShelve, 221 TestAsciiMemShelve, 222 TestBinaryMemShelve, 223 TestProto2MemShelve, 224 TestCase 225 ) 226 227if __name__ == "__main__": 228 test_main() 229