mirror of
https://github.com/python/cpython.git
synced 2025-10-22 14:42:22 +00:00
gh-111835: Add seekable method to mmap.mmap (gh-111852)
This commit is contained in:
parent
30ec968bef
commit
6046aec377
5 changed files with 40 additions and 12 deletions
|
@ -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
|
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).
|
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()
|
.. method:: size()
|
||||||
|
|
||||||
|
|
|
@ -198,6 +198,14 @@ ipaddress
|
||||||
* Add the :attr:`ipaddress.IPv4Address.ipv6_mapped` property, which returns the IPv4-mapped IPv6 address.
|
* Add the :attr:`ipaddress.IPv4Address.ipv6_mapped` property, which returns the IPv4-mapped IPv6 address.
|
||||||
(Contributed by Charles Machalow in :gh:`109466`.)
|
(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
|
opcode
|
||||||
------
|
------
|
||||||
|
|
||||||
|
|
|
@ -93,11 +93,12 @@ class MmapTests(unittest.TestCase):
|
||||||
self.assertEqual(end, PAGESIZE + 6)
|
self.assertEqual(end, PAGESIZE + 6)
|
||||||
|
|
||||||
# test seeking around (try to overflow the seek implementation)
|
# 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)
|
self.assertEqual(m.tell(), 0)
|
||||||
m.seek(42,1)
|
self.assertEqual(m.seek(42, 1), 42)
|
||||||
self.assertEqual(m.tell(), 42)
|
self.assertEqual(m.tell(), 42)
|
||||||
m.seek(0,2)
|
self.assertEqual(m.seek(0, 2), len(m))
|
||||||
self.assertEqual(m.tell(), len(m))
|
self.assertEqual(m.tell(), len(m))
|
||||||
|
|
||||||
# Try to seek to negative position...
|
# Try to seek to negative position...
|
||||||
|
@ -162,7 +163,7 @@ class MmapTests(unittest.TestCase):
|
||||||
|
|
||||||
# Ensuring that readonly mmap can't be write() to
|
# Ensuring that readonly mmap can't be write() to
|
||||||
try:
|
try:
|
||||||
m.seek(0,0)
|
m.seek(0, 0)
|
||||||
m.write(b'abc')
|
m.write(b'abc')
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
@ -171,7 +172,7 @@ class MmapTests(unittest.TestCase):
|
||||||
|
|
||||||
# Ensuring that readonly mmap can't be write_byte() to
|
# Ensuring that readonly mmap can't be write_byte() to
|
||||||
try:
|
try:
|
||||||
m.seek(0,0)
|
m.seek(0, 0)
|
||||||
m.write_byte(b'd')
|
m.write_byte(b'd')
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -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.
|
|
@ -171,7 +171,7 @@ mmap_object_dealloc(mmap_object *m_obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
mmap_close_method(mmap_object *self, PyObject *unused)
|
mmap_close_method(mmap_object *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
if (self->exports > 0) {
|
if (self->exports > 0) {
|
||||||
PyErr_SetString(PyExc_BufferError, "cannot close "\
|
PyErr_SetString(PyExc_BufferError, "cannot close "\
|
||||||
|
@ -260,7 +260,7 @@ do { \
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
mmap_read_byte_method(mmap_object *self,
|
mmap_read_byte_method(mmap_object *self,
|
||||||
PyObject *unused)
|
PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
CHECK_VALID(NULL);
|
CHECK_VALID(NULL);
|
||||||
if (self->pos >= self->size) {
|
if (self->pos >= self->size) {
|
||||||
|
@ -272,7 +272,7 @@ mmap_read_byte_method(mmap_object *self,
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
mmap_read_line_method(mmap_object *self,
|
mmap_read_line_method(mmap_object *self,
|
||||||
PyObject *unused)
|
PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
Py_ssize_t remaining;
|
Py_ssize_t remaining;
|
||||||
char *start, *eol;
|
char *start, *eol;
|
||||||
|
@ -460,7 +460,7 @@ mmap_write_byte_method(mmap_object *self,
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
mmap_size_method(mmap_object *self,
|
mmap_size_method(mmap_object *self,
|
||||||
PyObject *unused)
|
PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
CHECK_VALID(NULL);
|
CHECK_VALID(NULL);
|
||||||
|
|
||||||
|
@ -657,7 +657,7 @@ mmap_resize_method(mmap_object *self,
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
mmap_tell_method(mmap_object *self, PyObject *unused)
|
mmap_tell_method(mmap_object *self, PyObject *Py_UNUSED(ignored))
|
||||||
{
|
{
|
||||||
CHECK_VALID(NULL);
|
CHECK_VALID(NULL);
|
||||||
return PyLong_FromSize_t(self->pos);
|
return PyLong_FromSize_t(self->pos);
|
||||||
|
@ -729,7 +729,7 @@ mmap_seek_method(mmap_object *self, PyObject *args)
|
||||||
if (where > self->size || where < 0)
|
if (where > self->size || where < 0)
|
||||||
goto onoutofrange;
|
goto onoutofrange;
|
||||||
self->pos = where;
|
self->pos = where;
|
||||||
Py_RETURN_NONE;
|
return PyLong_FromSsize_t(self->pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
onoutofrange:
|
onoutofrange:
|
||||||
|
@ -737,6 +737,12 @@ mmap_seek_method(mmap_object *self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
mmap_seekable_method(mmap_object *self, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
Py_RETURN_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
mmap_move_method(mmap_object *self, PyObject *args)
|
mmap_move_method(mmap_object *self, PyObject *args)
|
||||||
{
|
{
|
||||||
|
@ -835,7 +841,7 @@ mmap__repr__method(PyObject *self)
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
static PyObject *
|
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));
|
size_t res = _PyObject_SIZE(Py_TYPE(self));
|
||||||
if (self->tagname) {
|
if (self->tagname) {
|
||||||
|
@ -905,6 +911,7 @@ static struct PyMethodDef mmap_object_methods[] = {
|
||||||
{"readline", (PyCFunction) mmap_read_line_method, METH_NOARGS},
|
{"readline", (PyCFunction) mmap_read_line_method, METH_NOARGS},
|
||||||
{"resize", (PyCFunction) mmap_resize_method, METH_VARARGS},
|
{"resize", (PyCFunction) mmap_resize_method, METH_VARARGS},
|
||||||
{"seek", (PyCFunction) mmap_seek_method, METH_VARARGS},
|
{"seek", (PyCFunction) mmap_seek_method, METH_VARARGS},
|
||||||
|
{"seekable", (PyCFunction) mmap_seekable_method, METH_NOARGS},
|
||||||
{"size", (PyCFunction) mmap_size_method, METH_NOARGS},
|
{"size", (PyCFunction) mmap_size_method, METH_NOARGS},
|
||||||
{"tell", (PyCFunction) mmap_tell_method, METH_NOARGS},
|
{"tell", (PyCFunction) mmap_tell_method, METH_NOARGS},
|
||||||
{"write", (PyCFunction) mmap_write_method, METH_VARARGS},
|
{"write", (PyCFunction) mmap_write_method, METH_VARARGS},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue