Home | History | Annotate | Download | only in test
      1 import unittest
      2 import shelve
      3 import glob
      4 from test import support
      5 from collections.abc import MutableMapping
      6 from test.test_dbm import dbm_iterator
      7 
      8 def L1(s):
      9     return s.decode("latin-1")
     10 
     11 class 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 
     42 class 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 = 'Pp'
    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 
    169 from test import mapping_tests
    170 
    171 class 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 
    196 class TestAsciiFileShelve(TestShelveBase):
    197     _args={'protocol':0}
    198     _in_mem = False
    199 class TestBinaryFileShelve(TestShelveBase):
    200     _args={'protocol':1}
    201     _in_mem = False
    202 class TestProto2FileShelve(TestShelveBase):
    203     _args={'protocol':2}
    204     _in_mem = False
    205 class TestAsciiMemShelve(TestShelveBase):
    206     _args={'protocol':0}
    207     _in_mem = True
    208 class TestBinaryMemShelve(TestShelveBase):
    209     _args={'protocol':1}
    210     _in_mem = True
    211 class TestProto2MemShelve(TestShelveBase):
    212     _args={'protocol':2}
    213     _in_mem = True
    214 
    215 def 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 
    227 if __name__ == "__main__":
    228     test_main()
    229