Skip to content

Commit fb73967

Browse files
committed
Merge branch 'main' into pythongh-127794
2 parents aaa8879 + e62e1ca commit fb73967

Some content is hidden

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

60 files changed

+963
-407
lines changed

.github/workflows/reusable-windows-msi.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ jobs:
2424
with:
2525
persist-credentials: false
2626
- name: Build CPython installer
27-
run: .\Tools\msi\build.bat --doc -"${ARCH}"
27+
run: ./Tools/msi/build.bat --doc -"${ARCH}"
28+
shell: bash

Doc/c-api/frame.rst

+21-1
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,34 @@ See also :ref:`Reflection <reflection>`.
132132
.. versionadded:: 3.11
133133
134134
.. versionchanged:: 3.13
135-
As part of :pep:`667`, return a proxy object for optimized scopes.
135+
As part of :pep:`667`, return an instance of :c:var:`PyFrameLocalsProxy_Type`.
136136
137137
138138
.. c:function:: int PyFrame_GetLineNumber(PyFrameObject *frame)
139139
140140
Return the line number that *frame* is currently executing.
141141
142142
143+
Frame Locals Proxies
144+
^^^^^^^^^^^^^^^^^^^^
145+
146+
.. versionadded:: 3.13
147+
148+
The :attr:`~frame.f_locals` attribute on a :ref:`frame object <frame-objects>`
149+
is an instance of a "frame-locals proxy". The proxy object exposes a
150+
write-through view of the underlying locals dictionary for the frame. This
151+
ensures that the variables exposed by ``f_locals`` are always up to date with
152+
the live local variables in the frame itself.
153+
154+
See :pep:`667` for more information.
155+
156+
.. c:var:: PyTypeObject PyFrameLocalsProxy_Type
157+
158+
The type of frame :func:`locals` proxy objects.
159+
160+
.. c:function:: int PyFrameLocalsProxy_Check(PyObject *obj)
161+
162+
Return non-zero if *obj* is a frame :func:`locals` proxy.
143163
144164
Internal Frames
145165
^^^^^^^^^^^^^^^

Doc/c-api/object.rst

+6
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,12 @@ Object Protocol
509509
iterated.
510510
511511
512+
.. c:function:: PyObject* PyObject_SelfIter(PyObject *obj)
513+
514+
This is equivalent to the Python ``__iter__(self): return self`` method.
515+
It is intended for :term:`iterator` types, to be used in the :c:member:`PyTypeObject.tp_iter` slot.
516+
517+
512518
.. c:function:: PyObject* PyObject_GetAIter(PyObject *o)
513519
514520
This is the equivalent to the Python expression ``aiter(o)``. Takes an

Doc/data/refcounts.dat

+3
Original file line numberDiff line numberDiff line change
@@ -1849,6 +1849,9 @@ PyObject_RichCompareBool:PyObject*:o1:0:
18491849
PyObject_RichCompareBool:PyObject*:o2:0:
18501850
PyObject_RichCompareBool:int:opid::
18511851

1852+
PyObject_SelfIter:PyObject*::+1:
1853+
PyObject_SelfIter:PyObject*:obj:0:
1854+
18521855
PyObject_SetAttr:int:::
18531856
PyObject_SetAttr:PyObject*:o:0:
18541857
PyObject_SetAttr:PyObject*:attr_name:0:

Doc/library/http.cookies.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ Cookie Objects
9898
.. method:: BaseCookie.output(attrs=None, header='Set-Cookie:', sep='\r\n')
9999

100100
Return a string representation suitable to be sent as HTTP headers. *attrs* and
101-
*header* are sent to each :class:`Morsel`'s :meth:`output` method. *sep* is used
101+
*header* are sent to each :class:`Morsel`'s :meth:`~Morsel.output` method. *sep* is used
102102
to join the headers together, and is by default the combination ``'\r\n'``
103103
(CRLF).
104104

Doc/library/itertools.rst

+6-6
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,7 @@ The following recipes have a more mathematical flavor:
10151015
.. testcode::
10161016

10171017
def powerset(iterable):
1018-
"powerset([1,2,3]) → () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
1018+
# powerset([1,2,3]) → () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)
10191019
s = list(iterable)
10201020
return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))
10211021

@@ -1104,11 +1104,6 @@ The following recipes have a more mathematical flavor:
11041104
data[p*p : n : p+p] = bytes(len(range(p*p, n, p+p)))
11051105
yield from iter_index(data, 1, start=3)
11061106

1107-
def is_prime(n):
1108-
"Return True if n is prime."
1109-
# is_prime(1_000_000_000_000_403) → True
1110-
return n > 1 and all(n % p for p in sieve(math.isqrt(n) + 1))
1111-
11121107
def factor(n):
11131108
"Prime factors of n."
11141109
# factor(99) → 3 3 11
@@ -1123,6 +1118,11 @@ The following recipes have a more mathematical flavor:
11231118
if n > 1:
11241119
yield n
11251120

1121+
def is_prime(n):
1122+
"Return True if n is prime."
1123+
# is_prime(1_000_000_000_000_403) → True
1124+
return n > 1 and next(factor(n)) == n
1125+
11261126
def totient(n):
11271127
"Count of natural numbers up to n that are coprime to n."
11281128
# https://mathworld.wolfram.com/TotientFunction.html

Doc/library/traceback.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ Module-Level Functions
274274
:class:`!TracebackException` objects are created from actual exceptions to
275275
capture data for later printing. They offer a more lightweight method of
276276
storing this information by avoiding holding references to
277-
:ref:`traceback<traceback-objects>` and :ref:`frame<frame-objects>` objects
277+
:ref:`traceback<traceback-objects>` and :ref:`frame<frame-objects>` objects.
278278
In addition, they expose more options to configure the output compared to
279279
the module-level functions described above.
280280

Include/internal/pycore_freelist.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static inline int
5151
_PyFreeList_Push(struct _Py_freelist *fl, void *obj, Py_ssize_t maxsize)
5252
{
5353
if (fl->size < maxsize && fl->size >= 0) {
54-
*(void **)obj = fl->freelist;
54+
FT_ATOMIC_STORE_PTR_RELAXED(*(void **)obj, fl->freelist);
5555
fl->freelist = obj;
5656
fl->size++;
5757
OBJECT_STAT_INC(to_freelist);

Include/internal/pycore_freelist_state.h

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ extern "C" {
1414
# define Py_dicts_MAXFREELIST 80
1515
# define Py_dictkeys_MAXFREELIST 80
1616
# define Py_floats_MAXFREELIST 100
17+
# define Py_ints_MAXFREELIST 100
1718
# define Py_slices_MAXFREELIST 1
1819
# define Py_contexts_MAXFREELIST 255
1920
# define Py_async_gens_MAXFREELIST 80
@@ -35,6 +36,7 @@ struct _Py_freelist {
3536

3637
struct _Py_freelists {
3738
struct _Py_freelist floats;
39+
struct _Py_freelist ints;
3840
struct _Py_freelist tuples[PyTuple_MAXSAVESIZE];
3941
struct _Py_freelist lists;
4042
struct _Py_freelist dicts;

Include/internal/pycore_global_objects_fini_generated.h

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_global_strings.h

+1
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,7 @@ struct _Py_global_strings {
618618
STRUCT_FOR_ID(origin)
619619
STRUCT_FOR_ID(out_fd)
620620
STRUCT_FOR_ID(outgoing)
621+
STRUCT_FOR_ID(outpath)
621622
STRUCT_FOR_ID(overlapped)
622623
STRUCT_FOR_ID(owner)
623624
STRUCT_FOR_ID(pages)

Include/internal/pycore_list.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ typedef struct {
6262
union _PyStackRef;
6363

6464
PyAPI_FUNC(PyObject *)_PyList_FromStackRefSteal(const union _PyStackRef *src, Py_ssize_t n);
65-
65+
PyAPI_FUNC(PyObject *)_PyList_AsTupleAndClear(PyListObject *v);
6666

6767
#ifdef __cplusplus
6868
}

Include/internal/pycore_long.h

+2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ extern void _PyLong_FiniTypes(PyInterpreterState *interp);
5555

5656
/* other API */
5757

58+
PyAPI_FUNC(void) _PyLong_ExactDealloc(PyObject *self);
59+
5860
#define _PyLong_SMALL_INTS _Py_SINGLETON(small_ints)
5961

6062
// _PyLong_GetZero() and _PyLong_GetOne() must always be available

Include/internal/pycore_object.h

+16-2
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,24 @@ PyAPI_FUNC(int) _PyObject_IsFreed(PyObject *);
7373
#define _PyObject_HEAD_INIT(type) \
7474
{ \
7575
.ob_ref_local = _Py_IMMORTAL_REFCNT_LOCAL, \
76+
.ob_flags = _Py_STATICALLY_ALLOCATED_FLAG, \
7677
.ob_type = (type) \
7778
}
7879
#else
80+
#if SIZEOF_VOID_P > 4
7981
#define _PyObject_HEAD_INIT(type) \
8082
{ \
81-
.ob_refcnt = _Py_IMMORTAL_INITIAL_REFCNT, \
83+
.ob_refcnt = _Py_IMMORTAL_INITIAL_REFCNT, \
84+
.ob_flags = _Py_STATICALLY_ALLOCATED_FLAG, \
8285
.ob_type = (type) \
8386
}
87+
#else
88+
#define _PyObject_HEAD_INIT(type) \
89+
{ \
90+
.ob_refcnt = _Py_STATIC_IMMORTAL_INITIAL_REFCNT, \
91+
.ob_type = (type) \
92+
}
93+
#endif
8494
#endif
8595
#define _PyVarObject_HEAD_INIT(type, size) \
8696
{ \
@@ -127,7 +137,11 @@ static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n)
127137
_Py_AddRefTotal(_PyThreadState_GET(), n);
128138
#endif
129139
#if !defined(Py_GIL_DISABLED)
140+
#if SIZEOF_VOID_P > 4
141+
op->ob_refcnt += (PY_UINT32_T)n;
142+
#else
130143
op->ob_refcnt += n;
144+
#endif
131145
#else
132146
if (_Py_IsOwnedByCurrentThread(op)) {
133147
uint32_t local = op->ob_ref_local;
@@ -170,7 +184,7 @@ PyAPI_FUNC(void) _Py_SetImmortalUntracked(PyObject *op);
170184

171185
// Makes an immortal object mortal again with the specified refcnt. Should only
172186
// be used during runtime finalization.
173-
static inline void _Py_SetMortal(PyObject *op, Py_ssize_t refcnt)
187+
static inline void _Py_SetMortal(PyObject *op, short refcnt)
174188
{
175189
if (op) {
176190
assert(_Py_IsImmortal(op));

Include/internal/pycore_optimizer.h

+5
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ typedef struct {
6060
};
6161
uint64_t operand0; // A cache entry
6262
uint64_t operand1;
63+
#ifdef Py_STATS
64+
uint64_t execution_count;
65+
#endif
6366
} _PyUOpInstruction;
6467

6568
typedef struct {
@@ -285,6 +288,8 @@ static inline int is_terminator(const _PyUOpInstruction *uop)
285288
);
286289
}
287290

291+
PyAPI_FUNC(int) _PyDumpExecutors(FILE *out);
292+
288293
#ifdef __cplusplus
289294
}
290295
#endif

Include/internal/pycore_runtime_init_generated.h

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/internal/pycore_unicodeobject_generated.h

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Include/object.h

+15-5
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ whose size is determined when the object is allocated.
7171
#define PyObject_HEAD_INIT(type) \
7272
{ \
7373
0, \
74-
0, \
74+
_Py_STATICALLY_ALLOCATED_FLAG, \
7575
{ 0 }, \
7676
0, \
7777
_Py_IMMORTAL_REFCNT_LOCAL, \
@@ -81,7 +81,7 @@ whose size is determined when the object is allocated.
8181
#else
8282
#define PyObject_HEAD_INIT(type) \
8383
{ \
84-
{ _Py_IMMORTAL_INITIAL_REFCNT }, \
84+
{ _Py_STATIC_IMMORTAL_INITIAL_REFCNT }, \
8585
(type) \
8686
},
8787
#endif
@@ -120,9 +120,19 @@ struct _object {
120120
__pragma(warning(disable: 4201))
121121
#endif
122122
union {
123-
Py_ssize_t ob_refcnt;
124123
#if SIZEOF_VOID_P > 4
125-
PY_UINT32_T ob_refcnt_split[2];
124+
PY_INT64_T ob_refcnt_full; /* This field is needed for efficient initialization with Clang on ARM */
125+
struct {
126+
# if PY_BIG_ENDIAN
127+
PY_UINT32_T ob_flags;
128+
PY_UINT32_T ob_refcnt;
129+
# else
130+
PY_UINT32_T ob_refcnt;
131+
PY_UINT32_T ob_flags;
132+
# endif
133+
};
134+
#else
135+
Py_ssize_t ob_refcnt;
126136
#endif
127137
};
128138
#ifdef _MSC_VER
@@ -142,7 +152,7 @@ struct _object {
142152
// trashcan mechanism as a linked list pointer and by the GC to store the
143153
// computed "gc_refs" refcount.
144154
uintptr_t ob_tid;
145-
uint16_t _padding;
155+
uint16_t ob_flags;
146156
PyMutex ob_mutex; // per-object lock
147157
uint8_t ob_gc_bits; // gc-related state
148158
uint32_t ob_ref_local; // local reference count

0 commit comments

Comments
 (0)