(root)/
Python-3.12.0/
Lib/
test/
test_dbm.py
       1  """Test script for the dbm.open function based on testdumbdbm.py"""
       2  
       3  import unittest
       4  import dbm
       5  import os
       6  from test.support import import_helper
       7  from test.support import os_helper
       8  
       9  try:
      10      from dbm import ndbm
      11  except ImportError:
      12      ndbm = None
      13  
      14  dirname = os_helper.TESTFN
      15  _fname = os.path.join(dirname, os_helper.TESTFN)
      16  
      17  #
      18  # Iterates over every database module supported by dbm currently available.
      19  #
      20  def dbm_iterator():
      21      for name in dbm._names:
      22          try:
      23              mod = __import__(name, fromlist=['open'])
      24          except ImportError:
      25              continue
      26          dbm._modules[name] = mod
      27          yield mod
      28  
      29  #
      30  # Clean up all scratch databases we might have created during testing
      31  #
      32  def cleaunup_test_dir():
      33      os_helper.rmtree(dirname)
      34  
      35  def setup_test_dir():
      36      cleaunup_test_dir()
      37      os.mkdir(dirname)
      38  
      39  
      40  class ESC[4;38;5;81mAnyDBMTestCase:
      41      _dict = {'a': b'Python:',
      42               'b': b'Programming',
      43               'c': b'the',
      44               'd': b'way',
      45               'f': b'Guido',
      46               'g': b'intended',
      47               }
      48  
      49      def init_db(self):
      50          f = dbm.open(_fname, 'n')
      51          for k in self._dict:
      52              f[k.encode("ascii")] = self._dict[k]
      53          f.close()
      54  
      55      def keys_helper(self, f):
      56          keys = sorted(k.decode("ascii") for k in f.keys())
      57          dkeys = sorted(self._dict.keys())
      58          self.assertEqual(keys, dkeys)
      59          return keys
      60  
      61      def test_error(self):
      62          self.assertTrue(issubclass(self.module.error, OSError))
      63  
      64      def test_anydbm_not_existing(self):
      65          self.assertRaises(dbm.error, dbm.open, _fname)
      66  
      67      def test_anydbm_creation(self):
      68          f = dbm.open(_fname, 'c')
      69          self.assertEqual(list(f.keys()), [])
      70          for key in self._dict:
      71              f[key.encode("ascii")] = self._dict[key]
      72          self.read_helper(f)
      73          f.close()
      74  
      75      def test_anydbm_creation_n_file_exists_with_invalid_contents(self):
      76          # create an empty file
      77          os_helper.create_empty_file(_fname)
      78          with dbm.open(_fname, 'n') as f:
      79              self.assertEqual(len(f), 0)
      80  
      81      def test_anydbm_modification(self):
      82          self.init_db()
      83          f = dbm.open(_fname, 'c')
      84          self._dict['g'] = f[b'g'] = b"indented"
      85          self.read_helper(f)
      86          # setdefault() works as in the dict interface
      87          self.assertEqual(f.setdefault(b'xxx', b'foo'), b'foo')
      88          self.assertEqual(f[b'xxx'], b'foo')
      89          f.close()
      90  
      91      def test_anydbm_read(self):
      92          self.init_db()
      93          f = dbm.open(_fname, 'r')
      94          self.read_helper(f)
      95          # get() works as in the dict interface
      96          self.assertEqual(f.get(b'a'), self._dict['a'])
      97          self.assertEqual(f.get(b'xxx', b'foo'), b'foo')
      98          self.assertIsNone(f.get(b'xxx'))
      99          with self.assertRaises(KeyError):
     100              f[b'xxx']
     101          f.close()
     102  
     103      def test_anydbm_keys(self):
     104          self.init_db()
     105          f = dbm.open(_fname, 'r')
     106          keys = self.keys_helper(f)
     107          f.close()
     108  
     109      def test_empty_value(self):
     110          if getattr(dbm._defaultmod, 'library', None) == 'Berkeley DB':
     111              self.skipTest("Berkeley DB doesn't distinguish the empty value "
     112                            "from the absent one")
     113          f = dbm.open(_fname, 'c')
     114          self.assertEqual(f.keys(), [])
     115          f[b'empty'] = b''
     116          self.assertEqual(f.keys(), [b'empty'])
     117          self.assertIn(b'empty', f)
     118          self.assertEqual(f[b'empty'], b'')
     119          self.assertEqual(f.get(b'empty'), b'')
     120          self.assertEqual(f.setdefault(b'empty'), b'')
     121          f.close()
     122  
     123      def test_anydbm_access(self):
     124          self.init_db()
     125          f = dbm.open(_fname, 'r')
     126          key = "a".encode("ascii")
     127          self.assertIn(key, f)
     128          assert(f[key] == b"Python:")
     129          f.close()
     130  
     131      def test_open_with_bytes(self):
     132          dbm.open(os.fsencode(_fname), "c").close()
     133  
     134      def test_open_with_pathlib_path(self):
     135          dbm.open(os_helper.FakePath(_fname), "c").close()
     136  
     137      def test_open_with_pathlib_path_bytes(self):
     138          dbm.open(os_helper.FakePath(os.fsencode(_fname)), "c").close()
     139  
     140      def read_helper(self, f):
     141          keys = self.keys_helper(f)
     142          for key in self._dict:
     143              self.assertEqual(self._dict[key], f[key.encode("ascii")])
     144  
     145      def test_keys(self):
     146          with dbm.open(_fname, 'c') as d:
     147              self.assertEqual(d.keys(), [])
     148              a = [(b'a', b'b'), (b'12345678910', b'019237410982340912840198242')]
     149              for k, v in a:
     150                  d[k] = v
     151              self.assertEqual(sorted(d.keys()), sorted(k for (k, v) in a))
     152              for k, v in a:
     153                  self.assertIn(k, d)
     154                  self.assertEqual(d[k], v)
     155              self.assertNotIn(b'xxx', d)
     156              self.assertRaises(KeyError, lambda: d[b'xxx'])
     157  
     158      def setUp(self):
     159          self.addCleanup(setattr, dbm, '_defaultmod', dbm._defaultmod)
     160          dbm._defaultmod = self.module
     161          self.addCleanup(cleaunup_test_dir)
     162          setup_test_dir()
     163  
     164  
     165  class ESC[4;38;5;81mWhichDBTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     166      def test_whichdb(self):
     167          self.addCleanup(setattr, dbm, '_defaultmod', dbm._defaultmod)
     168          _bytes_fname = os.fsencode(_fname)
     169          fnames = [_fname, os_helper.FakePath(_fname),
     170                    _bytes_fname, os_helper.FakePath(_bytes_fname)]
     171          for module in dbm_iterator():
     172              # Check whether whichdb correctly guesses module name
     173              # for databases opened with "module" module.
     174              name = module.__name__
     175              setup_test_dir()
     176              dbm._defaultmod = module
     177              # Try with empty files first
     178              with module.open(_fname, 'c'): pass
     179              for path in fnames:
     180                  self.assertEqual(name, self.dbm.whichdb(path))
     181              # Now add a key
     182              with module.open(_fname, 'w') as f:
     183                  f[b"1"] = b"1"
     184                  # and test that we can find it
     185                  self.assertIn(b"1", f)
     186                  # and read it
     187                  self.assertEqual(f[b"1"], b"1")
     188              for path in fnames:
     189                  self.assertEqual(name, self.dbm.whichdb(path))
     190  
     191      @unittest.skipUnless(ndbm, reason='Test requires ndbm')
     192      def test_whichdb_ndbm(self):
     193          # Issue 17198: check that ndbm which is referenced in whichdb is defined
     194          with open(_fname + '.db', 'wb'): pass
     195          _bytes_fname = os.fsencode(_fname)
     196          fnames = [_fname, os_helper.FakePath(_fname),
     197                    _bytes_fname, os_helper.FakePath(_bytes_fname)]
     198          for path in fnames:
     199              self.assertIsNone(self.dbm.whichdb(path))
     200  
     201      def setUp(self):
     202          self.addCleanup(cleaunup_test_dir)
     203          setup_test_dir()
     204          self.dbm = import_helper.import_fresh_module('dbm')
     205  
     206  
     207  for mod in dbm_iterator():
     208      assert mod.__name__.startswith('dbm.')
     209      suffix = mod.__name__[4:]
     210      testname = f'TestCase_{suffix}'
     211      globals()[testname] = type(testname,
     212                                 (AnyDBMTestCase, unittest.TestCase),
     213                                 {'module': mod})
     214  
     215  
     216  if __name__ == "__main__":
     217      unittest.main()