Unverified Kaydet (Commit) e7d4b2f2 authored tarafından Berker Peksag's avatar Berker Peksag Kaydeden (comit) GitHub

bpo-2122: Make mmap.flush() behave same on all platforms (GH-8692)

Previously, its behavior was platform-dependent and there was no error checking
under Windows.
üst 28853a24
...@@ -191,11 +191,13 @@ To map anonymous memory, -1 should be passed as the fileno along with the length ...@@ -191,11 +191,13 @@ To map anonymous memory, -1 should be passed as the fileno along with the length
changes to the given range of bytes will be flushed to disk; otherwise, the changes to the given range of bytes will be flushed to disk; otherwise, the
whole extent of the mapping is flushed. whole extent of the mapping is flushed.
**(Windows version)** A nonzero value returned indicates success; zero ``None`` is returned to indicate success. An exception is raised when the
indicates failure. call failed.
**(Unix version)** A zero value is returned to indicate success. An .. versionchanged:: 3.8
exception is raised when the call failed. Previously, a nonzero value was returned on success; zero was returned
on error under Windows. A zero value was returned on success; an
exception was raised on error under Unix.
.. method:: move(dest, src, count) .. method:: move(dest, src, count)
......
...@@ -265,6 +265,13 @@ Changes in the Python API ...@@ -265,6 +265,13 @@ Changes in the Python API
task name is visible in the ``repr()`` output of :class:`asyncio.Task` and task name is visible in the ``repr()`` output of :class:`asyncio.Task` and
can also be retrieved using the :meth:`~asyncio.Task.get_name` method. can also be retrieved using the :meth:`~asyncio.Task.get_name` method.
* The :meth:`mmap.flush() <mmap.mmap.flush>` method now returns ``None`` on
success and raises an exception on error under all platforms. Previously,
its behavior was platform-depended: a nonzero value was returned on success;
zero was returned on error under Windows. A zero value was returned on
success; an exception was raised on error under Unix.
(Contributed by Berker Peksag in :issue:`2122`.)
CPython bytecode changes CPython bytecode changes
------------------------ ------------------------
......
from test.support import (TESTFN, run_unittest, import_module, unlink, from test.support import (TESTFN, import_module, unlink,
requires, _2G, _4G, gc_collect, cpython_only) requires, _2G, _4G, gc_collect, cpython_only)
import unittest import unittest
import os import os
...@@ -741,6 +741,18 @@ class MmapTests(unittest.TestCase): ...@@ -741,6 +741,18 @@ class MmapTests(unittest.TestCase):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
m * 2 m * 2
def test_flush_return_value(self):
# mm.flush() should return None on success, raise an
# exception on error under all platforms.
mm = mmap.mmap(-1, 16)
self.addCleanup(mm.close)
mm.write(b'python')
result = mm.flush()
self.assertIsNone(result)
if os.name != 'nt':
# 'offset' must be a multiple of mmap.PAGESIZE.
self.assertRaises(OSError, mm.flush, 1, len(b'python'))
class LargeMmapTests(unittest.TestCase): class LargeMmapTests(unittest.TestCase):
...@@ -803,8 +815,5 @@ class LargeMmapTests(unittest.TestCase): ...@@ -803,8 +815,5 @@ class LargeMmapTests(unittest.TestCase):
self._test_around_boundary(_4G) self._test_around_boundary(_4G)
def test_main():
run_unittest(MmapTests, LargeMmapTests)
if __name__ == '__main__': if __name__ == '__main__':
test_main() unittest.main()
The :meth:`mmap.flush() <mmap.mmap.flush>` method now returns ``None`` on
success, raises an exception on error under all platforms.
...@@ -569,18 +569,21 @@ mmap_flush_method(mmap_object *self, PyObject *args) ...@@ -569,18 +569,21 @@ mmap_flush_method(mmap_object *self, PyObject *args)
} }
if (self->access == ACCESS_READ || self->access == ACCESS_COPY) if (self->access == ACCESS_READ || self->access == ACCESS_COPY)
return PyLong_FromLong(0); Py_RETURN_NONE;
#ifdef MS_WINDOWS #ifdef MS_WINDOWS
return PyLong_FromLong((long) FlushViewOfFile(self->data+offset, size)); if (!FlushViewOfFile(self->data+offset, size)) {
PyErr_SetFromWindowsErr(GetLastError());
return NULL;
}
Py_RETURN_NONE;
#elif defined(UNIX) #elif defined(UNIX)
/* XXX semantics of return value? */
/* XXX flags for msync? */ /* XXX flags for msync? */
if (-1 == msync(self->data + offset, size, MS_SYNC)) { if (-1 == msync(self->data + offset, size, MS_SYNC)) {
PyErr_SetFromErrno(PyExc_OSError); PyErr_SetFromErrno(PyExc_OSError);
return NULL; return NULL;
} }
return PyLong_FromLong(0); Py_RETURN_NONE;
#else #else
PyErr_SetString(PyExc_ValueError, "flush not supported on this system"); PyErr_SetString(PyExc_ValueError, "flush not supported on this system");
return NULL; return NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment