[Python-checkins] cpython (merge default -> default): Merge heads
serhiy.storchaka
python-checkins at python.org
Sun Nov 17 11:58:36 CET 2013
http://hg.python.org/cpython/rev/9c2da409dfaa
changeset: 87188:9c2da409dfaa
parent: 87186:e8276bb6a156
parent: 87177:d6ad412dee40
user: Serhiy Storchaka <storchaka at gmail.com>
date: Sun Nov 17 12:30:50 2013 +0200
summary:
Merge heads
files:
.hgtags | 2 +
Doc/library/dbm.rst | 38 +++++++++++++++-----------
Doc/library/string.rst | 2 +-
Lib/dbm/dumb.py | 6 ++++
Lib/test/test_dbm_dumb.py | 13 +++++++++
Lib/test/test_dbm_gnu.py | 11 +++++++
Lib/test/test_dbm_ndbm.py | 13 +++++++++
Misc/NEWS | 3 ++
Modules/_dbmmodule.c | 17 ++++++++++++
Modules/_gdbmmodule.c | 16 +++++++++++
10 files changed, 104 insertions(+), 17 deletions(-)
diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -116,6 +116,8 @@
d9893d13c6289aa03d33559ec67f97dcbf5c9e3c v3.3.1
d047928ae3f6314a13b6137051315453d0ae89b6 v3.3.2
fd53c500f8b80f54f3ecedec9da2e8c7e52a6888 v3.3.3rc1
+d32442c0e60dfbd71234e807d3d1dedd227495a9 v3.3.3rc2
+c3896275c0f61b2510a6c7e6c458a750359a91b8 v3.3.3
46535f65e7f3bcdcf176f36d34bc1fed719ffd2b v3.4.0a1
9265a2168e2cb2a84785d8717792acc661e6b692 v3.4.0a2
dd9cdf90a5073510877e9dd5112f8e6cf20d5e89 v3.4.0a3
diff --git a/Doc/library/dbm.rst b/Doc/library/dbm.rst
--- a/Doc/library/dbm.rst
+++ b/Doc/library/dbm.rst
@@ -73,33 +73,39 @@
strings are used they are implicitly converted to the default encoding before
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
then prints out the contents of the database::
import dbm
# Open database, creating it if necessary.
- db = dbm.open('cache', 'c')
+ with dbm.open('cache', 'c') as db:
- # Record some values
- db[b'hello'] = b'there'
- db['www.python.org'] = 'Python Website'
- db['www.cnn.com'] = 'Cable News Network'
+ # Record some values
+ db[b'hello'] = b'there'
+ db['www.python.org'] = 'Python Website'
+ db['www.cnn.com'] = 'Cable News Network'
- # Note that the keys are considered bytes now.
- assert db[b'www.python.org'] == b'Python Website'
- # Notice how the value is now in bytes.
- assert db['www.cnn.com'] == b'Cable News Network'
+ # Note that the keys are considered bytes now.
+ assert db[b'www.python.org'] == b'Python Website'
+ # Notice how the value is now in bytes.
+ assert db['www.cnn.com'] == b'Cable News Network'
- # Often-used methods of the dict interface work too.
- print(db.get('python.org', b'not present'))
+ # Often-used methods of the dict interface work too.
+ print(db.get('python.org', b'not present'))
- # Storing a non-string key or value will raise an exception (most
- # likely a TypeError).
- db['www.yahoo.com'] = 4
+ # Storing a non-string key or value will raise an exception (most
+ # likely a TypeError).
+ db['www.yahoo.com'] = 4
- # Close when done.
- db.close()
+ # db is automatically closed when leaving the with statement.
.. seealso::
diff --git a/Doc/library/string.rst b/Doc/library/string.rst
--- a/Doc/library/string.rst
+++ b/Doc/library/string.rst
@@ -300,7 +300,7 @@
precision: `integer`
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.
Note that it is not possible to use ``{`` and ``}`` as *fill* char while
using the :meth:`str.format` method; this limitation however doesn't
diff --git a/Lib/dbm/dumb.py b/Lib/dbm/dumb.py
--- a/Lib/dbm/dumb.py
+++ b/Lib/dbm/dumb.py
@@ -236,6 +236,12 @@
if hasattr(self._os, 'chmod'):
self._os.chmod(file, self._mode)
+ def __enter__(self):
+ return self
+
+ def __exit__(self, *args):
+ self.close()
+
def open(file, flag=None, mode=0o666):
"""Open the database file, filename, and return corresponding object.
diff --git a/Lib/test/test_dbm_dumb.py b/Lib/test/test_dbm_dumb.py
--- a/Lib/test/test_dbm_dumb.py
+++ b/Lib/test/test_dbm_dumb.py
@@ -184,6 +184,19 @@
self.assertEqual(expected, got)
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):
_delete_files()
diff --git a/Lib/test/test_dbm_gnu.py b/Lib/test/test_dbm_gnu.py
--- a/Lib/test/test_dbm_gnu.py
+++ b/Lib/test/test_dbm_gnu.py
@@ -81,6 +81,17 @@
size2 = os.path.getsize(filename)
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__':
unittest.main()
diff --git a/Lib/test/test_dbm_ndbm.py b/Lib/test/test_dbm_ndbm.py
--- a/Lib/test/test_dbm_ndbm.py
+++ b/Lib/test/test_dbm_ndbm.py
@@ -37,5 +37,18 @@
except error:
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__':
unittest.main()
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -50,6 +50,9 @@
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,
sunau, and wave modules.
diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c
--- a/Modules/_dbmmodule.c
+++ b/Modules/_dbmmodule.c
@@ -313,6 +313,21 @@
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[] = {
{"close", (PyCFunction)dbm__close, METH_NOARGS,
"close()\nClose the database."},
@@ -325,6 +340,8 @@
"setdefault(key[, default]) -> value\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."},
+ {"__enter__", dbm__enter__, METH_NOARGS, NULL},
+ {"__exit__", dbm__exit__, METH_VARARGS, NULL},
{NULL, NULL} /* sentinel */
};
diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c
--- a/Modules/_gdbmmodule.c
+++ b/Modules/_gdbmmodule.c
@@ -425,6 +425,20 @@
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[] = {
{"close", (PyCFunction)dbm_close, METH_NOARGS, dbm_close__doc__},
{"keys", (PyCFunction)dbm_keys, METH_NOARGS, dbm_keys__doc__},
@@ -434,6 +448,8 @@
{"sync", (PyCFunction)dbm_sync, METH_NOARGS, dbm_sync__doc__},
{"get", (PyCFunction)dbm_get, METH_VARARGS, dbm_get__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 */
};
--
Repository URL: http://hg.python.org/cpython
More information about the Python-checkins
mailing list