(root)/
Python-3.12.0/
Lib/
test/
test_dbm_gnu.py
       1  from test import support
       2  from test.support import import_helper, cpython_only
       3  gdbm = import_helper.import_module("dbm.gnu") #skip if not supported
       4  import unittest
       5  import os
       6  from test.support.os_helper import TESTFN, TESTFN_NONASCII, unlink, FakePath
       7  
       8  
       9  filename = TESTFN
      10  
      11  class ESC[4;38;5;81mTestGdbm(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      12      @staticmethod
      13      def setUpClass():
      14          if support.verbose:
      15              try:
      16                  from _gdbm import _GDBM_VERSION as version
      17              except ImportError:
      18                  pass
      19              else:
      20                  print(f"gdbm version: {version}")
      21  
      22      def setUp(self):
      23          self.g = None
      24  
      25      def tearDown(self):
      26          if self.g is not None:
      27              self.g.close()
      28          unlink(filename)
      29  
      30      @cpython_only
      31      def test_disallow_instantiation(self):
      32          # Ensure that the type disallows instantiation (bpo-43916)
      33          self.g = gdbm.open(filename, 'c')
      34          support.check_disallow_instantiation(self, type(self.g))
      35  
      36      def test_key_methods(self):
      37          self.g = gdbm.open(filename, 'c')
      38          self.assertEqual(self.g.keys(), [])
      39          self.g['a'] = 'b'
      40          self.g['12345678910'] = '019237410982340912840198242'
      41          self.g[b'bytes'] = b'data'
      42          key_set = set(self.g.keys())
      43          self.assertEqual(key_set, set([b'a', b'bytes', b'12345678910']))
      44          self.assertIn('a', self.g)
      45          self.assertIn(b'a', self.g)
      46          self.assertEqual(self.g[b'bytes'], b'data')
      47          key = self.g.firstkey()
      48          while key:
      49              self.assertIn(key, key_set)
      50              key_set.remove(key)
      51              key = self.g.nextkey(key)
      52          # get() and setdefault() work as in the dict interface
      53          self.assertEqual(self.g.get(b'a'), b'b')
      54          self.assertIsNone(self.g.get(b'xxx'))
      55          self.assertEqual(self.g.get(b'xxx', b'foo'), b'foo')
      56          with self.assertRaises(KeyError):
      57              self.g['xxx']
      58          self.assertEqual(self.g.setdefault(b'xxx', b'foo'), b'foo')
      59          self.assertEqual(self.g[b'xxx'], b'foo')
      60  
      61      def test_error_conditions(self):
      62          # Try to open a non-existent database.
      63          unlink(filename)
      64          self.assertRaises(gdbm.error, gdbm.open, filename, 'r')
      65          # Try to access a closed database.
      66          self.g = gdbm.open(filename, 'c')
      67          self.g.close()
      68          self.assertRaises(gdbm.error, lambda: self.g['a'])
      69          # try pass an invalid open flag
      70          self.assertRaises(gdbm.error, lambda: gdbm.open(filename, 'rx').close())
      71  
      72      def test_flags(self):
      73          # Test the flag parameter open() by trying all supported flag modes.
      74          all = set(gdbm.open_flags)
      75          # Test standard flags (presumably "crwn").
      76          modes = all - set('fsu')
      77          for mode in sorted(modes):  # put "c" mode first
      78              self.g = gdbm.open(filename, mode)
      79              self.g.close()
      80  
      81          # Test additional flags (presumably "fsu").
      82          flags = all - set('crwn')
      83          for mode in modes:
      84              for flag in flags:
      85                  self.g = gdbm.open(filename, mode + flag)
      86                  self.g.close()
      87  
      88      def test_reorganize(self):
      89          self.g = gdbm.open(filename, 'c')
      90          size0 = os.path.getsize(filename)
      91  
      92          # bpo-33901: on macOS with gdbm 1.15, an empty database uses 16 MiB
      93          # and adding an entry of 10,000 B has no effect on the file size.
      94          # Add size0 bytes to make sure that the file size changes.
      95          value_size = max(size0, 10000)
      96          self.g['x'] = 'x' * value_size
      97          size1 = os.path.getsize(filename)
      98          self.assertGreater(size1, size0)
      99  
     100          del self.g['x']
     101          # 'size' is supposed to be the same even after deleting an entry.
     102          self.assertEqual(os.path.getsize(filename), size1)
     103  
     104          self.g.reorganize()
     105          size2 = os.path.getsize(filename)
     106          self.assertLess(size2, size1)
     107          self.assertGreaterEqual(size2, size0)
     108  
     109      def test_context_manager(self):
     110          with gdbm.open(filename, 'c') as db:
     111              db["gdbm context manager"] = "context manager"
     112  
     113          with gdbm.open(filename, 'r') as db:
     114              self.assertEqual(list(db.keys()), [b"gdbm context manager"])
     115  
     116          with self.assertRaises(gdbm.error) as cm:
     117              db.keys()
     118          self.assertEqual(str(cm.exception),
     119                           "GDBM object has already been closed")
     120  
     121      def test_bool_empty(self):
     122          with gdbm.open(filename, 'c') as db:
     123              self.assertFalse(bool(db))
     124  
     125      def test_bool_not_empty(self):
     126          with gdbm.open(filename, 'c') as db:
     127              db['a'] = 'b'
     128              self.assertTrue(bool(db))
     129  
     130      def test_bool_on_closed_db_raises(self):
     131          with gdbm.open(filename, 'c') as db:
     132              db['a'] = 'b'
     133          self.assertRaises(gdbm.error, bool, db)
     134  
     135      def test_bytes(self):
     136          with gdbm.open(filename, 'c') as db:
     137              db[b'bytes key \xbd'] = b'bytes value \xbd'
     138          with gdbm.open(filename, 'r') as db:
     139              self.assertEqual(list(db.keys()), [b'bytes key \xbd'])
     140              self.assertTrue(b'bytes key \xbd' in db)
     141              self.assertEqual(db[b'bytes key \xbd'], b'bytes value \xbd')
     142  
     143      def test_unicode(self):
     144          with gdbm.open(filename, 'c') as db:
     145              db['Unicode key \U0001f40d'] = 'Unicode value \U0001f40d'
     146          with gdbm.open(filename, 'r') as db:
     147              self.assertEqual(list(db.keys()), ['Unicode key \U0001f40d'.encode()])
     148              self.assertTrue('Unicode key \U0001f40d'.encode() in db)
     149              self.assertTrue('Unicode key \U0001f40d' in db)
     150              self.assertEqual(db['Unicode key \U0001f40d'.encode()],
     151                               'Unicode value \U0001f40d'.encode())
     152              self.assertEqual(db['Unicode key \U0001f40d'],
     153                               'Unicode value \U0001f40d'.encode())
     154  
     155      def test_write_readonly_file(self):
     156          with gdbm.open(filename, 'c') as db:
     157              db[b'bytes key'] = b'bytes value'
     158          with gdbm.open(filename, 'r') as db:
     159              with self.assertRaises(gdbm.error):
     160                  del db[b'not exist key']
     161              with self.assertRaises(gdbm.error):
     162                  del db[b'bytes key']
     163              with self.assertRaises(gdbm.error):
     164                  db[b'not exist key'] = b'not exist value'
     165  
     166      @unittest.skipUnless(TESTFN_NONASCII,
     167                           'requires OS support of non-ASCII encodings')
     168      def test_nonascii_filename(self):
     169          filename = TESTFN_NONASCII
     170          self.addCleanup(unlink, filename)
     171          with gdbm.open(filename, 'c') as db:
     172              db[b'key'] = b'value'
     173          self.assertTrue(os.path.exists(filename))
     174          with gdbm.open(filename, 'r') as db:
     175              self.assertEqual(list(db.keys()), [b'key'])
     176              self.assertTrue(b'key' in db)
     177              self.assertEqual(db[b'key'], b'value')
     178  
     179      def test_nonexisting_file(self):
     180          nonexisting_file = 'nonexisting-file'
     181          with self.assertRaises(gdbm.error) as cm:
     182              gdbm.open(nonexisting_file)
     183          self.assertIn(nonexisting_file, str(cm.exception))
     184          self.assertEqual(cm.exception.filename, nonexisting_file)
     185  
     186      def test_open_with_pathlib_path(self):
     187          gdbm.open(FakePath(filename), "c").close()
     188  
     189      def test_open_with_bytes_path(self):
     190          gdbm.open(os.fsencode(filename), "c").close()
     191  
     192      def test_open_with_pathlib_bytes_path(self):
     193          gdbm.open(FakePath(os.fsencode(filename)), "c").close()
     194  
     195  
     196  if __name__ == '__main__':
     197      unittest.main()