Skip to content

Commit 5daf7c4

Browse files
authored
Merge branch 'main' into gh-145678-grouper-uaf
2 parents 1863876 + cd52172 commit 5daf7c4

14 files changed

+180
-41
lines changed

Doc/c-api/dict.rst

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ Dictionary objects
4242
enforces read-only behavior. This is normally used to create a view to
4343
prevent modification of the dictionary for non-dynamic class types.
4444
45+
The first argument can be a :class:`dict`, a :class:`frozendict`, or a
46+
mapping.
47+
48+
.. versionchanged:: next
49+
Also accept :class:`frozendict`.
50+
4551
4652
.. c:var:: PyTypeObject PyDictProxy_Type
4753
@@ -68,15 +74,25 @@ Dictionary objects
6874
*key*, return ``1``, otherwise return ``0``. On error, return ``-1``.
6975
This is equivalent to the Python expression ``key in p``.
7076
77+
The first argument can be a :class:`dict` or a :class:`frozendict`.
78+
79+
.. versionchanged:: next
80+
Also accept :class:`frozendict`.
81+
7182
7283
.. c:function:: int PyDict_ContainsString(PyObject *p, const char *key)
7384
7485
This is the same as :c:func:`PyDict_Contains`, but *key* is specified as a
7586
:c:expr:`const char*` UTF-8 encoded bytes string, rather than a
7687
:c:expr:`PyObject*`.
7788
89+
The first argument can be a :class:`dict` or a :class:`frozendict`.
90+
7891
.. versionadded:: 3.13
7992
93+
.. versionchanged:: next
94+
Also accept :class:`frozendict`.
95+
8096
8197
.. c:function:: PyObject* PyDict_Copy(PyObject *p)
8298
@@ -122,8 +138,13 @@ Dictionary objects
122138
* If the key is missing, set *\*result* to ``NULL`` and return ``0``.
123139
* On error, raise an exception and return ``-1``.
124140
141+
The first argument can be a :class:`dict` or a :class:`frozendict`.
142+
125143
.. versionadded:: 3.13
126144
145+
.. versionchanged:: next
146+
Also accept :class:`frozendict`.
147+
127148
See also the :c:func:`PyObject_GetItem` function.
128149
129150
@@ -133,6 +154,8 @@ Dictionary objects
133154
has a key *key*. Return ``NULL`` if the key *key* is missing *without*
134155
setting an exception.
135156
157+
The first argument can be a :class:`dict` or a :class:`frozendict`.
158+
136159
.. note::
137160
138161
Exceptions that occur while this calls :meth:`~object.__hash__` and
@@ -143,6 +166,9 @@ Dictionary objects
143166
Calling this API without an :term:`attached thread state` had been allowed for historical
144167
reason. It is no longer allowed.
145168
169+
.. versionchanged:: next
170+
Also accept :class:`frozendict`.
171+
146172
147173
.. c:function:: PyObject* PyDict_GetItemWithError(PyObject *p, PyObject *key)
148174
@@ -151,6 +177,9 @@ Dictionary objects
151177
occurred. Return ``NULL`` **without** an exception set if the key
152178
wasn't present.
153179
180+
.. versionchanged:: next
181+
Also accept :class:`frozendict`.
182+
154183
155184
.. c:function:: PyObject* PyDict_GetItemString(PyObject *p, const char *key)
156185
@@ -166,6 +195,9 @@ Dictionary objects
166195
Prefer using the :c:func:`PyDict_GetItemWithError` function with your own
167196
:c:func:`PyUnicode_FromString` *key* instead.
168197
198+
.. versionchanged:: next
199+
Also accept :class:`frozendict`.
200+
169201
170202
.. c:function:: int PyDict_GetItemStringRef(PyObject *p, const char *key, PyObject **result)
171203
@@ -175,6 +207,9 @@ Dictionary objects
175207
176208
.. versionadded:: 3.13
177209
210+
.. versionchanged:: next
211+
Also accept :class:`frozendict`.
212+
178213
179214
.. c:function:: PyObject* PyDict_SetDefault(PyObject *p, PyObject *key, PyObject *defaultobj)
180215
@@ -238,17 +273,32 @@ Dictionary objects
238273
239274
Return a :c:type:`PyListObject` containing all the items from the dictionary.
240275
276+
The first argument can be a :class:`dict` or a :class:`frozendict`.
277+
278+
.. versionchanged:: next
279+
Also accept :class:`frozendict`.
280+
241281
242282
.. c:function:: PyObject* PyDict_Keys(PyObject *p)
243283
244284
Return a :c:type:`PyListObject` containing all the keys from the dictionary.
245285
286+
The first argument can be a :class:`dict` or a :class:`frozendict`.
287+
288+
.. versionchanged:: next
289+
Also accept :class:`frozendict`.
290+
246291
247292
.. c:function:: PyObject* PyDict_Values(PyObject *p)
248293
249294
Return a :c:type:`PyListObject` containing all the values from the dictionary
250295
*p*.
251296
297+
The first argument can be a :class:`dict` or a :class:`frozendict`.
298+
299+
.. versionchanged:: next
300+
Also accept :class:`frozendict`.
301+
252302
253303
.. c:function:: Py_ssize_t PyDict_Size(PyObject *p)
254304
@@ -257,11 +307,19 @@ Dictionary objects
257307
Return the number of items in the dictionary. This is equivalent to
258308
``len(p)`` on a dictionary.
259309
310+
The argument can be a :class:`dict` or a :class:`frozendict`.
311+
312+
.. versionchanged:: next
313+
Also accept :class:`frozendict`.
314+
260315
261316
.. c:function:: Py_ssize_t PyDict_GET_SIZE(PyObject *p)
262317
263318
Similar to :c:func:`PyDict_Size`, but without error checking.
264319
320+
.. versionchanged:: next
321+
Also accept :class:`frozendict`.
322+
265323
266324
.. c:function:: int PyDict_Next(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue)
267325
@@ -276,6 +334,8 @@ Dictionary objects
276334
value represents offsets within the internal dictionary structure, and
277335
since the structure is sparse, the offsets are not consecutive.
278336
337+
The first argument can be a :class:`dict` or a :class:`frozendict`.
338+
279339
For example::
280340
281341
PyObject *key, *value;
@@ -309,7 +369,7 @@ Dictionary objects
309369
}
310370
311371
The function is not thread-safe in the :term:`free-threaded <free threading>`
312-
build without external synchronization. You can use
372+
build without external synchronization for a mutable :class:`dict`. You can use
313373
:c:macro:`Py_BEGIN_CRITICAL_SECTION` to lock the dictionary while iterating
314374
over it::
315375
@@ -319,6 +379,8 @@ Dictionary objects
319379
}
320380
Py_END_CRITICAL_SECTION();
321381
382+
The function is thread-safe on a :class:`frozendict`.
383+
322384
.. note::
323385
324386
On the free-threaded build, this function can be used safely inside a
@@ -329,6 +391,9 @@ Dictionary objects
329391
:term:`strong reference <strong reference>` (for example, using
330392
:c:func:`Py_NewRef`).
331393
394+
.. versionchanged:: next
395+
Also accept :class:`frozendict`.
396+
332397
.. c:function:: int PyDict_Merge(PyObject *a, PyObject *b, int override)
333398
334399
Iterate over mapping object *b* adding key-value pairs to dictionary *a*.

Doc/whatsnew/3.15.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,14 @@ mimetypes
828828
* Add ``application/sql`` and ``application/vnd.sqlite3``.
829829
(Contributed by Charlie Lin in :gh:`145698`.)
830830
* Add ``image/jxl``. (Contributed by Foolbar in :gh:`144213`.)
831+
* Add the following MIME types:
832+
833+
- ``application/vnd.ms-cab-compressed`` for ``.cab`` extension
834+
- ``application/vnd.ms-htmlhelp`` for ``.chm`` extension
835+
- ``application/vnd.ms-officetheme`` for ``.thmx`` extension
836+
837+
(Contributed by Charlie Lin in :gh:`145718`.)
838+
831839
* Rename ``application/x-texinfo`` to ``application/texinfo``.
832840
(Contributed by Charlie Lin in :gh:`140165`.)
833841
* Changed the MIME type for ``.ai`` files to ``application/pdf``.

Include/internal/pycore_pyatomic_ft_wrappers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ extern "C" {
9595
_Py_atomic_store_int_relaxed(&value, new_value)
9696
#define FT_ATOMIC_LOAD_INT_RELAXED(value) \
9797
_Py_atomic_load_int_relaxed(&value)
98+
#define FT_ATOMIC_LOAD_UINT(value) \
99+
_Py_atomic_load_uint(&value)
98100
#define FT_ATOMIC_STORE_UINT_RELAXED(value, new_value) \
99101
_Py_atomic_store_uint_relaxed(&value, new_value)
100102
#define FT_ATOMIC_LOAD_UINT_RELAXED(value) \
@@ -167,6 +169,7 @@ extern "C" {
167169
#define FT_ATOMIC_STORE_INT(value, new_value) value = new_value
168170
#define FT_ATOMIC_LOAD_INT_RELAXED(value) value
169171
#define FT_ATOMIC_STORE_INT_RELAXED(value, new_value) value = new_value
172+
#define FT_ATOMIC_LOAD_UINT(value) value
170173
#define FT_ATOMIC_LOAD_UINT_RELAXED(value) value
171174
#define FT_ATOMIC_STORE_UINT_RELAXED(value, new_value) value = new_value
172175
#define FT_ATOMIC_LOAD_LONG_RELAXED(value) value

Lib/_pyrepl/windows_console.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -270,18 +270,13 @@ def __write_changed_line(
270270
self._erase_to_end()
271271

272272
self.__write(newline[x_pos:])
273-
if wlen(newline) == self.width:
274-
# If we wrapped we want to start at the next line
275-
self._move_relative(0, y + 1)
276-
self.posxy = 0, y + 1
277-
else:
278-
self.posxy = wlen(newline), y
273+
self.posxy = min(wlen(newline), self.width - 1), y
279274

280-
if "\x1b" in newline or y != self.posxy[1] or '\x1a' in newline:
281-
# ANSI escape characters are present, so we can't assume
282-
# anything about the position of the cursor. Moving the cursor
283-
# to the left margin should work to get to a known position.
284-
self.move_cursor(0, y)
275+
if "\x1b" in newline or y != self.posxy[1] or '\x1a' in newline:
276+
# ANSI escape characters are present, so we can't assume
277+
# anything about the position of the cursor. Moving the cursor
278+
# to the left margin should work to get to a known position.
279+
self.move_cursor(0, y)
285280

286281
def _scroll(
287282
self, top: int, bottom: int, left: int | None = None, right: int | None = None

Lib/mimetypes.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,9 +510,12 @@ def _default_mime_types():
510510
'.m3u8' : 'application/vnd.apple.mpegurl',
511511
'.dll' : 'application/vnd.microsoft.portable-executable',
512512
'.exe' : 'application/vnd.microsoft.portable-executable',
513+
'.cab' : 'application/vnd.ms-cab-compressed',
513514
'.xls' : 'application/vnd.ms-excel',
514515
'.xlb' : 'application/vnd.ms-excel',
515516
'.eot' : 'application/vnd.ms-fontobject',
517+
'.chm' : 'application/vnd.ms-htmlhelp',
518+
'.thmx' : 'application/vnd.ms-officetheme',
516519
'.ppt' : 'application/vnd.ms-powerpoint',
517520
'.pot' : 'application/vnd.ms-powerpoint',
518521
'.ppa' : 'application/vnd.ms-powerpoint',

Lib/test/test_pyrepl/test_pyrepl.py

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import tempfile
1313
from pkgutil import ModuleInfo
1414
from unittest import TestCase, skipUnless, skipIf, SkipTest
15-
from unittest.mock import patch
15+
from unittest.mock import Mock, patch
1616
from test.support import force_not_colorized, make_clean_env, Py_DEBUG
1717
from test.support import has_subprocess_support, SHORT_TIMEOUT, STDLIB_DIR
1818
from test.support.import_helper import import_module
@@ -2105,3 +2105,47 @@ def test_ctrl_d_single_line_end_no_newline(self):
21052105
)
21062106
reader, _ = handle_all_events(events)
21072107
self.assertEqual("hello", "".join(reader.buffer))
2108+
2109+
2110+
@skipUnless(sys.platform == "win32", "windows console only")
2111+
class TestWindowsConsoleEolWrap(TestCase):
2112+
def _make_mock_console(self, width=80):
2113+
from _pyrepl import windows_console as wc
2114+
2115+
console = object.__new__(wc.WindowsConsole)
2116+
2117+
console.width = width
2118+
console.posxy = (0, 0)
2119+
console.screen = [""]
2120+
2121+
console._hide_cursor = Mock()
2122+
console._show_cursor = Mock()
2123+
console._erase_to_end = Mock()
2124+
console._move_relative = Mock()
2125+
console.move_cursor = Mock()
2126+
console._WindowsConsole__write = Mock()
2127+
2128+
return console, wc
2129+
2130+
def test_short_line_sets_posxy_normally(self):
2131+
width = 10
2132+
y = 3
2133+
console, wc = self._make_mock_console(width=width)
2134+
old_line = ""
2135+
new_line = "a" * 3
2136+
wc.WindowsConsole._WindowsConsole__write_changed_line(
2137+
console, y, old_line, new_line, 0
2138+
)
2139+
self.assertEqual(console.posxy, (3, y))
2140+
2141+
def test_exact_width_line_does_not_wrap(self):
2142+
width = 10
2143+
y = 3
2144+
console, wc = self._make_mock_console(width=width)
2145+
old_line = ""
2146+
new_line = "a" * width
2147+
2148+
wc.WindowsConsole._WindowsConsole__write_changed_line(
2149+
console, y, old_line, new_line, 0
2150+
)
2151+
self.assertEqual(console.posxy, (width - 1, y))
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Improve scaling of type attribute lookups in the :term:`free-threaded build` by
2+
avoiding contention on the internal type lock.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix inconsistent display of long multiline pasted content in the REPL.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Now :mod:`functools` is safer in free-threaded build when using keywords in :func:`functools.partial`
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add a few Microsoft-specific MIME types.

0 commit comments

Comments
 (0)