Skip to content

Commit 9d12a8a

Browse files
Merge branch 'main' into fix-issue-112632
2 parents 815e1da + c5f925c commit 9d12a8a

File tree

90 files changed

+2203
-1869
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+2203
-1869
lines changed

Doc/c-api/exceptions.rst

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -921,11 +921,7 @@ because the :ref:`call protocol <call>` takes care of recursion handling.
921921
922922
Marks a point where a recursive C-level call is about to be performed.
923923
924-
If :c:macro:`!USE_STACKCHECK` is defined, this function checks if the OS
925-
stack overflowed using :c:func:`PyOS_CheckStack`. If this is the case, it
926-
sets a :exc:`MemoryError` and returns a nonzero value.
927-
928-
The function then checks if the recursion limit is reached. If this is the
924+
The function then checks if the stack limit is reached. If this is the
929925
case, a :exc:`RecursionError` is set and a nonzero value is returned.
930926
Otherwise, zero is returned.
931927

Doc/glossary.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,7 @@ Glossary
719719
iterables include all sequence types (such as :class:`list`, :class:`str`,
720720
and :class:`tuple`) and some non-sequence types like :class:`dict`,
721721
:term:`file objects <file object>`, and objects of any classes you define
722-
with an :meth:`~iterator.__iter__` method or with a
722+
with an :meth:`~object.__iter__` method or with a
723723
:meth:`~object.__getitem__` method
724724
that implements :term:`sequence` semantics.
725725

Doc/library/abc.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -141,18 +141,18 @@ a helper class :class:`ABC` to alternatively define ABCs through inheritance:
141141
MyIterable.register(Foo)
142142

143143
The ABC ``MyIterable`` defines the standard iterable method,
144-
:meth:`~iterator.__iter__`, as an abstract method. The implementation given
144+
:meth:`~object.__iter__`, as an abstract method. The implementation given
145145
here can still be called from subclasses. The :meth:`!get_iterator` method
146146
is also part of the ``MyIterable`` abstract base class, but it does not have
147147
to be overridden in non-abstract derived classes.
148148

149149
The :meth:`__subclasshook__` class method defined here says that any class
150-
that has an :meth:`~iterator.__iter__` method in its
150+
that has an :meth:`~object.__iter__` method in its
151151
:attr:`~object.__dict__` (or in that of one of its base classes, accessed
152152
via the :attr:`~type.__mro__` list) is considered a ``MyIterable`` too.
153153

154154
Finally, the last line makes ``Foo`` a virtual subclass of ``MyIterable``,
155-
even though it does not define an :meth:`~iterator.__iter__` method (it uses
155+
even though it does not define an :meth:`~object.__iter__` method (it uses
156156
the old-style iterable protocol, defined in terms of :meth:`~object.__len__` and
157157
:meth:`~object.__getitem__`). Note that this will not make ``get_iterator``
158158
available as a method of ``Foo``, so it is provided separately.

Doc/library/stdtypes.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -949,9 +949,9 @@ Generator Types
949949
---------------
950950

951951
Python's :term:`generator`\s provide a convenient way to implement the iterator
952-
protocol. If a container object's :meth:`~iterator.__iter__` method is implemented as a
952+
protocol. If a container object's :meth:`~object.__iter__` method is implemented as a
953953
generator, it will automatically return an iterator object (technically, a
954-
generator object) supplying the :meth:`!__iter__` and :meth:`~generator.__next__`
954+
generator object) supplying the :meth:`~iterator.__iter__` and :meth:`~generator.__next__`
955955
methods.
956956
More information about generators can be found in :ref:`the documentation for
957957
the yield expression <yieldexpr>`.

Doc/library/string.rst

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -319,14 +319,19 @@ non-empty format specification typically modifies the result.
319319
The general form of a *standard format specifier* is:
320320

321321
.. productionlist:: format-spec
322-
format_spec: [[`fill`]`align`][`sign`]["z"]["#"]["0"][`width`][`grouping_option`]["." `precision`][`type`]
322+
format_spec: [`options`][`width_and_precision`][`type`]
323+
options: [[`fill`]`align`][`sign`]["z"]["#"]["0"]
323324
fill: <any character>
324325
align: "<" | ">" | "=" | "^"
325326
sign: "+" | "-" | " "
327+
width_and_precision: [`width_with_grouping`][`precision_with_grouping`]
328+
width_with_grouping: [`width`][`grouping_option`]
329+
precision_with_grouping: "." [`precision`]`grouping_option`
326330
width: `~python-grammar:digit`+
327331
grouping_option: "_" | ","
328332
precision: `~python-grammar:digit`+
329-
type: "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g" | "G" | "n" | "o" | "s" | "x" | "X" | "%"
333+
type: "b" | "c" | "d" | "e" | "E" | "f" | "F" | "g"
334+
: | "G" | "n" | "o" | "s" | "x" | "X" | "%"
330335

331336
If a valid *align* value is specified, it can be preceded by a *fill*
332337
character that can be any character and defaults to a space if omitted.
@@ -458,6 +463,13 @@ indicates the maximum field size - in other words, how many characters will be
458463
used from the field content. The *precision* is not allowed for integer
459464
presentation types.
460465

466+
The ``'_'`` or ``','`` option after *precision* means the use of an underscore
467+
or a comma for a thousands separator of the fractional part for floating-point
468+
presentation types.
469+
470+
.. versionchanged:: 3.14
471+
Support thousands separators for the fractional part.
472+
461473
Finally, the *type* determines how the data should be presented.
462474

463475
The available string presentation types are:
@@ -704,10 +716,18 @@ Replacing ``%x`` and ``%o`` and converting the value to different bases::
704716
>>> "int: {0:d}; hex: {0:#x}; oct: {0:#o}; bin: {0:#b}".format(42)
705717
'int: 42; hex: 0x2a; oct: 0o52; bin: 0b101010'
706718

707-
Using the comma as a thousands separator::
719+
Using the comma or the underscore as a thousands separator::
708720

709721
>>> '{:,}'.format(1234567890)
710722
'1,234,567,890'
723+
>>> '{:_}'.format(1234567890)
724+
'1_234_567_890'
725+
>>> '{:_}'.format(123456789.123456789)
726+
'123_456_789.12345679'
727+
>>> '{:._}'.format(123456789.123456789)
728+
'123456789.123_456_79'
729+
>>> '{:_._}'.format(123456789.123456789)
730+
'123_456_789.123_456_79'
711731

712732
Expressing a percentage::
713733

Doc/library/uuid.rst

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,6 @@ The :mod:`uuid` module defines the following functions:
184184
administered MAC addresses, since the former are guaranteed to be
185185
globally unique, while the latter are not.
186186

187-
.. index:: single: getnode
188-
189187

190188
.. function:: uuid1(node=None, clock_seq=None)
191189

@@ -194,33 +192,25 @@ The :mod:`uuid` module defines the following functions:
194192
*clock_seq* is given, it is used as the sequence number; otherwise a random
195193
14-bit sequence number is chosen.
196194

197-
.. index:: single: uuid1
198-
199195

200196
.. function:: uuid3(namespace, name)
201197

202198
Generate a UUID based on the MD5 hash of a namespace identifier (which is a
203199
UUID) and a name (which is a :class:`bytes` object or a string
204200
that will be encoded using UTF-8).
205201

206-
.. index:: single: uuid3
207-
208202

209203
.. function:: uuid4()
210204

211205
Generate a random UUID.
212206

213-
.. index:: single: uuid4
214-
215207

216208
.. function:: uuid5(namespace, name)
217209

218210
Generate a UUID based on the SHA-1 hash of a namespace identifier (which is a
219211
UUID) and a name (which is a :class:`bytes` object or a string
220212
that will be encoded using UTF-8).
221213

222-
.. index:: single: uuid5
223-
224214

225215
.. function:: uuid8(a=None, b=None, c=None)
226216

@@ -235,8 +225,6 @@ The :mod:`uuid` module defines the following functions:
235225

236226
.. versionadded:: 3.14
237227

238-
.. index:: single: uuid8
239-
240228

241229
The :mod:`uuid` module defines the following namespace identifiers for use with
242230
:func:`uuid3` or :func:`uuid5`.

Doc/whatsnew/3.14.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@ Other language changes
336336
making it a :term:`generic type`.
337337
(Contributed by Brian Schubert in :gh:`126012`.)
338338

339+
* Support underscore and comma as thousands separators in the fractional part
340+
for floating-point presentation types of the new-style string formatting
341+
(with :func:`format` or :ref:`f-strings`).
342+
(Contrubuted by Sergey B Kirpichev in :gh:`87790`.)
343+
339344
* ``\B`` in :mod:`regular expression <re>` now matches empty input string.
340345
Now it is always the opposite of ``\b``.
341346
(Contributed by Serhiy Storchaka in :gh:`124130`.)

Include/cpython/object.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -487,18 +487,19 @@ PyAPI_FUNC(void) _PyTrash_thread_destroy_chain(PyThreadState *tstate);
487487
* we have headroom above the trigger limit */
488488
#define Py_TRASHCAN_HEADROOM 50
489489

490+
/* Helper function for Py_TRASHCAN_BEGIN */
491+
PyAPI_FUNC(int) _Py_ReachedRecursionLimitWithMargin(PyThreadState *tstate, int margin_count);
492+
490493
#define Py_TRASHCAN_BEGIN(op, dealloc) \
491494
do { \
492495
PyThreadState *tstate = PyThreadState_Get(); \
493-
if (tstate->c_recursion_remaining <= Py_TRASHCAN_HEADROOM && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \
496+
if (_Py_ReachedRecursionLimitWithMargin(tstate, 1) && Py_TYPE(op)->tp_dealloc == (destructor)dealloc) { \
494497
_PyTrash_thread_deposit_object(tstate, (PyObject *)op); \
495498
break; \
496-
} \
497-
tstate->c_recursion_remaining--;
499+
}
498500
/* The body of the deallocator is here. */
499501
#define Py_TRASHCAN_END \
500-
tstate->c_recursion_remaining++; \
501-
if (tstate->delete_later && tstate->c_recursion_remaining > (Py_TRASHCAN_HEADROOM*2)) { \
502+
if (tstate->delete_later && !_Py_ReachedRecursionLimitWithMargin(tstate, 2)) { \
502503
_PyTrash_thread_destroy_chain(tstate); \
503504
} \
504505
} while (0);

Include/cpython/pystate.h

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ struct _ts {
112112
int py_recursion_remaining;
113113
int py_recursion_limit;
114114

115-
int c_recursion_remaining;
115+
int c_recursion_remaining; /* Retained for backwards compatibility. Do not use */
116116
int recursion_headroom; /* Allow 50 more calls to handle any errors. */
117117

118118
/* 'tracing' keeps track of the execution depth when tracing/profiling.
@@ -202,36 +202,7 @@ struct _ts {
202202
PyObject *threading_local_sentinel;
203203
};
204204

205-
#ifdef Py_DEBUG
206-
// A debug build is likely built with low optimization level which implies
207-
// higher stack memory usage than a release build: use a lower limit.
208-
# define Py_C_RECURSION_LIMIT 500
209-
#elif defined(__s390x__)
210-
# define Py_C_RECURSION_LIMIT 800
211-
#elif defined(_WIN32) && defined(_M_ARM64)
212-
# define Py_C_RECURSION_LIMIT 1000
213-
#elif defined(_WIN32)
214-
# define Py_C_RECURSION_LIMIT 3000
215-
#elif defined(__ANDROID__)
216-
// On an ARM64 emulator, API level 34 was OK with 10000, but API level 21
217-
// crashed in test_compiler_recursion_limit.
218-
# define Py_C_RECURSION_LIMIT 3000
219-
#elif defined(_Py_ADDRESS_SANITIZER)
220-
# define Py_C_RECURSION_LIMIT 4000
221-
#elif defined(__sparc__)
222-
// test_descr crashed on sparc64 with >7000 but let's keep a margin of error.
223-
# define Py_C_RECURSION_LIMIT 4000
224-
#elif defined(__wasi__)
225-
// Based on wasmtime 16.
226-
# define Py_C_RECURSION_LIMIT 5000
227-
#elif defined(__hppa__) || defined(__powerpc64__)
228-
// test_descr crashed with >8000 but let's keep a margin of error.
229-
# define Py_C_RECURSION_LIMIT 5000
230-
#else
231-
// This value is duplicated in Lib/test/support/__init__.py
232-
# define Py_C_RECURSION_LIMIT 10000
233-
#endif
234-
205+
# define Py_C_RECURSION_LIMIT 5000
235206

236207
/* other API */
237208

@@ -246,7 +217,6 @@ _PyThreadState_UncheckedGet(void)
246217
return PyThreadState_GetUnchecked();
247218
}
248219

249-
250220
// Disable tracing and profiling.
251221
PyAPI_FUNC(void) PyThreadState_EnterTracing(PyThreadState *tstate);
252222

Include/internal/pycore_ceval.h

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -193,18 +193,28 @@ extern void _PyEval_DeactivateOpCache(void);
193193

194194
/* --- _Py_EnterRecursiveCall() ----------------------------------------- */
195195

196-
#ifdef USE_STACKCHECK
197-
/* With USE_STACKCHECK macro defined, trigger stack checks in
198-
_Py_CheckRecursiveCall() on every 64th call to _Py_EnterRecursiveCall. */
199-
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
200-
return (tstate->c_recursion_remaining-- < 0
201-
|| (tstate->c_recursion_remaining & 63) == 0);
196+
#if !_Py__has_builtin(__builtin_frame_address)
197+
static uintptr_t return_pointer_as_int(char* p) {
198+
return (uintptr_t)p;
202199
}
200+
#endif
201+
202+
static inline uintptr_t
203+
_Py_get_machine_stack_pointer(void) {
204+
#if _Py__has_builtin(__builtin_frame_address)
205+
return (uintptr_t)__builtin_frame_address(0);
203206
#else
204-
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
205-
return tstate->c_recursion_remaining-- < 0;
206-
}
207+
char here;
208+
/* Avoid compiler warning about returning stack address */
209+
return return_pointer_as_int(&here);
207210
#endif
211+
}
212+
213+
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
214+
uintptr_t here_addr = _Py_get_machine_stack_pointer();
215+
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
216+
return here_addr < _tstate->c_stack_soft_limit;
217+
}
208218

209219
// Export for '_json' shared extension, used via _Py_EnterRecursiveCall()
210220
// static inline function.
@@ -220,23 +230,30 @@ static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate,
220230
return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where));
221231
}
222232

223-
static inline void _Py_EnterRecursiveCallTstateUnchecked(PyThreadState *tstate) {
224-
assert(tstate->c_recursion_remaining > 0);
225-
tstate->c_recursion_remaining--;
226-
}
227-
228233
static inline int _Py_EnterRecursiveCall(const char *where) {
229234
PyThreadState *tstate = _PyThreadState_GET();
230235
return _Py_EnterRecursiveCallTstate(tstate, where);
231236
}
232237

233-
static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) {
234-
tstate->c_recursion_remaining++;
238+
static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) {
239+
(void)tstate;
240+
}
241+
242+
PyAPI_FUNC(void) _Py_InitializeRecursionLimits(PyThreadState *tstate);
243+
244+
static inline int _Py_ReachedRecursionLimit(PyThreadState *tstate) {
245+
uintptr_t here_addr = _Py_get_machine_stack_pointer();
246+
_PyThreadStateImpl *_tstate = (_PyThreadStateImpl *)tstate;
247+
if (here_addr > _tstate->c_stack_soft_limit) {
248+
return 0;
249+
}
250+
if (_tstate->c_stack_hard_limit == 0) {
251+
_Py_InitializeRecursionLimits(tstate);
252+
}
253+
return here_addr <= _tstate->c_stack_soft_limit;
235254
}
236255

237256
static inline void _Py_LeaveRecursiveCall(void) {
238-
PyThreadState *tstate = _PyThreadState_GET();
239-
_Py_LeaveRecursiveCallTstate(tstate);
240257
}
241258

242259
extern struct _PyInterpreterFrame* _PyEval_GetFrame(void);
@@ -327,7 +344,6 @@ void _Py_unset_eval_breaker_bit_all(PyInterpreterState *interp, uintptr_t bit);
327344

328345
PyAPI_FUNC(PyObject *) _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyStackRef right, double value);
329346

330-
331347
#ifdef __cplusplus
332348
}
333349
#endif

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy