| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 973cae0 commit 6f600ff
8 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -281,6 +281,21 @@ def test_readonly_files(self): | |||
| 281 | 281 | self.assertEqual(sorted(f.keys()), sorted(self._dict)) | |
| 282 | 282 | f.close() # don't write | |
| 283 | 283 | ||
| 284 | + @unittest.skipUnless(support.TESTFN_NONASCII, | ||
| 285 | + 'requires OS support of non-ASCII encodings') | ||
| 286 | + def test_nonascii_filename(self): | ||
| 287 | + filename = support.TESTFN_NONASCII | ||
| 288 | + for suffix in ['.dir', '.dat', '.bak']: | ||
| 289 | + self.addCleanup(support.unlink, filename + suffix) | ||
| 290 | + with dumbdbm.open(filename, 'c') as db: | ||
| 291 | + db[b'key'] = b'value' | ||
| 292 | + self.assertTrue(os.path.exists(filename + '.dat')) | ||
| 293 | + self.assertTrue(os.path.exists(filename + '.dir')) | ||
| 294 | + with dumbdbm.open(filename, 'r') as db: | ||
| 295 | + self.assertEqual(list(db.keys()), [b'key']) | ||
| 296 | + self.assertTrue(b'key' in db) | ||
| 297 | + self.assertEqual(db[b'key'], b'value') | ||
| 298 | + | ||
| 284 | 299 | def tearDown(self): | |
| 285 | 300 | _delete_files() | |
| 286 | 301 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -2,7 +2,7 @@ | |||
| 2 | 2 | gdbm = support.import_module("dbm.gnu") #skip if not supported | |
| 3 | 3 | import unittest | |
| 4 | 4 | import os | |
| 5 | - from test.support import TESTFN, unlink | ||
| 5 | + from test.support import TESTFN, TESTFN_NONASCII, unlink | ||
| 6 | 6 | ||
| 7 | 7 | ||
| 8 | 8 | filename = TESTFN | |
@@ -93,5 +93,39 @@ def test_context_manager(self): | |||
| 93 | 93 | self.assertEqual(str(cm.exception), | |
| 94 | 94 | "GDBM object has already been closed") | |
| 95 | 95 | ||
| 96 | + def test_bytes(self): | ||
| 97 | + with gdbm.open(filename, 'c') as db: | ||
| 98 | + db[b'bytes key \xbd'] = b'bytes value \xbd' | ||
| 99 | + with gdbm.open(filename, 'r') as db: | ||
| 100 | + self.assertEqual(list(db.keys()), [b'bytes key \xbd']) | ||
| 101 | + self.assertTrue(b'bytes key \xbd' in db) | ||
| 102 | + self.assertEqual(db[b'bytes key \xbd'], b'bytes value \xbd') | ||
| 103 | + | ||
| 104 | + def test_unicode(self): | ||
| 105 | + with gdbm.open(filename, 'c') as db: | ||
| 106 | + db['Unicode key \U0001f40d'] = 'Unicode value \U0001f40d' | ||
| 107 | + with gdbm.open(filename, 'r') as db: | ||
| 108 | + self.assertEqual(list(db.keys()), ['Unicode key \U0001f40d'.encode()]) | ||
| 109 | + self.assertTrue('Unicode key \U0001f40d'.encode() in db) | ||
| 110 | + self.assertTrue('Unicode key \U0001f40d' in db) | ||
| 111 | + self.assertEqual(db['Unicode key \U0001f40d'.encode()], | ||
| 112 | + 'Unicode value \U0001f40d'.encode()) | ||
| 113 | + self.assertEqual(db['Unicode key \U0001f40d'], | ||
| 114 | + 'Unicode value \U0001f40d'.encode()) | ||
| 115 | + | ||
| 116 | + @unittest.skipUnless(TESTFN_NONASCII, | ||
| 117 | + 'requires OS support of non-ASCII encodings') | ||
| 118 | + def test_nonascii_filename(self): | ||
| 119 | + filename = TESTFN_NONASCII | ||
| 120 | + self.addCleanup(unlink, filename) | ||
| 121 | + with gdbm.open(filename, 'c') as db: | ||
| 122 | + db[b'key'] = b'value' | ||
| 123 | + self.assertTrue(os.path.exists(filename)) | ||
| 124 | + with gdbm.open(filename, 'r') as db: | ||
| 125 | + self.assertEqual(list(db.keys()), [b'key']) | ||
| 126 | + self.assertTrue(b'key' in db) | ||
| 127 | + self.assertEqual(db[b'key'], b'value') | ||
| 128 | + | ||
| 129 | + | ||
| 96 | 130 | if __name__ == '__main__': | |
| 97 | 131 | unittest.main() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,5 +1,6 @@ | |||
| 1 | 1 | from test import support | |
| 2 | 2 | support.import_module("dbm.ndbm") #skip if not supported | |
| 3 | + import os | ||
| 3 | 4 | import unittest | |
| 4 | 5 | import dbm.ndbm | |
| 5 | 6 | from dbm.ndbm import error | |
@@ -47,6 +48,42 @@ def test_context_manager(self): | |||
| 47 | 48 | self.assertEqual(str(cm.exception), | |
| 48 | 49 | "DBM object has already been closed") | |
| 49 | 50 | ||
| 51 | + def test_bytes(self): | ||
| 52 | + with dbm.ndbm.open(self.filename, 'c') as db: | ||
| 53 | + db[b'bytes key \xbd'] = b'bytes value \xbd' | ||
| 54 | + with dbm.ndbm.open(self.filename, 'r') as db: | ||
| 55 | + self.assertEqual(list(db.keys()), [b'bytes key \xbd']) | ||
| 56 | + self.assertTrue(b'bytes key \xbd' in db) | ||
| 57 | + self.assertEqual(db[b'bytes key \xbd'], b'bytes value \xbd') | ||
| 58 | + | ||
| 59 | + def test_unicode(self): | ||
| 60 | + with dbm.ndbm.open(self.filename, 'c') as db: | ||
| 61 | + db['Unicode key \U0001f40d'] = 'Unicode value \U0001f40d' | ||
| 62 | + with dbm.ndbm.open(self.filename, 'r') as db: | ||
| 63 | + self.assertEqual(list(db.keys()), ['Unicode key \U0001f40d'.encode()]) | ||
| 64 | + self.assertTrue('Unicode key \U0001f40d'.encode() in db) | ||
| 65 | + self.assertTrue('Unicode key \U0001f40d' in db) | ||
| 66 | + self.assertEqual(db['Unicode key \U0001f40d'.encode()], | ||
| 67 | + 'Unicode value \U0001f40d'.encode()) | ||
| 68 | + self.assertEqual(db['Unicode key \U0001f40d'], | ||
| 69 | + 'Unicode value \U0001f40d'.encode()) | ||
| 70 | + | ||
| 71 | + @unittest.skipUnless(support.TESTFN_NONASCII, | ||
| 72 | + 'requires OS support of non-ASCII encodings') | ||
| 73 | + def test_nonascii_filename(self): | ||
| 74 | + filename = support.TESTFN_NONASCII | ||
| 75 | + for suffix in ['', '.pag', '.dir', '.db']: | ||
| 76 | + self.addCleanup(support.unlink, filename + suffix) | ||
| 77 | + with dbm.ndbm.open(filename, 'c') as db: | ||
| 78 | + db[b'key'] = b'value' | ||
| 79 | + self.assertTrue(any(os.path.exists(filename + suffix) | ||
| 80 | + for suffix in ['', '.pag', '.dir', '.db'])) | ||
| 81 | + with dbm.ndbm.open(filename, 'r') as db: | ||
| 82 | + self.assertEqual(list(db.keys()), [b'key']) | ||
| 83 | + self.assertTrue(b'key' in db) | ||
| 84 | + self.assertEqual(db[b'key'], b'value') | ||
| 85 | + | ||
| 86 | + | ||
| 50 | 87 | ||
| 51 | 88 | if __name__ == '__main__': | |
| 52 | 89 | unittest.main() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + dbm.open() now encodes filename with the filesystem encoding rather than | ||
| 2 | + default encoding. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -412,7 +412,7 @@ static PyTypeObject Dbmtype = { | |||
| 412 | 412 | ||
| 413 | 413 | _dbm.open as dbmopen | |
| 414 | 414 | ||
| 415 | - filename: str | ||
| 415 | + filename: unicode | ||
| 416 | 416 | The filename to open. | |
| 417 | 417 | ||
| 418 | 418 | flags: str="r" | |
@@ -429,9 +429,9 @@ Return a database object. | |||
| 429 | 429 | [clinic start generated code]*/ | |
| 430 | 430 | ||
| 431 | 431 | static PyObject * | |
| 432 | - dbmopen_impl(PyObject *module, const char *filename, const char *flags, | ||
| 432 | + dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, | ||
| 433 | 433 | int mode) | |
| 434 | - /*[clinic end generated code: output=5fade8cf16e0755f input=226334bade5764e6]*/ | ||
| 434 | + /*[clinic end generated code: output=9527750f5df90764 input=376a9d903a50df59]*/ | ||
| 435 | 435 | { | |
| 436 | 436 | int iflags; | |
| 437 | 437 | ||
@@ -450,7 +450,20 @@ dbmopen_impl(PyObject *module, const char *filename, const char *flags, | |||
| 450 | 450 | "arg 2 to open should be 'r', 'w', 'c', or 'n'"); | |
| 451 | 451 | return NULL; | |
| 452 | 452 | } | |
| 453 | - return newdbmobject(filename, iflags, mode); | ||
| 453 | + | ||
| 454 | + PyObject *filenamebytes = PyUnicode_EncodeFSDefault(filename); | ||
| 455 | + if (filenamebytes == NULL) { | ||
| 456 | + return NULL; | ||
| 457 | + } | ||
| 458 | + const char *name = PyBytes_AS_STRING(filenamebytes); | ||
| 459 | + if (strlen(name) != (size_t)PyBytes_GET_SIZE(filenamebytes)) { | ||
| 460 | + Py_DECREF(filenamebytes); | ||
| 461 | + PyErr_SetString(PyExc_ValueError, "embedded null character"); | ||
| 462 | + return NULL; | ||
| 463 | + } | ||
| 464 | + PyObject *self = newdbmobject(name, iflags, mode); | ||
| 465 | + Py_DECREF(filenamebytes); | ||
| 466 | + return self; | ||
| 454 | 467 | } | |
| 455 | 468 | ||
| 456 | 469 | static PyMethodDef dbmmodule_methods[] = { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -527,7 +527,7 @@ static PyTypeObject Dbmtype = { | |||
| 527 | 527 | ||
| 528 | 528 | /*[clinic input] | |
| 529 | 529 | _gdbm.open as dbmopen | |
| 530 | - filename as name: str | ||
| 530 | + filename: unicode | ||
| 531 | 531 | flags: str="r" | |
| 532 | 532 | mode: int(py_default="0o666") = 0o666 | |
| 533 | 533 | / | |
@@ -557,8 +557,9 @@ when the database has to be created. It defaults to octal 0o666. | |||
| 557 | 557 | [clinic start generated code]*/ | |
| 558 | 558 | ||
| 559 | 559 | static PyObject * | |
| 560 | - dbmopen_impl(PyObject *module, const char *name, const char *flags, int mode) | ||
| 561 | - /*[clinic end generated code: output=31aa1bafdf5da688 input=55563cd60e51984a]*/ | ||
| 560 | + dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, | ||
| 561 | + int mode) | ||
| 562 | + /*[clinic end generated code: output=9527750f5df90764 input=3be0b0875974b928]*/ | ||
| 562 | 563 | { | |
| 563 | 564 | int iflags; | |
| 564 | 565 | ||
@@ -606,7 +607,19 @@ dbmopen_impl(PyObject *module, const char *name, const char *flags, int mode) | |||
| 606 | 607 | } | |
| 607 | 608 | } | |
| 608 | 609 | ||
| 609 | - return newdbmobject(name, iflags, mode); | ||
| 610 | + PyObject *filenamebytes = PyUnicode_EncodeFSDefault(filename); | ||
| 611 | + if (filenamebytes == NULL) { | ||
| 612 | + return NULL; | ||
| 613 | + } | ||
| 614 | + const char *name = PyBytes_AS_STRING(filenamebytes); | ||
| 615 | + if (strlen(name) != (size_t)PyBytes_GET_SIZE(filenamebytes)) { | ||
| 616 | + Py_DECREF(filenamebytes); | ||
| 617 | + PyErr_SetString(PyExc_ValueError, "embedded null character"); | ||
| 618 | + return NULL; | ||
| 619 | + } | ||
| 620 | + PyObject *self = newdbmobject(name, iflags, mode); | ||
| 621 | + Py_DECREF(filenamebytes); | ||
| 622 | + return self; | ||
| 610 | 623 | } | |
| 611 | 624 | ||
| 612 | 625 | static const char dbmmodule_open_flags[] = "rwcn" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -121,18 +121,18 @@ PyDoc_STRVAR(dbmopen__doc__, | |||
| 121 | 121 | {"open", (PyCFunction)dbmopen, METH_FASTCALL, dbmopen__doc__}, | |
| 122 | 122 | ||
| 123 | 123 | static PyObject * | |
| 124 | - dbmopen_impl(PyObject *module, const char *filename, const char *flags, | ||
| 124 | + dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, | ||
| 125 | 125 | int mode); | |
| 126 | 126 | ||
| 127 | 127 | static PyObject * | |
| 128 | 128 | dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) | |
| 129 | 129 | { | |
| 130 | 130 | PyObject *return_value = NULL; | |
| 131 | - const char *filename; | ||
| 131 | + PyObject *filename; | ||
| 132 | 132 | const char *flags = "r"; | |
| 133 | 133 | int mode = 438; | |
| 134 | 134 | ||
| 135 | - if (!_PyArg_ParseStack(args, nargs, "s|si:open", | ||
| 135 | + if (!_PyArg_ParseStack(args, nargs, "U|si:open", | ||
| 136 | 136 | &filename, &flags, &mode)) { | |
| 137 | 137 | goto exit; | |
| 138 | 138 | } | |
@@ -141,4 +141,4 @@ dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) | |||
| 141 | 141 | exit: | |
| 142 | 142 | return return_value; | |
| 143 | 143 | } | |
| 144 | - /*[clinic end generated code: output=8ce71abac849155f input=a9049054013a1b77]*/ | ||
| 144 | + /*[clinic end generated code: output=5c858b4080a011a4 input=a9049054013a1b77]*/ | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -234,23 +234,24 @@ PyDoc_STRVAR(dbmopen__doc__, | |||
| 234 | 234 | {"open", (PyCFunction)dbmopen, METH_FASTCALL, dbmopen__doc__}, | |
| 235 | 235 | ||
| 236 | 236 | static PyObject * | |
| 237 | - dbmopen_impl(PyObject *module, const char *name, const char *flags, int mode); | ||
| 237 | + dbmopen_impl(PyObject *module, PyObject *filename, const char *flags, | ||
| 238 | + int mode); | ||
| 238 | 239 | ||
| 239 | 240 | static PyObject * | |
| 240 | 241 | dbmopen(PyObject *module, PyObject *const *args, Py_ssize_t nargs) | |
| 241 | 242 | { | |
| 242 | 243 | PyObject *return_value = NULL; | |
| 243 | - const char *name; | ||
| 244 | + PyObject *filename; | ||
| 244 | 245 | const char *flags = "r"; | |
| 245 | 246 | int mode = 438; | |
| 246 | 247 | ||
| 247 | - if (!_PyArg_ParseStack(args, nargs, "s|si:open", | ||
| 248 | - &name, &flags, &mode)) { | ||
| 248 | + if (!_PyArg_ParseStack(args, nargs, "U|si:open", | ||
| 249 | + &filename, &flags, &mode)) { | ||
| 249 | 250 | goto exit; | |
| 250 | 251 | } | |
| 251 | - return_value = dbmopen_impl(module, name, flags, mode); | ||
| 252 | + return_value = dbmopen_impl(module, filename, flags, mode); | ||
| 252 | 253 | ||
| 253 | 254 | exit: | |
| 254 | 255 | return return_value; | |
| 255 | 256 | } | |
| 256 | - /*[clinic end generated code: output=dc0aca8c00055d02 input=a9049054013a1b77]*/ | ||
| 257 | + /*[clinic end generated code: output=dec05ff9c5aeaeae input=a9049054013a1b77]*/ | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments