1import os
2import unittest
3import shelve
4import glob
5from test import test_support
6
7test_support.import_module('anydbm', deprecated=True)
8
9class TestCase(unittest.TestCase):
10
11    fn = "shelftemp" + os.extsep + "db"
12
13    def test_close(self):
14        d1 = {}
15        s = shelve.Shelf(d1, protocol=2, writeback=False)
16        s['key1'] = [1,2,3,4]
17        self.assertEqual(s['key1'], [1,2,3,4])
18        self.assertEqual(len(s), 1)
19        s.close()
20        self.assertRaises(ValueError, len, s)
21        try:
22            s['key1']
23        except ValueError:
24            pass
25        else:
26            self.fail('Closed shelf should not find a key')
27
28    def test_ascii_file_shelf(self):
29        try:
30            s = shelve.open(self.fn, protocol=0)
31            s['key1'] = (1,2,3,4)
32            self.assertEqual(s['key1'], (1,2,3,4))
33            s.close()
34        finally:
35            for f in glob.glob(self.fn+"*"):
36                os.unlink(f)
37
38    def test_binary_file_shelf(self):
39        try:
40            s = shelve.open(self.fn, protocol=1)
41            s['key1'] = (1,2,3,4)
42            self.assertEqual(s['key1'], (1,2,3,4))
43            s.close()
44        finally:
45            for f in glob.glob(self.fn+"*"):
46                os.unlink(f)
47
48    def test_proto2_file_shelf(self):
49        try:
50            s = shelve.open(self.fn, protocol=2)
51            s['key1'] = (1,2,3,4)
52            self.assertEqual(s['key1'], (1,2,3,4))
53            s.close()
54        finally:
55            for f in glob.glob(self.fn+"*"):
56                os.unlink(f)
57
58    def test_in_memory_shelf(self):
59        d1 = {}
60        s = shelve.Shelf(d1, protocol=0)
61        s['key1'] = (1,2,3,4)
62        self.assertEqual(s['key1'], (1,2,3,4))
63        s.close()
64        d2 = {}
65        s = shelve.Shelf(d2, protocol=1)
66        s['key1'] = (1,2,3,4)
67        self.assertEqual(s['key1'], (1,2,3,4))
68        s.close()
69
70        self.assertEqual(len(d1), 1)
71        self.assertNotEqual(d1, d2)
72
73    def test_mutable_entry(self):
74        d1 = {}
75        s = shelve.Shelf(d1, protocol=2, writeback=False)
76        s['key1'] = [1,2,3,4]
77        self.assertEqual(s['key1'], [1,2,3,4])
78        s['key1'].append(5)
79        self.assertEqual(s['key1'], [1,2,3,4])
80        s.close()
81
82        d2 = {}
83        s = shelve.Shelf(d2, protocol=2, writeback=True)
84        s['key1'] = [1,2,3,4]
85        self.assertEqual(s['key1'], [1,2,3,4])
86        s['key1'].append(5)
87        self.assertEqual(s['key1'], [1,2,3,4,5])
88        s.close()
89
90        self.assertEqual(len(d1), 1)
91        self.assertEqual(len(d2), 1)
92
93    def test_writeback_also_writes_immediately(self):
94        # Issue 5754
95        d = {}
96        s = shelve.Shelf(d, writeback=True)
97        s['key'] = [1]
98        p1 = d['key']  # Will give a KeyError if backing store not updated
99        s['key'].append(2)
100        s.close()
101        p2 = d['key']
102        self.assertNotEqual(p1, p2)  # Write creates new object in store
103
104
105from test import mapping_tests
106
107class TestShelveBase(mapping_tests.BasicTestMappingProtocol):
108    fn = "shelftemp.db"
109    counter = 0
110    def __init__(self, *args, **kw):
111        self._db = []
112        mapping_tests.BasicTestMappingProtocol.__init__(self, *args, **kw)
113    type2test = shelve.Shelf
114    def _reference(self):
115        return {"key1":"value1", "key2":2, "key3":(1,2,3)}
116    def _empty_mapping(self):
117        if self._in_mem:
118            x= shelve.Shelf({}, **self._args)
119        else:
120            self.counter+=1
121            x= shelve.open(self.fn+str(self.counter), **self._args)
122        self._db.append(x)
123        return x
124    def tearDown(self):
125        for db in self._db:
126            db.close()
127        self._db = []
128        if not self._in_mem:
129            for f in glob.glob(self.fn+"*"):
130                test_support.unlink(f)
131
132class TestAsciiFileShelve(TestShelveBase):
133    _args={'protocol':0}
134    _in_mem = False
135class TestBinaryFileShelve(TestShelveBase):
136    _args={'protocol':1}
137    _in_mem = False
138class TestProto2FileShelve(TestShelveBase):
139    _args={'protocol':2}
140    _in_mem = False
141class TestAsciiMemShelve(TestShelveBase):
142    _args={'protocol':0}
143    _in_mem = True
144class TestBinaryMemShelve(TestShelveBase):
145    _args={'protocol':1}
146    _in_mem = True
147class TestProto2MemShelve(TestShelveBase):
148    _args={'protocol':2}
149    _in_mem = True
150
151def test_main():
152    test_support.run_unittest(
153        TestAsciiFileShelve,
154        TestBinaryFileShelve,
155        TestProto2FileShelve,
156        TestAsciiMemShelve,
157        TestBinaryMemShelve,
158        TestProto2MemShelve,
159        TestCase
160    )
161
162if __name__ == "__main__":
163    test_main()
164