mirror of https://github.com/python/cpython
Merge heads
This commit is contained in:
commit
f532d9419d
2
.hgtags
2
.hgtags
|
@ -116,6 +116,8 @@ bd8afb90ebf28ba4edc901d4a235f75e7bbc79fd v3.3.0
|
||||||
d9893d13c6289aa03d33559ec67f97dcbf5c9e3c v3.3.1
|
d9893d13c6289aa03d33559ec67f97dcbf5c9e3c v3.3.1
|
||||||
d047928ae3f6314a13b6137051315453d0ae89b6 v3.3.2
|
d047928ae3f6314a13b6137051315453d0ae89b6 v3.3.2
|
||||||
fd53c500f8b80f54f3ecedec9da2e8c7e52a6888 v3.3.3rc1
|
fd53c500f8b80f54f3ecedec9da2e8c7e52a6888 v3.3.3rc1
|
||||||
|
d32442c0e60dfbd71234e807d3d1dedd227495a9 v3.3.3rc2
|
||||||
|
c3896275c0f61b2510a6c7e6c458a750359a91b8 v3.3.3
|
||||||
46535f65e7f3bcdcf176f36d34bc1fed719ffd2b v3.4.0a1
|
46535f65e7f3bcdcf176f36d34bc1fed719ffd2b v3.4.0a1
|
||||||
9265a2168e2cb2a84785d8717792acc661e6b692 v3.4.0a2
|
9265a2168e2cb2a84785d8717792acc661e6b692 v3.4.0a2
|
||||||
dd9cdf90a5073510877e9dd5112f8e6cf20d5e89 v3.4.0a3
|
dd9cdf90a5073510877e9dd5112f8e6cf20d5e89 v3.4.0a3
|
||||||
|
|
|
@ -73,13 +73,20 @@ Key and values are always stored as bytes. This means that when
|
||||||
strings are used they are implicitly converted to the default encoding before
|
strings are used they are implicitly converted to the default encoding before
|
||||||
being stored.
|
being stored.
|
||||||
|
|
||||||
|
These objects also support being used in a :keyword:`with` statement, which
|
||||||
|
will automatically close them when done.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.4
|
||||||
|
Added native support for the context management protocol to the objects
|
||||||
|
returned by :func:`.open`.
|
||||||
|
|
||||||
The following example records some hostnames and a corresponding title, and
|
The following example records some hostnames and a corresponding title, and
|
||||||
then prints out the contents of the database::
|
then prints out the contents of the database::
|
||||||
|
|
||||||
import dbm
|
import dbm
|
||||||
|
|
||||||
# Open database, creating it if necessary.
|
# Open database, creating it if necessary.
|
||||||
db = dbm.open('cache', 'c')
|
with dbm.open('cache', 'c') as db:
|
||||||
|
|
||||||
# Record some values
|
# Record some values
|
||||||
db[b'hello'] = b'there'
|
db[b'hello'] = b'there'
|
||||||
|
@ -98,8 +105,7 @@ then prints out the contents of the database::
|
||||||
# likely a TypeError).
|
# likely a TypeError).
|
||||||
db['www.yahoo.com'] = 4
|
db['www.yahoo.com'] = 4
|
||||||
|
|
||||||
# Close when done.
|
# db is automatically closed when leaving the with statement.
|
||||||
db.close()
|
|
||||||
|
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
|
@ -300,7 +300,7 @@ The general form of a *standard format specifier* is:
|
||||||
precision: `integer`
|
precision: `integer`
|
||||||
type: "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
|
type: "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
|
||||||
|
|
||||||
If a valid *align* value is specified, it can be preceeded by a *fill*
|
If a valid *align* value is specified, it can be preceded by a *fill*
|
||||||
character that can be any character and defaults to a space if omitted.
|
character that can be any character and defaults to a space if omitted.
|
||||||
Note that it is not possible to use ``{`` and ``}`` as *fill* char while
|
Note that it is not possible to use ``{`` and ``}`` as *fill* char while
|
||||||
using the :meth:`str.format` method; this limitation however doesn't
|
using the :meth:`str.format` method; this limitation however doesn't
|
||||||
|
|
|
@ -236,6 +236,12 @@ class _Database(collections.MutableMapping):
|
||||||
if hasattr(self._os, 'chmod'):
|
if hasattr(self._os, 'chmod'):
|
||||||
self._os.chmod(file, self._mode)
|
self._os.chmod(file, self._mode)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
|
||||||
def open(file, flag=None, mode=0o666):
|
def open(file, flag=None, mode=0o666):
|
||||||
"""Open the database file, filename, and return corresponding object.
|
"""Open the database file, filename, and return corresponding object.
|
||||||
|
|
|
@ -184,6 +184,19 @@ class DumbDBMTestCase(unittest.TestCase):
|
||||||
self.assertEqual(expected, got)
|
self.assertEqual(expected, got)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
def test_context_manager(self):
|
||||||
|
with dumbdbm.open(_fname, 'c') as db:
|
||||||
|
db["dumbdbm context manager"] = "context manager"
|
||||||
|
|
||||||
|
with dumbdbm.open(_fname, 'r') as db:
|
||||||
|
self.assertEqual(list(db.keys()), [b"dumbdbm context manager"])
|
||||||
|
|
||||||
|
# This currently just raises AttributeError rather than a specific
|
||||||
|
# exception like the GNU or NDBM based implementations. See
|
||||||
|
# http://bugs.python.org/issue19385 for details.
|
||||||
|
with self.assertRaises(Exception):
|
||||||
|
db.keys()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
_delete_files()
|
_delete_files()
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,17 @@ class TestGdbm(unittest.TestCase):
|
||||||
size2 = os.path.getsize(filename)
|
size2 = os.path.getsize(filename)
|
||||||
self.assertTrue(size1 > size2 >= size0)
|
self.assertTrue(size1 > size2 >= size0)
|
||||||
|
|
||||||
|
def test_context_manager(self):
|
||||||
|
with gdbm.open(filename, 'c') as db:
|
||||||
|
db["gdbm context manager"] = "context manager"
|
||||||
|
|
||||||
|
with gdbm.open(filename, 'r') as db:
|
||||||
|
self.assertEqual(list(db.keys()), [b"gdbm context manager"])
|
||||||
|
|
||||||
|
with self.assertRaises(gdbm.error) as cm:
|
||||||
|
db.keys()
|
||||||
|
self.assertEqual(str(cm.exception),
|
||||||
|
"GDBM object has already been closed")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -37,5 +37,18 @@ class DbmTestCase(unittest.TestCase):
|
||||||
except error:
|
except error:
|
||||||
self.fail()
|
self.fail()
|
||||||
|
|
||||||
|
def test_context_manager(self):
|
||||||
|
with dbm.ndbm.open(self.filename, 'c') as db:
|
||||||
|
db["ndbm context manager"] = "context manager"
|
||||||
|
|
||||||
|
with dbm.ndbm.open(self.filename, 'r') as db:
|
||||||
|
self.assertEqual(list(db.keys()), [b"ndbm context manager"])
|
||||||
|
|
||||||
|
with self.assertRaises(dbm.ndbm.error) as cm:
|
||||||
|
db.keys()
|
||||||
|
self.assertEqual(str(cm.exception),
|
||||||
|
"DBM object has already been closed")
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -50,6 +50,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #19282: dbm.open now supports the context manager protocol. (Inital
|
||||||
|
patch by Claudiu Popa)
|
||||||
|
|
||||||
- Issue #8311: Added support for writing any bytes-like objects in the aifc,
|
- Issue #8311: Added support for writing any bytes-like objects in the aifc,
|
||||||
sunau, and wave modules.
|
sunau, and wave modules.
|
||||||
|
|
||||||
|
|
|
@ -313,6 +313,21 @@ dbm_setdefault(dbmobject *dp, PyObject *args)
|
||||||
return defvalue;
|
return defvalue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
dbm__enter__(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
Py_INCREF(self);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
dbm__exit__(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
_Py_IDENTIFIER(close);
|
||||||
|
return _PyObject_CallMethodId(self, &PyId_close, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static PyMethodDef dbm_methods[] = {
|
static PyMethodDef dbm_methods[] = {
|
||||||
{"close", (PyCFunction)dbm__close, METH_NOARGS,
|
{"close", (PyCFunction)dbm__close, METH_NOARGS,
|
||||||
"close()\nClose the database."},
|
"close()\nClose the database."},
|
||||||
|
@ -325,6 +340,8 @@ static PyMethodDef dbm_methods[] = {
|
||||||
"setdefault(key[, default]) -> value\n"
|
"setdefault(key[, default]) -> value\n"
|
||||||
"Return the value for key if present, otherwise default. If key\n"
|
"Return the value for key if present, otherwise default. If key\n"
|
||||||
"is not in the database, it is inserted with default as the value."},
|
"is not in the database, it is inserted with default as the value."},
|
||||||
|
{"__enter__", dbm__enter__, METH_NOARGS, NULL},
|
||||||
|
{"__exit__", dbm__exit__, METH_VARARGS, NULL},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -425,6 +425,20 @@ dbm_sync(dbmobject *dp, PyObject *unused)
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
dbm__enter__(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
Py_INCREF(self);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
dbm__exit__(PyObject *self, PyObject *args)
|
||||||
|
{
|
||||||
|
_Py_IDENTIFIER(close);
|
||||||
|
return _PyObject_CallMethodId(self, &PyId_close, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static PyMethodDef dbm_methods[] = {
|
static PyMethodDef dbm_methods[] = {
|
||||||
{"close", (PyCFunction)dbm_close, METH_NOARGS, dbm_close__doc__},
|
{"close", (PyCFunction)dbm_close, METH_NOARGS, dbm_close__doc__},
|
||||||
{"keys", (PyCFunction)dbm_keys, METH_NOARGS, dbm_keys__doc__},
|
{"keys", (PyCFunction)dbm_keys, METH_NOARGS, dbm_keys__doc__},
|
||||||
|
@ -434,6 +448,8 @@ static PyMethodDef dbm_methods[] = {
|
||||||
{"sync", (PyCFunction)dbm_sync, METH_NOARGS, dbm_sync__doc__},
|
{"sync", (PyCFunction)dbm_sync, METH_NOARGS, dbm_sync__doc__},
|
||||||
{"get", (PyCFunction)dbm_get, METH_VARARGS, dbm_get__doc__},
|
{"get", (PyCFunction)dbm_get, METH_VARARGS, dbm_get__doc__},
|
||||||
{"setdefault",(PyCFunction)dbm_setdefault,METH_VARARGS, dbm_setdefault__doc__},
|
{"setdefault",(PyCFunction)dbm_setdefault,METH_VARARGS, dbm_setdefault__doc__},
|
||||||
|
{"__enter__", dbm__enter__, METH_NOARGS, NULL},
|
||||||
|
{"__exit__", dbm__exit__, METH_VARARGS, NULL},
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue