Skip to content

Commit ff64721

Browse files
committed
gh-113093: add parameter 'mode' in shelve.open, letting users control file's type and access permissions
1 parent a86234e commit ff64721

File tree

5 files changed

+29
-13
lines changed

5 files changed

+29
-13
lines changed

Doc/library/shelve.rst

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ lots of shared sub-objects. The keys are ordinary strings.
4242
determine which accessed entries are mutable, nor which ones were actually
4343
mutated).
4444

45+
The optional *mode* parameter controls the file mode (permissions) when creating
46+
a new shelf. It is passed to :func:`dbm.open` and defaults to ``0o666`` (octal),
47+
which means read and write permissions for everyone, subject to the current umask.
48+
This parameter has no effect if the database already exists.
49+
4550
By default, :mod:`!shelve` uses :func:`pickle.dumps` and :func:`pickle.loads`
4651
for serializing and deserializing. This can be changed by supplying
4752
*serializer* and *deserializer*, respectively.
@@ -209,19 +214,19 @@ Restrictions
209214

210215

211216
.. class:: DbfilenameShelf(filename, flag='c', protocol=None, \
212-
writeback=False, *, serializer=None, \
213-
deserializer=None)
217+
writeback=False, mode=0o666, *, \
218+
serializer=None, deserializer=None)
214219
215220
A subclass of :class:`Shelf` which accepts a *filename* instead of a dict-like
216221
object. The underlying file will be opened using :func:`dbm.open`. By
217222
default, the file will be created and opened for both read and write. The
218223
optional *flag* parameter has the same interpretation as for the
219-
:func:`.open` function. The optional *protocol*, *writeback*, *serializer*
224+
:func:`.open` function. The optional *mode*, *protocol*, *writeback*, *serializer*
220225
and *deserializer* parameters have the same interpretation as in
221226
:func:`~shelve.open`.
222227

223228
.. versionchanged:: 3.15
224-
Added the *serializer* and *deserializer* parameters.
229+
Added the *mode*, *serializer* and *deserializer* parameters.
225230

226231

227232
.. _shelve-example:
@@ -284,4 +289,3 @@ Exceptions
284289

285290
Module :mod:`pickle`
286291
Object serialization used by :mod:`!shelve`.
287-

Doc/whatsnew/3.15.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,8 @@ shelve
10241024
* Add support for custom serialization and deserialization functions
10251025
in the :mod:`shelve` module.
10261026
(Contributed by Furkan Onder in :gh:`99631`.)
1027-
1027+
* Add suport for custom mode in :func:`shelve.open`.
1028+
(Contributed by Guilherme Crocetti in :gh:`113093`.)
10281029

10291030
socket
10301031
------

Lib/shelve.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,10 @@ class DbfilenameShelf(Shelf):
235235
See the module's __doc__ string for an overview of the interface.
236236
"""
237237

238-
def __init__(self, filename, flag='c', protocol=None, writeback=False, *,
239-
serializer=None, deserializer=None):
238+
def __init__(self, filename, flag='c', protocol=None, writeback=False,
239+
mode=0o666, *, serializer=None, deserializer=None):
240240
import dbm
241-
Shelf.__init__(self, dbm.open(filename, flag), protocol, writeback,
241+
Shelf.__init__(self, dbm.open(filename, flag, mode), protocol, writeback,
242242
serializer=serializer, deserializer=deserializer)
243243

244244
def clear(self):
@@ -248,19 +248,21 @@ def clear(self):
248248
self.cache.clear()
249249
self.dict.clear()
250250

251-
def open(filename, flag='c', protocol=None, writeback=False, *,
252-
serializer=None, deserializer=None):
251+
def open(filename, flag='c', protocol=None, writeback=False,
252+
mode=0o666, *, serializer=None, deserializer=None):
253253
"""Open a persistent dictionary for reading and writing.
254254
255255
The filename parameter is the base filename for the underlying
256256
database. As a side-effect, an extension may be added to the
257257
filename and more than one file may be created. The optional flag
258258
parameter has the same interpretation as the flag parameter of
259259
dbm.open(). The optional protocol parameter specifies the
260-
version of the pickle protocol.
260+
version of the pickle protocol. The optional mode parameter is
261+
passed to dbm.open() and controls the file mode when creating a
262+
new shelf, set to 0666 by default.
261263
262264
See the module's __doc__ string for an overview of the interface.
263265
"""
264266

265-
return DbfilenameShelf(filename, flag, protocol, writeback,
267+
return DbfilenameShelf(filename, flag, protocol, writeback, mode,
266268
serializer=serializer, deserializer=deserializer)

Lib/test/test_shelve.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import array
22
import unittest
3+
from unittest import mock
34
import dbm
45
import shelve
56
import pickle
@@ -47,6 +48,12 @@ class TestCase(unittest.TestCase):
4748
dirname = os_helper.TESTFN
4849
fn = os.path.join(os_helper.TESTFN, "shelftemp.db")
4950

51+
@mock.patch("dbm.open", autospec=True)
52+
def test_open_calls_dbm_as_expected(self, dbm_open):
53+
shelf_open_mode = 0o433
54+
shelve.open(filename=self.fn, mode=shelf_open_mode)
55+
dbm_open.assert_called_once_with(self.fn, 'c', shelf_open_mode)
56+
5057
def test_close(self):
5158
d1 = {}
5259
s = shelve.Shelf(d1, protocol=2, writeback=False)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add parameter *mode* in :func:`shelve.open`.
2+
Contributed by Guilherme Crocetti.

0 commit comments

Comments
 (0)