blob: ac25eee2e52fd92ee368c8b57cd887250d46b2d0 [file] [log] [blame]
Skip Montanaro3bf99e32002-12-08 18:36:24 +00001import unittest
2import shelve
3import glob
Benjamin Petersonee8712c2008-05-20 21:35:26 +00004from test import support
Hai Shia089d212020-07-06 17:15:08 +08005from test.support import os_helper
Raymond Hettinger57d1a882011-02-23 00:46:28 +00006from collections.abc import MutableMapping
Georg Brandl24420152008-05-26 16:32:26 +00007from test.test_dbm import dbm_iterator
Martin v. Löwis79c32082007-08-11 06:57:14 +00008
9def L1(s):
10 return s.decode("latin-1")
11
Raymond Hettingeredf3b732008-02-04 22:07:15 +000012class byteskeydict(MutableMapping):
Martin v. Löwis79c32082007-08-11 06:57:14 +000013 "Mapping that supports bytes keys"
14
15 def __init__(self):
16 self.d = {}
17
18 def __getitem__(self, key):
19 return self.d[L1(key)]
20
21 def __setitem__(self, key, value):
22 self.d[L1(key)] = value
23
24 def __delitem__(self, key):
25 del self.d[L1(key)]
26
Raymond Hettingeredf3b732008-02-04 22:07:15 +000027 def __len__(self):
28 return len(self.d)
29
Martin v. Löwis79c32082007-08-11 06:57:14 +000030 def iterkeys(self):
31 for k in self.d.keys():
Guido van Rossum83800a62007-08-29 02:57:31 +000032 yield k.encode("latin-1")
Martin v. Löwis79c32082007-08-11 06:57:14 +000033
Raymond Hettingeredf3b732008-02-04 22:07:15 +000034 __iter__ = iterkeys
35
Martin v. Löwis79c32082007-08-11 06:57:14 +000036 def keys(self):
37 return list(self.iterkeys())
38
39 def copy(self):
40 return byteskeydict(self.d)
41
Skip Montanaro3bf99e32002-12-08 18:36:24 +000042
43class TestCase(unittest.TestCase):
44
Guido van Rossum94b59bb2007-05-18 22:12:08 +000045 fn = "shelftemp.db"
Tim Peters6578dc92002-12-24 18:31:27 +000046
Guido van Rossum8d9db042007-05-18 21:57:09 +000047 def tearDown(self):
48 for f in glob.glob(self.fn+"*"):
Hai Shia089d212020-07-06 17:15:08 +080049 os_helper.unlink(f)
Guido van Rossum8d9db042007-05-18 21:57:09 +000050
Benjamin Petersond6313712008-07-31 16:23:04 +000051 def test_close(self):
52 d1 = {}
53 s = shelve.Shelf(d1, protocol=2, writeback=False)
54 s['key1'] = [1,2,3,4]
55 self.assertEqual(s['key1'], [1,2,3,4])
56 self.assertEqual(len(s), 1)
57 s.close()
58 self.assertRaises(ValueError, len, s)
59 try:
60 s['key1']
61 except ValueError:
62 pass
63 else:
64 self.fail('Closed shelf should not find a key')
65
Skip Montanaro3bf99e32002-12-08 18:36:24 +000066 def test_ascii_file_shelf(self):
Guido van Rossum8d9db042007-05-18 21:57:09 +000067 s = shelve.open(self.fn, protocol=0)
Skip Montanaro3bf99e32002-12-08 18:36:24 +000068 try:
Skip Montanaro3bf99e32002-12-08 18:36:24 +000069 s['key1'] = (1,2,3,4)
70 self.assertEqual(s['key1'], (1,2,3,4))
Skip Montanaro3bf99e32002-12-08 18:36:24 +000071 finally:
Guido van Rossum8d9db042007-05-18 21:57:09 +000072 s.close()
Skip Montanaro3bf99e32002-12-08 18:36:24 +000073
74 def test_binary_file_shelf(self):
Guido van Rossum8d9db042007-05-18 21:57:09 +000075 s = shelve.open(self.fn, protocol=1)
Skip Montanaro3bf99e32002-12-08 18:36:24 +000076 try:
Skip Montanaro3bf99e32002-12-08 18:36:24 +000077 s['key1'] = (1,2,3,4)
78 self.assertEqual(s['key1'], (1,2,3,4))
Skip Montanaro3bf99e32002-12-08 18:36:24 +000079 finally:
Guido van Rossum8d9db042007-05-18 21:57:09 +000080 s.close()
Skip Montanaro3bf99e32002-12-08 18:36:24 +000081
Martin v. Löwis153c9e42003-04-19 20:59:03 +000082 def test_proto2_file_shelf(self):
Guido van Rossum8d9db042007-05-18 21:57:09 +000083 s = shelve.open(self.fn, protocol=2)
Martin v. Löwis153c9e42003-04-19 20:59:03 +000084 try:
Martin v. Löwis153c9e42003-04-19 20:59:03 +000085 s['key1'] = (1,2,3,4)
86 self.assertEqual(s['key1'], (1,2,3,4))
Martin v. Löwis153c9e42003-04-19 20:59:03 +000087 finally:
Guido van Rossum8d9db042007-05-18 21:57:09 +000088 s.close()
Martin v. Löwis153c9e42003-04-19 20:59:03 +000089
Skip Montanaro3bf99e32002-12-08 18:36:24 +000090 def test_in_memory_shelf(self):
Martin v. Löwis79c32082007-08-11 06:57:14 +000091 d1 = byteskeydict()
Serhiy Storchaka5b10b982019-03-05 10:06:26 +020092 with shelve.Shelf(d1, protocol=0) as s:
93 s['key1'] = (1,2,3,4)
94 self.assertEqual(s['key1'], (1,2,3,4))
Martin v. Löwis79c32082007-08-11 06:57:14 +000095 d2 = byteskeydict()
Serhiy Storchaka5b10b982019-03-05 10:06:26 +020096 with shelve.Shelf(d2, protocol=1) as s:
97 s['key1'] = (1,2,3,4)
98 self.assertEqual(s['key1'], (1,2,3,4))
Skip Montanaro3bf99e32002-12-08 18:36:24 +000099
100 self.assertEqual(len(d1), 1)
Guido van Rossum83800a62007-08-29 02:57:31 +0000101 self.assertEqual(len(d2), 1)
102 self.assertNotEqual(d1.items(), d2.items())
Skip Montanaro3bf99e32002-12-08 18:36:24 +0000103
Martin v. Löwis153c9e42003-04-19 20:59:03 +0000104 def test_mutable_entry(self):
Martin v. Löwis79c32082007-08-11 06:57:14 +0000105 d1 = byteskeydict()
Serhiy Storchaka5b10b982019-03-05 10:06:26 +0200106 with shelve.Shelf(d1, protocol=2, writeback=False) as s:
107 s['key1'] = [1,2,3,4]
108 self.assertEqual(s['key1'], [1,2,3,4])
109 s['key1'].append(5)
110 self.assertEqual(s['key1'], [1,2,3,4])
Martin v. Löwis153c9e42003-04-19 20:59:03 +0000111
Martin v. Löwis79c32082007-08-11 06:57:14 +0000112 d2 = byteskeydict()
Serhiy Storchaka5b10b982019-03-05 10:06:26 +0200113 with shelve.Shelf(d2, protocol=2, writeback=True) as s:
114 s['key1'] = [1,2,3,4]
115 self.assertEqual(s['key1'], [1,2,3,4])
116 s['key1'].append(5)
117 self.assertEqual(s['key1'], [1,2,3,4,5])
Martin v. Löwis153c9e42003-04-19 20:59:03 +0000118
119 self.assertEqual(len(d1), 1)
120 self.assertEqual(len(d2), 1)
121
Georg Brandl732324a2010-12-04 11:12:43 +0000122 def test_keyencoding(self):
123 d = {}
124 key = 'Pöp'
125 # the default keyencoding is utf-8
126 shelve.Shelf(d)[key] = [1]
127 self.assertIn(key.encode('utf-8'), d)
128 # but a different one can be given
Marc-André Lemburg8f36af72011-02-25 15:42:01 +0000129 shelve.Shelf(d, keyencoding='latin-1')[key] = [1]
130 self.assertIn(key.encode('latin-1'), d)
Georg Brandl732324a2010-12-04 11:12:43 +0000131 # with all consequences
132 s = shelve.Shelf(d, keyencoding='ascii')
133 self.assertRaises(UnicodeEncodeError, s.__setitem__, key, [1])
134
R. David Murrayddb3ed02010-02-11 02:42:19 +0000135 def test_writeback_also_writes_immediately(self):
136 # Issue 5754
137 d = {}
138 key = 'key'
139 encodedkey = key.encode('utf-8')
Serhiy Storchaka5b10b982019-03-05 10:06:26 +0200140 with shelve.Shelf(d, writeback=True) as s:
141 s[key] = [1]
142 p1 = d[encodedkey] # Will give a KeyError if backing store not updated
143 s['key'].append(2)
R. David Murrayddb3ed02010-02-11 02:42:19 +0000144 p2 = d[encodedkey]
145 self.assertNotEqual(p1, p2) # Write creates new object in store
146
Andrew Svetlovef08fb12012-10-06 13:52:19 +0300147 def test_with(self):
148 d1 = {}
149 with shelve.Shelf(d1, protocol=2, writeback=False) as s:
150 s['key1'] = [1,2,3,4]
151 self.assertEqual(s['key1'], [1,2,3,4])
152 self.assertEqual(len(s), 1)
153 self.assertRaises(ValueError, len, s)
154 try:
155 s['key1']
156 except ValueError:
157 pass
158 else:
159 self.fail('Closed shelf should not find a key')
Martin v. Löwis153c9e42003-04-19 20:59:03 +0000160
Berker Peksag8faca612016-07-01 12:33:00 +0300161 def test_default_protocol(self):
162 with shelve.Shelf({}) as s:
163 self.assertEqual(s._protocol, 3)
164
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000165from test import mapping_tests
Skip Montanaro3bf99e32002-12-08 18:36:24 +0000166
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000167class TestShelveBase(mapping_tests.BasicTestMappingProtocol):
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000168 fn = "shelftemp.db"
169 counter = 0
170 def __init__(self, *args, **kw):
171 self._db = []
Walter Dörwald0a6d0ff2004-05-31 16:29:04 +0000172 mapping_tests.BasicTestMappingProtocol.__init__(self, *args, **kw)
Walter Dörwald118f9312004-06-02 18:42:25 +0000173 type2test = shelve.Shelf
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000174 def _reference(self):
175 return {"key1":"value1", "key2":2, "key3":(1,2,3)}
176 def _empty_mapping(self):
177 if self._in_mem:
Martin v. Löwis79c32082007-08-11 06:57:14 +0000178 x= shelve.Shelf(byteskeydict(), **self._args)
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000179 else:
180 self.counter+=1
Martin v. Löwis153c9e42003-04-19 20:59:03 +0000181 x= shelve.open(self.fn+str(self.counter), **self._args)
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000182 self._db.append(x)
183 return x
184 def tearDown(self):
185 for db in self._db:
186 db.close()
187 self._db = []
188 if not self._in_mem:
189 for f in glob.glob(self.fn+"*"):
Hai Shia089d212020-07-06 17:15:08 +0800190 os_helper.unlink(f)
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000191
192class TestAsciiFileShelve(TestShelveBase):
Raymond Hettinger1bc82f82004-12-05 03:58:17 +0000193 _args={'protocol':0}
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000194 _in_mem = False
195class TestBinaryFileShelve(TestShelveBase):
Raymond Hettinger1bc82f82004-12-05 03:58:17 +0000196 _args={'protocol':1}
Martin v. Löwis153c9e42003-04-19 20:59:03 +0000197 _in_mem = False
198class TestProto2FileShelve(TestShelveBase):
199 _args={'protocol':2}
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000200 _in_mem = False
201class TestAsciiMemShelve(TestShelveBase):
Raymond Hettinger1bc82f82004-12-05 03:58:17 +0000202 _args={'protocol':0}
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000203 _in_mem = True
204class TestBinaryMemShelve(TestShelveBase):
Raymond Hettinger1bc82f82004-12-05 03:58:17 +0000205 _args={'protocol':1}
Martin v. Löwis153c9e42003-04-19 20:59:03 +0000206 _in_mem = True
207class TestProto2MemShelve(TestShelveBase):
208 _args={'protocol':2}
Raymond Hettinger2c2d3222003-03-09 07:05:43 +0000209 _in_mem = True
210
211def test_main():
Gregory P. Smith178fefb2007-08-24 21:59:45 +0000212 for module in dbm_iterator():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000213 support.run_unittest(
Gregory P. Smith178fefb2007-08-24 21:59:45 +0000214 TestAsciiFileShelve,
215 TestBinaryFileShelve,
216 TestProto2FileShelve,
217 TestAsciiMemShelve,
218 TestBinaryMemShelve,
219 TestProto2MemShelve,
220 TestCase
221 )
Skip Montanaro3bf99e32002-12-08 18:36:24 +0000222
223if __name__ == "__main__":
224 test_main()