Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 33 additions & 11 deletions Doc/c-api/memory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -293,17 +293,39 @@ The following type-oriented macros are provided for convenience. Note that

Same as :c:func:`PyMem_Free`.

In addition, the following macro sets are provided for calling the Python memory
allocator directly, without involving the C API functions listed above. However,
note that their use does not preserve binary compatibility across Python
versions and is therefore deprecated in extension modules.

* ``PyMem_MALLOC(size)``
* ``PyMem_NEW(type, size)``
* ``PyMem_REALLOC(ptr, size)``
* ``PyMem_RESIZE(ptr, type, size)``
* ``PyMem_FREE(ptr)``
* ``PyMem_DEL(ptr)``

Deprecated aliases
------------------

These are :term:`soft deprecated` aliases to existing functions and macros.
They exist solely for backwards compatibility.

.. list-table::
:widths: auto
:header-rows: 1

* * Deprecated alias
* Corresponding function or macro
* * .. c:macro:: PyMem_MALLOC(size)
* :c:func:`PyMem_Malloc`
* * .. c:macro:: PyMem_NEW(type, size)
* :c:macro:`PyMem_New`
* * .. c:macro:: PyMem_REALLOC(ptr, size)
* :c:func:`PyMem_Realloc`
* * .. c:macro:: PyMem_RESIZE(ptr, type, size)
* :c:macro:`PyMem_Resize`
* * .. c:macro:: PyMem_FREE(ptr)
* :c:func:`PyMem_Free`
* * .. c:macro:: PyMem_DEL(ptr)
* :c:func:`PyMem_Free`

.. versionchanged:: 3.4

The macros are now aliases of the corresponding functions and macros.
Previously, their behavior was the same, but their use did not necessarily
preserve binary compatibility across Python versions.

.. deprecated:: 2.0


.. _objectinterface:
Expand Down
2 changes: 2 additions & 0 deletions Doc/library/select.rst
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,8 @@ linearly scanned again. :c:func:`!select` is *O*\ (*highest file descriptor*), w

.. versionchanged:: 3.15
Accepts any real number as *timeout*, not only integer or float.
If ``ppoll()`` function is available, *timeout* has a resolution
of ``1`` ns (``1e-6`` ms) instead of ``1`` ms.


.. _kqueue-objects:
Expand Down
23 changes: 12 additions & 11 deletions Lib/_pyio.py
Original file line number Diff line number Diff line change
Expand Up @@ -952,20 +952,21 @@ def write(self, b):
if isinstance(b, str):
raise TypeError("can't write str to binary stream")
with memoryview(b) as view:
n = view.nbytes # Size of any bytes-like object
if self.closed:
raise ValueError("write to closed file")
if n == 0:
return 0

with self._lock:
pos = self._pos
if pos > len(self._buffer):
# Pad buffer to pos with null bytes.
self._buffer.resize(pos)
self._buffer[pos:pos + n] = b
self._pos += n
return n
n = view.nbytes # Size of any bytes-like object
if n == 0:
return 0

with self._lock:
pos = self._pos
if pos > len(self._buffer):
# Pad buffer to pos with null bytes.
self._buffer.resize(pos)
self._buffer[pos:pos + n] = view
self._pos += n
return n

def seek(self, pos, whence=0):
if self.closed:
Expand Down
22 changes: 22 additions & 0 deletions Lib/test/test_io/test_memoryio.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,6 +629,28 @@ def __buffer__(self, flags):
memio = self.ioclass()
self.assertRaises(BufferError, memio.writelines, [B()])

def test_write_mutating_buffer(self):
# Test that buffer is exported only once during write().
# See: https://github.com/python/cpython/issues/143602.
class B:
count = 0
def __buffer__(self, flags):
self.count += 1
if self.count == 1:
return memoryview(b"AAA")
else:
return memoryview(b"BBBBBBBBB")

memio = self.ioclass(b'0123456789')
memio.seek(2)
b = B()
n = memio.write(b)

self.assertEqual(b.count, 1)
self.assertEqual(n, 3)
self.assertEqual(memio.getvalue(), b"01AAA56789")
self.assertEqual(memio.tell(), 5)


class TextIOTestMixin:

Expand Down
12 changes: 10 additions & 2 deletions Lib/test/test_poll.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,17 +173,25 @@ def test_poll3(self):
@cpython_only
def test_poll_c_limits(self):
try:
import _testcapi
from _testcapi import USHRT_MAX, INT_MAX, UINT_MAX
HAVE_PPOLL = getattr(_testcapi, 'HAVE_PPOLL', False)
except ImportError:
raise unittest.SkipTest("requires _testcapi")

pollster = select.poll()
pollster.register(1)

# Issues #15989, #17919
self.assertRaises(OverflowError, pollster.register, 0, USHRT_MAX + 1)
self.assertRaises(OverflowError, pollster.modify, 1, USHRT_MAX + 1)
self.assertRaises(OverflowError, pollster.poll, INT_MAX + 1)
self.assertRaises(OverflowError, pollster.poll, UINT_MAX + 1)
if HAVE_PPOLL:
MS_TO_NS = 1_000_000
tmax = _testcapi.INT64_MAX // MS_TO_NS
self.assertRaises(OverflowError, pollster.poll, tmax + 1)
else:
self.assertRaises(OverflowError, pollster.poll, INT_MAX + 1)
self.assertRaises(OverflowError, pollster.poll, UINT_MAX + 1)

@threading_helper.reap_threads
def test_threaded_poll(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Use ``ppoll()`` if available in :func:`select.poll` to have a timeout
resolution of 1 nanosecond, instead of a resolution of 1 ms. Patch by Victor
Stinner.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix a inconsistency issue in :meth:`~io.RawIOBase.write` that leads to
unexpected buffer overwrite by deduplicating the buffer exports.
6 changes: 6 additions & 0 deletions Modules/_testcapimodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -3359,6 +3359,12 @@ _testcapi_exec(PyObject *m)
PyModule_AddObject(m, "INT64_MAX", PyLong_FromInt64(INT64_MAX));
PyModule_AddObject(m, "UINT64_MAX", PyLong_FromUInt64(UINT64_MAX));

#ifdef HAVE_PPOLL
if (PyModule_AddObjectRef(m, "HAVE_PPOLL", Py_True) < 0) {
return -1;
}
#endif

if (PyModule_AddIntMacro(m, _Py_STACK_GROWS_DOWN)) {
return -1;
}
Expand Down
50 changes: 25 additions & 25 deletions Modules/clinic/selectmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading