Skip to content

Commit b2bf829

Browse files
authored
Merge branch 'main' into remove-JUMP_IF_FALSE_OR_POP
2 parents 12595f6 + d1a89ce commit b2bf829

32 files changed

+334
-364
lines changed

Doc/c-api/object.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,15 @@ Object Protocol
179179
If *o1* and *o2* are the same object, :c:func:`PyObject_RichCompareBool`
180180
will always return ``1`` for :const:`Py_EQ` and ``0`` for :const:`Py_NE`.
181181
182+
.. c:function:: PyObject* PyObject_Format(PyObject *obj, PyObject *format_spec)
183+
184+
Format *obj* using *format_spec*. This is equivalent to the Python
185+
expression ``format(obj, format_spec)``.
186+
187+
*format_spec* may be ``NULL``. In this case the call is equivalent
188+
to ``format(obj)``.
189+
Returns the formatted string on success, ``NULL`` on failure.
190+
182191
.. c:function:: PyObject* PyObject_Repr(PyObject *o)
183192
184193
.. index:: builtin: repr

Doc/library/itertools.rst

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ loops that truncate the stream.
195195
if n < 1:
196196
raise ValueError('n must be at least one')
197197
it = iter(iterable)
198-
while (batch := tuple(islice(it, n))):
198+
while batch := tuple(islice(it, n)):
199199
yield batch
200200

201201
.. versionadded:: 3.12
@@ -866,6 +866,17 @@ which incur interpreter overhead.
866866
window.append(x)
867867
yield math.sumprod(kernel, window)
868868

869+
def polynomial_from_roots(roots):
870+
"""Compute a polynomial's coefficients from its roots.
871+
872+
(x - 5) (x + 4) (x - 3) expands to: x³ -4x² -17x + 60
873+
"""
874+
# polynomial_from_roots([5, -4, 3]) --> [1, -4, -17, 60]
875+
expansion = [1]
876+
for r in roots:
877+
expansion = convolve(expansion, (1, -r))
878+
return list(expansion)
879+
869880
def polynomial_eval(coefficients, x):
870881
"""Evaluate a polynomial at a specific value.
871882

@@ -876,20 +887,8 @@ which incur interpreter overhead.
876887
n = len(coefficients)
877888
if n == 0:
878889
return x * 0 # coerce zero to the type of x
879-
powers = map(pow, repeat(x), range(n))
880-
return math.sumprod(reversed(coefficients), powers)
881-
882-
def polynomial_from_roots(roots):
883-
"""Compute a polynomial's coefficients from its roots.
884-
885-
(x - 5) (x + 4) (x - 3) expands to: x³ -4x² -17x + 60
886-
"""
887-
# polynomial_from_roots([5, -4, 3]) --> [1, -4, -17, 60]
888-
roots = list(map(operator.neg, roots))
889-
return [
890-
sum(map(math.prod, combinations(roots, k)))
891-
for k in range(len(roots) + 1)
892-
]
890+
powers = map(pow, repeat(x), reversed(range(n)))
891+
return math.sumprod(coefficients, powers)
893892

894893
def iter_index(iterable, value, start=0):
895894
"Return indices where a value occurs in a sequence or iterable."

Doc/library/os.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3951,7 +3951,7 @@ to be ignored.
39513951

39523952
.. note::
39533953

3954-
The standard way to exit is ``sys.exit(n)``. :func:`_exit` should
3954+
The standard way to exit is :func:`sys.exit(n) <sys.exit>`. :func:`!_exit` should
39553955
normally only be used in the child process after a :func:`fork`.
39563956

39573957
The following exit codes are defined and can be used with :func:`_exit`,

Include/cpython/initconfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ PyAPI_FUNC(PyStatus) PyStatus_Exit(int exitcode);
2525
PyAPI_FUNC(int) PyStatus_IsError(PyStatus err);
2626
PyAPI_FUNC(int) PyStatus_IsExit(PyStatus err);
2727
PyAPI_FUNC(int) PyStatus_Exception(PyStatus err);
28+
PyAPI_FUNC(PyObject *) _PyErr_SetFromPyStatus(PyStatus status);
2829

2930
/* --- PyWideStringList ------------------------------------------------ */
3031

Include/cpython/object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ PyAPI_FUNC(void) _Py_ForgetReference(PyObject *);
1515
PyAPI_FUNC(Py_ssize_t) _Py_GetGlobalRefTotal(void);
1616
# define _Py_GetRefTotal() _Py_GetGlobalRefTotal()
1717
PyAPI_FUNC(Py_ssize_t) _Py_GetLegacyRefTotal(void);
18+
PyAPI_FUNC(Py_ssize_t) _PyInterpreterState_GetRefTotal(PyInterpreterState *);
1819
#endif
1920

2021

Include/cpython/pyerrors.h

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -116,24 +116,6 @@ PyAPI_FUNC(int) _PyException_AddNote(
116116
PyObject *exc,
117117
PyObject *note);
118118

119-
/* Helper that attempts to replace the current exception with one of the
120-
* same type but with a prefix added to the exception text. The resulting
121-
* exception description looks like:
122-
*
123-
* prefix (exc_type: original_exc_str)
124-
*
125-
* Only some exceptions can be safely replaced. If the function determines
126-
* it isn't safe to perform the replacement, it will leave the original
127-
* unmodified exception in place.
128-
*
129-
* Returns a borrowed reference to the new exception (if any), NULL if the
130-
* existing exception was left in place.
131-
*/
132-
PyAPI_FUNC(PyObject *) _PyErr_TrySetFromCause(
133-
const char *prefix_format, /* ASCII-encoded string */
134-
...
135-
);
136-
137119
/* In signalmodule.c */
138120

139121
int PySignal_SetWakeupFd(int fd);

Include/cpython/pylifecycle.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,5 +62,6 @@ PyAPI_FUNC(int) _Py_CoerceLegacyLocale(int warn);
6262
PyAPI_FUNC(int) _Py_LegacyLocaleDetected(int warn);
6363
PyAPI_FUNC(char *) _Py_SetLocaleFromEnv(int category);
6464

65-
PyAPI_FUNC(PyThreadState *) _Py_NewInterpreterFromConfig(
66-
const _PyInterpreterConfig *);
65+
PyAPI_FUNC(PyStatus) _Py_NewInterpreterFromConfig(
66+
PyThreadState **tstate_p,
67+
const _PyInterpreterConfig *config);

Include/internal/pycore_initconfig.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ struct pyruntimestate;
4444
#define _PyStatus_UPDATE_FUNC(err) \
4545
do { (err).func = _PyStatus_GET_FUNC(); } while (0)
4646

47-
PyObject* _PyErr_SetFromPyStatus(PyStatus status);
48-
4947
/* --- PyWideStringList ------------------------------------------------ */
5048

5149
#define _PyWideStringList_INIT (PyWideStringList){.length = 0, .items = NULL}

Include/internal/pycore_interp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ extern "C" {
2525
#include "pycore_import.h" // struct _import_state
2626
#include "pycore_list.h" // struct _Py_list_state
2727
#include "pycore_global_objects.h" // struct _Py_interp_static_objects
28+
#include "pycore_object_state.h" // struct _py_object_state
2829
#include "pycore_tuple.h" // struct _Py_tuple_state
2930
#include "pycore_typeobject.h" // struct type_cache
3031
#include "pycore_unicodeobject.h" // struct _Py_unicode_state
@@ -138,6 +139,7 @@ struct _is {
138139
// One bit is set for each non-NULL entry in code_watchers
139140
uint8_t active_code_watchers;
140141

142+
struct _py_object_state object_state;
141143
struct _Py_unicode_state unicode;
142144
struct _Py_float_state float_state;
143145
struct _Py_long_state long_state;

Include/internal/pycore_object.h

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,18 +43,19 @@ PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc(
4343
built against the pre-3.12 stable ABI. */
4444
PyAPI_DATA(Py_ssize_t) _Py_RefTotal;
4545

46-
extern void _Py_AddRefTotal(Py_ssize_t);
47-
extern void _Py_IncRefTotal(void);
48-
extern void _Py_DecRefTotal(void);
46+
extern void _Py_AddRefTotal(PyInterpreterState *, Py_ssize_t);
47+
extern void _Py_IncRefTotal(PyInterpreterState *);
48+
extern void _Py_DecRefTotal(PyInterpreterState *);
4949

50-
# define _Py_DEC_REFTOTAL() _PyRuntime.object_state.reftotal--
50+
# define _Py_DEC_REFTOTAL(interp) \
51+
interp->object_state.reftotal--
5152
#endif
5253

5354
// Increment reference count by n
5455
static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n)
5556
{
5657
#ifdef Py_REF_DEBUG
57-
_Py_AddRefTotal(n);
58+
_Py_AddRefTotal(_PyInterpreterState_GET(), n);
5859
#endif
5960
op->ob_refcnt += n;
6061
}
@@ -65,7 +66,7 @@ _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
6566
{
6667
_Py_DECREF_STAT_INC();
6768
#ifdef Py_REF_DEBUG
68-
_Py_DEC_REFTOTAL();
69+
_Py_DEC_REFTOTAL(_PyInterpreterState_GET());
6970
#endif
7071
if (--op->ob_refcnt != 0) {
7172
assert(op->ob_refcnt > 0);
@@ -83,7 +84,7 @@ _Py_DECREF_NO_DEALLOC(PyObject *op)
8384
{
8485
_Py_DECREF_STAT_INC();
8586
#ifdef Py_REF_DEBUG
86-
_Py_DEC_REFTOTAL();
87+
_Py_DEC_REFTOTAL(_PyInterpreterState_GET());
8788
#endif
8889
op->ob_refcnt--;
8990
#ifdef Py_DEBUG
@@ -226,6 +227,7 @@ static inline void _PyObject_GC_UNTRACK(
226227
#endif
227228

228229
#ifdef Py_REF_DEBUG
230+
extern void _PyInterpreterState_FinalizeRefTotal(PyInterpreterState *);
229231
extern void _Py_FinalizeRefTotal(_PyRuntimeState *);
230232
extern void _PyDebug_PrintTotalRefs(void);
231233
#endif

0 commit comments

Comments
 (0)