gh-111835: Add seekable method to mmap.mmap (gh-111852)

This commit is contained in:
Donghee Na 2023-11-09 11:13:35 +00:00 committed by GitHub
parent 30ec968bef
commit 6046aec377
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 40 additions and 12 deletions

View file

@ -285,6 +285,14 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
values are ``os.SEEK_CUR`` or ``1`` (seek relative to the current
position) and ``os.SEEK_END`` or ``2`` (seek relative to the file's end).
.. versionchanged:: 3.13
Return the new absolute position instead of ``None``.
.. method:: seekable()
Return whether the file supports seeking, and the return value is always ``True``.
.. versionadded:: 3.13
.. method:: size()

View file

@ -198,6 +198,14 @@ ipaddress
* Add the :attr:`ipaddress.IPv4Address.ipv6_mapped` property, which returns the IPv4-mapped IPv6 address.
(Contributed by Charles Machalow in :gh:`109466`.)
mmap
----
* The :class:`mmap.mmap` class now has an :meth:`~mmap.mmap.seekable` method
that can be used where it requires a file-like object with seekable and
the :meth:`~mmap.mmap.seek` method return the new absolute position.
(Contributed by Donghee Na and Sylvie Liberman in :gh:`111835`.)
opcode
------

View file

@ -93,11 +93,12 @@ def test_basic(self):
self.assertEqual(end, PAGESIZE + 6)
# test seeking around (try to overflow the seek implementation)
m.seek(0,0)
self.assertTrue(m.seekable())
self.assertEqual(m.seek(0, 0), 0)
self.assertEqual(m.tell(), 0)
m.seek(42,1)
self.assertEqual(m.seek(42, 1), 42)
self.assertEqual(m.tell(), 42)
m.seek(0,2)
self.assertEqual(m.seek(0, 2), len(m))
self.assertEqual(m.tell(), len(m))
# Try to seek to negative position...
@ -162,7 +163,7 @@ def test_access_parameter(self):
# Ensuring that readonly mmap can't be write() to
try:
m.seek(0,0)
m.seek(0, 0)
m.write(b'abc')
except TypeError:
pass
@ -171,7 +172,7 @@ def test_access_parameter(self):
# Ensuring that readonly mmap can't be write_byte() to
try:
m.seek(0,0)
m.seek(0, 0)
m.write_byte(b'd')
except TypeError:
pass

View file

@ -0,0 +1,4 @@
The :class:`mmap.mmap` class now has an :meth:`~mmap.mmap.seekable` method
that can be used where it requires a file-like object with seekable and
the :meth:`~mmap.mmap.seek` method return the new absolute position.
Patch by Donghee Na.

View file

@ -171,7 +171,7 @@ mmap_object_dealloc(mmap_object *m_obj)
}
static PyObject *
mmap_close_method(mmap_object *self, PyObject *unused)
mmap_close_method(mmap_object *self, PyObject *Py_UNUSED(ignored))
{
if (self->exports > 0) {
PyErr_SetString(PyExc_BufferError, "cannot close "\
@ -260,7 +260,7 @@ do { \
static PyObject *
mmap_read_byte_method(mmap_object *self,
PyObject *unused)
PyObject *Py_UNUSED(ignored))
{
CHECK_VALID(NULL);
if (self->pos >= self->size) {
@ -272,7 +272,7 @@ mmap_read_byte_method(mmap_object *self,
static PyObject *
mmap_read_line_method(mmap_object *self,
PyObject *unused)
PyObject *Py_UNUSED(ignored))
{
Py_ssize_t remaining;
char *start, *eol;
@ -460,7 +460,7 @@ mmap_write_byte_method(mmap_object *self,
static PyObject *
mmap_size_method(mmap_object *self,
PyObject *unused)
PyObject *Py_UNUSED(ignored))
{
CHECK_VALID(NULL);
@ -657,7 +657,7 @@ mmap_resize_method(mmap_object *self,
}
static PyObject *
mmap_tell_method(mmap_object *self, PyObject *unused)
mmap_tell_method(mmap_object *self, PyObject *Py_UNUSED(ignored))
{
CHECK_VALID(NULL);
return PyLong_FromSize_t(self->pos);
@ -729,7 +729,7 @@ mmap_seek_method(mmap_object *self, PyObject *args)
if (where > self->size || where < 0)
goto onoutofrange;
self->pos = where;
Py_RETURN_NONE;
return PyLong_FromSsize_t(self->pos);
}
onoutofrange:
@ -737,6 +737,12 @@ mmap_seek_method(mmap_object *self, PyObject *args)
return NULL;
}
static PyObject *
mmap_seekable_method(mmap_object *self, PyObject *Py_UNUSED(ignored))
{
Py_RETURN_TRUE;
}
static PyObject *
mmap_move_method(mmap_object *self, PyObject *args)
{
@ -835,7 +841,7 @@ mmap__repr__method(PyObject *self)
#ifdef MS_WINDOWS
static PyObject *
mmap__sizeof__method(mmap_object *self, void *unused)
mmap__sizeof__method(mmap_object *self, void *Py_UNUSED(ignored))
{
size_t res = _PyObject_SIZE(Py_TYPE(self));
if (self->tagname) {
@ -905,6 +911,7 @@ static struct PyMethodDef mmap_object_methods[] = {
{"readline", (PyCFunction) mmap_read_line_method, METH_NOARGS},
{"resize", (PyCFunction) mmap_resize_method, METH_VARARGS},
{"seek", (PyCFunction) mmap_seek_method, METH_VARARGS},
{"seekable", (PyCFunction) mmap_seekable_method, METH_NOARGS},
{"size", (PyCFunction) mmap_size_method, METH_NOARGS},
{"tell", (PyCFunction) mmap_tell_method, METH_NOARGS},
{"write", (PyCFunction) mmap_write_method, METH_VARARGS},