Skip to content

Commit 9c0b1dc

Browse files
Merge branch 'main' of https://github.com/python/cpython into bytearray
2 parents 6b73c34 + 6a94980 commit 9c0b1dc

File tree

18 files changed

+240
-61
lines changed

18 files changed

+240
-61
lines changed

Doc/c-api/bytes.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ called with a non-bytes parameter.
127127
Return the bytes representation of object *o* that implements the buffer
128128
protocol.
129129
130+
.. note::
131+
If the object implements the buffer protocol, then the buffer
132+
must not be mutated while the bytes object is being created.
133+
130134
131135
.. c:function:: Py_ssize_t PyBytes_Size(PyObject *o)
132136
@@ -185,13 +189,20 @@ called with a non-bytes parameter.
185189
created, the old reference to *bytes* will still be discarded and the value
186190
of *\*bytes* will be set to ``NULL``; the appropriate exception will be set.
187191
192+
.. note::
193+
If *newpart* implements the buffer protocol, then the buffer
194+
must not be mutated while the new bytes object is being created.
188195
189196
.. c:function:: void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart)
190197
191198
Create a new bytes object in *\*bytes* containing the contents of *newpart*
192199
appended to *bytes*. This version releases the :term:`strong reference`
193200
to *newpart* (i.e. decrements its reference count).
194201
202+
.. note::
203+
If *newpart* implements the buffer protocol, then the buffer
204+
must not be mutated while the new bytes object is being created.
205+
195206
196207
.. c:function:: PyObject* PyBytes_Join(PyObject *sep, PyObject *iterable)
197208
@@ -210,6 +221,9 @@ called with a non-bytes parameter.
210221
211222
.. versionadded:: 3.14
212223
224+
.. note::
225+
If *iterable* objects implement the buffer protocol, then the buffers
226+
must not be mutated while the new bytes object is being created.
213227
214228
.. c:function:: int _PyBytes_Resize(PyObject **bytes, Py_ssize_t newsize)
215229

Doc/data/threadsafety.dat

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,47 @@ PyList_Reverse:shared:
6666
# is a list
6767
PyList_SetSlice:shared:
6868

69-
# Sort - per-object lock held; comparison callbacks may execute
70-
# arbitrary Python code
69+
# Sort - per-object lock held; the list is emptied before sorting
70+
# so other threads may observe an empty list, but they won't see the
71+
# intermediate states of the sort
7172
PyList_Sort:shared:
7273

7374
# Extend - lock target list; also lock source when it is a
7475
# list, set, or dict
7576
PyList_Extend:shared:
7677

78+
# Creation - pure allocation, no shared state
79+
PyBytes_FromString:atomic:
80+
PyBytes_FromStringAndSize:atomic:
81+
PyBytes_DecodeEscape:atomic:
82+
83+
# Creation from formatting C primitives - pure allocation, no shared state
84+
PyBytes_FromFormat:atomic:
85+
PyBytes_FromFormatV:atomic:
86+
87+
# Creation from object - uses buffer protocol so may call arbitrary code;
88+
# safe as long as the buffer is not mutated by another thread during the operation
89+
PyBytes_FromObject:shared:
90+
91+
# Size - uses atomic load on free-threaded builds
92+
PyBytes_Size:atomic:
93+
PyBytes_GET_SIZE:atomic:
94+
95+
# Raw data - no locking; mutating it is unsafe if the bytes object is shared between threads
96+
PyBytes_AsString:compatible:
97+
PyBytes_AS_STRING:compatible:
98+
PyBytes_AsStringAndSize:compatible:
99+
100+
# Concatenation - uses buffer protocol; safe as long as buffer is not mutated by another thread during the operation
101+
PyBytes_Concat:shared:
102+
PyBytes_ConcatAndDel:shared:
103+
PyBytes_Join:shared:
104+
105+
# Resizing - safe if the object is unique
106+
_PyBytes_Resize:distinct:
107+
108+
# Repr - atomic as bytes are immutable
109+
PyBytes_Repr:atomic:
77110

78111
# Creation from object - may call arbitrary code
79112
PyByteArray_FromObject:shared:
@@ -90,4 +123,4 @@ PyByteArray_GET_SIZE:atomic:
90123

91124
# Raw data - no locking; mutating it is unsafe if the bytearray object is shared between threads
92125
PyByteArray_AsString:compatible:
93-
PyByteArray_AS_STRING:compatible:
126+
PyByteArray_AS_STRING:compatible:

Doc/library/json.rst

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ Basic Usage
264264

265265
.. function:: load(fp, *, cls=None, object_hook=None, parse_float=None, \
266266
parse_int=None, parse_constant=None, \
267-
object_pairs_hook=None, **kw)
267+
object_pairs_hook=None, array_hook=None, **kw)
268268
269269
Deserialize *fp* to a Python object
270270
using the :ref:`JSON-to-Python conversion table <json-to-py-table>`.
@@ -301,6 +301,15 @@ Basic Usage
301301
Default ``None``.
302302
:type object_pairs_hook: :term:`callable` | None
303303

304+
:param array_hook:
305+
If set, a function that is called with the result of
306+
any JSON array literal decoded with as a Python list.
307+
The return value of this function will be used
308+
instead of the :class:`list`.
309+
This feature can be used to implement custom decoders.
310+
Default ``None``.
311+
:type array_hook: :term:`callable` | None
312+
304313
:param parse_float:
305314
If set, a function that is called with
306315
the string of every JSON float to be decoded.
@@ -349,7 +358,10 @@ Basic Usage
349358
conversion length limitation <int_max_str_digits>` to help avoid denial
350359
of service attacks.
351360

352-
.. function:: loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, **kw)
361+
.. versionchanged:: next
362+
Added the optional *array_hook* parameter.
363+
364+
.. function:: loads(s, *, cls=None, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, object_pairs_hook=None, array_hook=None, **kw)
353365

354366
Identical to :func:`load`, but instead of a file-like object,
355367
deserialize *s* (a :class:`str`, :class:`bytes` or :class:`bytearray`
@@ -367,7 +379,7 @@ Basic Usage
367379
Encoders and Decoders
368380
---------------------
369381

370-
.. class:: JSONDecoder(*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None)
382+
.. class:: JSONDecoder(*, object_hook=None, parse_float=None, parse_int=None, parse_constant=None, strict=True, object_pairs_hook=None, array_hook=None)
371383

372384
Simple JSON decoder.
373385

@@ -412,6 +424,14 @@ Encoders and Decoders
412424
.. versionchanged:: 3.1
413425
Added support for *object_pairs_hook*.
414426

427+
*array_hook* is an optional function that will be called with the
428+
result of every JSON array decoded as a list. The return value of
429+
*array_hook* will be used instead of the :class:`list`. This feature can be
430+
used to implement custom decoders.
431+
432+
.. versionchanged:: next
433+
Added support for *array_hook*.
434+
415435
*parse_float* is an optional function that will be called with the string of
416436
every JSON float to be decoded. By default, this is equivalent to
417437
``float(num_str)``. This can be used to use another datatype or parser for

Doc/library/math.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -848,8 +848,7 @@ Constants
848848

849849
The :mod:`!math` module consists mostly of thin wrappers around the platform C
850850
math library functions. Behavior in exceptional cases follows Annex F of
851-
the C99 standard, if :attr:`sys.float_info.iec_60559` is true.
852-
The current implementation will raise
851+
the C99 standard where appropriate. The current implementation will raise
853852
:exc:`ValueError` for invalid operations like ``sqrt(-1.0)`` or ``log(0.0)``
854853
(where C99 Annex F recommends signaling invalid operation or divide-by-zero),
855854
and :exc:`OverflowError` for results that overflow (for example,

Doc/library/sys.rst

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -694,16 +694,15 @@ always available. Unless explicitly noted otherwise, all variables are read-only
694694
A :term:`named tuple` holding information about the float type. It
695695
contains low level information about the precision and internal
696696
representation. The values correspond to the various floating-point
697-
constants defined by C implementation and in the standard header file
698-
:file:`float.h` for the 'C' programming language; see Annex F and section
699-
5.2.4.2.2 of the 1999 ISO/IEC C standard [C99]_, 'Characteristics of
700-
floating types', for details.
697+
constants defined in the standard header file :file:`float.h` for the 'C'
698+
programming language; see section 5.2.4.2.2 of the 1999 ISO/IEC C standard
699+
[C99]_, 'Characteristics of floating types', for details.
701700

702701
.. list-table:: Attributes of the :data:`!float_info` :term:`named tuple`
703702
:header-rows: 1
704703

705704
* - attribute
706-
- C macro
705+
- float.h macro
707706
- explanation
708707

709708
* - .. attribute:: float_info.epsilon
@@ -772,12 +771,6 @@ always available. Unless explicitly noted otherwise, all variables are read-only
772771
All other values for :c:macro:`!FLT_ROUNDS` characterize
773772
implementation-defined rounding behavior.
774773

775-
* - .. attribute:: float_info.iec_60559
776-
- :c:macro:`!__STDC_IEC_559__`
777-
- A boolean, indicating support the IEC 60559 floating-point standard.
778-
If true, the :class:`float` type characteristics and behavior matches
779-
the IEC 60559 double format.
780-
781774
The attribute :attr:`sys.float_info.dig` needs further explanation. If
782775
``s`` is any string representing a decimal number with at most
783776
:attr:`!sys.float_info.dig` significant digits, then converting ``s`` to a

Doc/whatsnew/3.15.rst

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ Summary -- Release highlights
8484
<whatsnew315-pybyteswriter>`
8585
* :ref:`The JIT compiler has been significantly upgraded <whatsnew315-jit>`
8686
* :ref:`Improved error messages <whatsnew315-improved-error-messages>`
87-
87+
* :ref:`The official Windows 64-bit binaries now use the tail-calling interpreter
88+
<whatsnew315-windows-tail-calling-interpreter>`
8889

8990
New features
9091
============
@@ -801,6 +802,17 @@ inspect
801802
for :func:`~inspect.getdoc`.
802803
(Contributed by Serhiy Storchaka in :gh:`132686`.)
803804

805+
json
806+
----
807+
808+
* Add the *array_hook* parameter to :func:`~json.load` and
809+
:func:`~json.loads` functions:
810+
allow a callback for JSON literal array types to customize Python lists in
811+
the resulting decoded object. Passing combined :class:`frozendict` to
812+
*object_pairs_hook* param and :class:`tuple` to ``array_hook`` will yield a
813+
deeply nested immutable Python structure representing the JSON data.
814+
(Contributed by Joao S. O. Bueno in :gh:`146440`)
815+
804816

805817
locale
806818
------
@@ -1028,11 +1040,6 @@ sys
10281040
* Add :data:`sys.abi_info` namespace to improve access to ABI information.
10291041
(Contributed by Klaus Zimmermann in :gh:`137476`.)
10301042

1031-
* Add :data:`sys.float_info.iec_60559 <sys.float_info>`: a boolean flag,
1032-
indicating support the IEC 60559 floating-point standard (as specified by the
1033-
Annex F of C99).
1034-
(Contributed by Sergey B Kirpichev in :gh:`138580`.)
1035-
10361043

10371044
tarfile
10381045
-------
@@ -1288,18 +1295,6 @@ zlib
12881295
Optimizations
12891296
=============
12901297

1291-
* Builds using Visual Studio 2026 (MSVC 18) may now use the new
1292-
:ref:`tail-calling interpreter <whatsnew314-tail-call-interpreter>`.
1293-
Results on Visual Studio 18.1.1 report between
1294-
`15-20% <https://github.com/faster-cpython/ideas/blob/main/results/5800X-msvc.pgo2-vs-msvc.pgo.tc.svg>`__
1295-
speedup on the geometric mean of pyperformance on Windows x86-64 over
1296-
the switch-case interpreter on an AMD Ryzen 7 5800X. We have
1297-
observed speedups ranging from 14% for large pure-Python libraries
1298-
to 40% for long-running small pure-Python scripts on Windows.
1299-
This was made possible by a new feature introduced in MSVC 18.
1300-
(Contributed by Chris Eibl, Ken Jin, and Brandt Bucher in :gh:`143068`.
1301-
Special thanks to the MSVC team including Hulon Jenkins.)
1302-
13031298
* ``mimalloc`` is now used as the default allocator for
13041299
for raw memory allocations such as via :c:func:`PyMem_RawMalloc`
13051300
for better performance on :term:`free-threaded builds <free-threaded build>`.
@@ -1956,6 +1951,23 @@ Build changes
19561951
and :option:`-X dev <-X>` is passed to the Python or Python is built in :ref:`debug mode <debug-build>`.
19571952
(Contributed by Donghee Na in :gh:`141770`.)
19581953

1954+
.. _whatsnew315-windows-tail-calling-interpreter:
1955+
1956+
* 64-bit builds using Visual Studio 2026 (MSVC 18) may now use the new
1957+
:ref:`tail-calling interpreter <whatsnew314-tail-call-interpreter>`.
1958+
Results on Visual Studio 18.1.1 report between
1959+
`15-20% <https://github.com/faster-cpython/ideas/blob/main/results/5800X-msvc.pgo2-vs-msvc.pgo.tc.svg>`__
1960+
speedup on the geometric mean of pyperformance on Windows x86-64 over
1961+
the switch-case interpreter on an AMD Ryzen 7 5800X. We have
1962+
observed speedups ranging from 14% for large pure-Python libraries
1963+
to 40% for long-running small pure-Python scripts on Windows.
1964+
This was made possible by a new feature introduced in MSVC 18,
1965+
which the official Windows 64-bit binaries on python.org__ now use.
1966+
(Contributed by Chris Eibl, Ken Jin, and Brandt Bucher in :gh:`143068`.
1967+
Special thanks to Steve Dower, and the MSVC team including Hulon Jenkins.)
1968+
1969+
__ https://www.python.org/downloads/windows/
1970+
19591971

19601972
Porting to Python 3.15
19611973
======================

Lib/json/__init__.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
241241
**kw).encode(obj)
242242

243243

244-
_default_decoder = JSONDecoder(object_hook=None, object_pairs_hook=None)
244+
_default_decoder = JSONDecoder()
245245

246246

247247
def detect_encoding(b):
@@ -275,7 +275,8 @@ def detect_encoding(b):
275275

276276

277277
def load(fp, *, cls=None, object_hook=None, parse_float=None,
278-
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
278+
parse_int=None, parse_constant=None, object_pairs_hook=None,
279+
array_hook=None, **kw):
279280
"""Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
280281
a JSON document) to a Python object.
281282
@@ -291,17 +292,26 @@ def load(fp, *, cls=None, object_hook=None, parse_float=None,
291292
``object_hook`` is also defined, the ``object_pairs_hook`` takes
292293
priority.
293294
295+
``array_hook`` is an optional function that will be called with the result
296+
of any literal array decode (a ``list``). The return value of this function will
297+
be used instead of the ``list``. This feature can be used along
298+
``object_pairs_hook`` to customize the resulting data structure - for example,
299+
by setting that to ``frozendict`` and ``array_hook`` to ``tuple``, one can get
300+
a deep immutable data structute from any JSON data.
301+
294302
To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
295303
kwarg; otherwise ``JSONDecoder`` is used.
296304
"""
297305
return loads(fp.read(),
298306
cls=cls, object_hook=object_hook,
299307
parse_float=parse_float, parse_int=parse_int,
300-
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw)
308+
parse_constant=parse_constant, object_pairs_hook=object_pairs_hook,
309+
array_hook=None, **kw)
301310

302311

303312
def loads(s, *, cls=None, object_hook=None, parse_float=None,
304-
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
313+
parse_int=None, parse_constant=None, object_pairs_hook=None,
314+
array_hook=None, **kw):
305315
"""Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray`` instance
306316
containing a JSON document) to a Python object.
307317
@@ -317,6 +327,13 @@ def loads(s, *, cls=None, object_hook=None, parse_float=None,
317327
``object_hook`` is also defined, the ``object_pairs_hook`` takes
318328
priority.
319329
330+
``array_hook`` is an optional function that will be called with the result
331+
of any literal array decode (a ``list``). The return value of this function will
332+
be used instead of the ``list``. This feature can be used along
333+
``object_pairs_hook`` to customize the resulting data structure - for example,
334+
by setting that to ``frozendict`` and ``array_hook`` to ``tuple``, one can get
335+
a deep immutable data structute from any JSON data.
336+
320337
``parse_float``, if specified, will be called with the string
321338
of every JSON float to be decoded. By default this is equivalent to
322339
float(num_str). This can be used to use another datatype or parser
@@ -347,14 +364,17 @@ def loads(s, *, cls=None, object_hook=None, parse_float=None,
347364

348365
if (cls is None and object_hook is None and
349366
parse_int is None and parse_float is None and
350-
parse_constant is None and object_pairs_hook is None and not kw):
367+
parse_constant is None and object_pairs_hook is None
368+
and array_hook is None and not kw):
351369
return _default_decoder.decode(s)
352370
if cls is None:
353371
cls = JSONDecoder
354372
if object_hook is not None:
355373
kw['object_hook'] = object_hook
356374
if object_pairs_hook is not None:
357375
kw['object_pairs_hook'] = object_pairs_hook
376+
if array_hook is not None:
377+
kw['array_hook'] = array_hook
358378
if parse_float is not None:
359379
kw['parse_float'] = parse_float
360380
if parse_int is not None:

0 commit comments

Comments
 (0)