8000 Merge branch 'main' into whats-new · python/cpython@b54ddcf · GitHub
[go: up one dir, main page]

Skip to content

Commit b54ddcf

Browse files
authored
Merge branch 'main' into whats-new
2 parents 72d0b39 + 173d13b commit b54ddcf

40 files changed

+1030
-819
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ Doc/c-api/stable.rst @encukou
151151

152152
**/*idlelib* @terryjreedy
153153

154-
**/*typing* @gvanrossum @Fidget-Spinner @JelleZijlstra @AlexWaygood
154+
**/*typing* @gvanrossum @JelleZijlstra @AlexWaygood
155155

156156
**/*ftplib @giampaolo
157157
**/*shutil @giampaolo

.github/workflows/build.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -500,11 +500,13 @@ jobs:
500500
- check_source # Transitive dependency, needed to access `run_tests` value
501501
- check-docs
502502
- check_generated_files
503-
- build_windows
504503
- build_macos
504+
- build_macos_free_threaded
505505
- build_ubuntu
506506
- build_ubuntu_free_threaded
507507
- build_ubuntu_ssltests
508+
- build_windows
509+
- build_windows_free_threaded
508510
- test_hypothesis
509511
- build_asan
510512
- cifuzz
@@ -517,10 +519,10 @@ jobs:
517519
with:
518520
allowed-failures: >-
519521
build_macos,
522+
build_macos_free_threaded,
520523
build_ubuntu_free_threaded,
521524
build_ubuntu_ssltests,
522-
build_win32,
523-
build_win_arm64,
525+
build_windows_free_threaded,
524526
cifuzz,
525527
test_hypothesis,
526528
allowed-skips: >-
@@ -535,13 +537,13 @@ jobs:
535537
needs.check_source.outputs.run_tests != 'true'
536538
&& '
537539
check_generated_files,
538-
build_win32,
539-
build_win_amd64,
540-
build_win_arm64,
541540
build_macos,
541+
build_macos_free_threaded,
542542
build_ubuntu,
543543
build_ubuntu_free_threaded,
544544
build_ubuntu_ssltests,
545+
build_windows,
546+
build_windows_free_threaded,
545547
build_asan,
546548
'
547549
|| ''

Doc/c-api/exceptions.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,17 @@ Printing and clearing
8888
The function is called with a single argument *obj* that identifies the context
8989
in which the unraisable exception occurred. If possible,
9090
the repr of *obj* will be printed in the warning message.
91+
If *obj* is ``NULL``, only the traceback is printed.
9192
9293
An exception must be set when calling this function.
9394
95+
.. versionchanged:: 3.4
96+
Print a traceback. Print only traceback if *obj* is ``NULL``.
97+
98+
.. versionchanged:: 3.8
99+
Use :func:`sys.unraisablehook`.
100+
101+
94102
.. c:function:: void PyErr_DisplayException(PyObject *exc)
95103
96104
Print the standard traceback display of ``exc`` to ``sys.stderr``, including

Doc/howto/enum.rst

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,7 @@ Dataclass support
483483
When inheriting from a :class:`~dataclasses.dataclass`,
484484
the :meth:`~Enum.__repr__` omits the inherited class' name. For example::
485485

486+
>>> from dataclasses import dataclass, field
486487
>>> @dataclass
487488
... class CreatureDataMixin:
488489
... size: str
@@ -527,7 +528,8 @@ It is possible to modify how enum members are pickled/unpickled by defining
527528
:meth:`__reduce_ex__` in the enumeration class. The default method is by-value,
528529
but enums with complicated values may want to use by-name::
529530

530-
>>> class MyEnum(Enum):
531+
>>> import enum
532+
>>> class MyEnum(enum.Enum):
531533
... __reduce_ex__ = enum.pickle_by_enum_name
532534

533535
.. note::
@@ -770,7 +772,7 @@ be combined with them (but may lose :class:`IntFlag` membership::
770772
>>> Perm.X | 4
771773
<Perm.R|X: 5>
772774

773-
>>> Perm.X | 8
775+
>>> Perm.X + 8
774776
9
775777

776778
.. note::
@@ -1435,8 +1437,9 @@ alias::
14351437
... GRENE = 2
14361438
...
14371439
Traceback (most recent call last):
1438-
...
1440+
...
14391441
ValueError: aliases not allowed in DuplicateFreeEnum: 'GRENE' --> 'GREEN'
1442+
Error calling __set_name__ on '_proto_member' instance 'GRENE' in 'Color'
14401443

14411444
.. note::
14421445

Include/cpython/pystate.h

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -258,80 +258,3 @@ PyAPI_FUNC(_PyFrameEvalFunction) _PyInterpreterState_GetEvalFrameFunc(
258258
PyAPI_FUNC(void) _PyInterpreterState_SetEvalFrameFunc(
259259
PyInterpreterState *interp,
260260
_PyFrameEvalFunction eval_frame);
261-
262-
263-
/* cross-interpreter data */
264-
265-
// _PyCrossInterpreterData is similar to Py_buffer as an effectively
266-
// opaque struct that holds data outside the object machinery. This
267-
// is necessary to pass safely between interpreters in the same process.
268-
typedef struct _xid _PyCrossInterpreterData;
269-
270-
typedef PyObject *(*xid_newobjectfunc)(_PyCrossInterpreterData *);
271-
typedef void (*xid_freefunc)(void *);
272-
273-
struct _xid {
274-
// data is the cross-interpreter-safe derivation of a Python object
275-
// (see _PyObject_GetCrossInterpreterData). It will be NULL if the
276-
// new_object func (below) encodes the data.
277-
void *data;
278-
// obj is the Python object from which the data was derived. This
279-
// is non-NULL only if the data remains bound to the object in some
280-
// way, such that the object must be "released" (via a decref) when
281-
// the data is released. In that case the code that sets the field,
282-
// likely a registered "crossinterpdatafunc", is responsible for
283-
// ensuring it owns the reference (i.e. incref).
284-
PyObject *obj;
285-
// interp is the ID of the owning interpreter of the original
286-
// object. It corresponds to the active interpreter when
287-
// _PyObject_GetCrossInterpreterData() was called. This should only
288-
// be set by the cross-interpreter machinery.
289-
//
290-
// We use the ID rather than the PyInterpreterState to avoid issues
291-
// with deleted interpreters. Note that IDs are never re-used, so
292-
// each one will always correspond to a specific interpreter
293-
// (whether still alive or not).
294-
int64_t interpid;
295-
// new_object is a function that returns a new object in the current
296-
// interpreter given the data. The resulting object (a new
297-
// reference) will be equivalent to the original object. This field
298-
// is required.
299-
xid_newobjectfunc new_object;
300-
// free is called when the data is released. If it is NULL then
301-
// nothing will be done to free the data. For some types this is
302-
// okay (e.g. bytes) and for those types this field should be set
303-
// to NULL. However, for most the data was allocated just for
304-
// cross-interpreter use, so it must be freed when
305-
// _PyCrossInterpreterData_Release is called or the memory will
306-
// leak. In that case, at the very least this field should be set
307-
// to PyMem_RawFree (the default if not explicitly set to NULL).
308-
// The call will happen with the original interpreter activated.
309-
xid_freefunc free;
310-
};
311-
312-
PyAPI_FUNC(void) _PyCrossInterpreterData_Init(
313-
_PyCrossInterpreterData *data,
314-
PyInterpreterState *interp, void *shared, PyObject *obj,
315-
xid_newobjectfunc new_object);
316-
PyAPI_FUNC(int) _PyCrossInterpreterData_InitWithSize(
317-
_PyCrossInterpreterData *,
318-
PyInterpreterState *interp, const size_t, PyObject *,
319-
xid_newobjectfunc);
320-
PyAPI_FUNC(void) _PyCrossInterpreterData_Clear(
321-
PyInterpreterState *, _PyCrossInterpreterData *);
322-
323-
PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *);
324-
PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *);
325-
PyAPI_FUNC(int) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *);
326-
PyAPI_FUNC(int) _PyCrossInterpreterData_ReleaseAndRawFree(_PyCrossInterpreterData *);
327-
328-
PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *);
329-
330-
/* cross-interpreter data registry */
331-
332-
typedef int (*crossinterpdatafunc)(PyThreadState *tstate, PyObject *,
333-
_PyCrossInterpreterData *);
334-
335-
PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc);
336-
PyAPI_FUNC(int) _PyCrossInterpreterData_UnregisterClass(PyTypeObject *);
337-
PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *);

Include/cpython/pystats.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ typedef struct _gc_stats {
9898

9999
typedef struct _uop_stats {
100100
uint64_t execution_count;
101+
uint64_t miss;
101102
} UOpStats;
102103

103104
#define _Py_UOP_HIST_SIZE 32

Include/internal/mimalloc/mimalloc/atomic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ static inline uintptr_t mi_atomic_load_explicit(_Atomic(uintptr_t) const* p, mi_
195195
#else
196196
uintptr_t x = *p;
197197
if (mo > mi_memory_order_relaxed) {
198-
while (!mi_atomic_compare_exchange_weak_explicit(p, &x, x, mo, mi_memory_order_relaxed)) { /* nothing */ };
198+
while (!mi_atomic_compare_exchange_weak_explicit((_Atomic(uintptr_t)*)p, &x, x, mo, mi_memory_order_relaxed)) { /* nothing */ };
199199
}
200200
return x;
201201
#endif

Include/internal/pycore_ceval.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,6 @@ PyAPI_FUNC(int) _PyEval_AddPendingCall(
5454
void *arg,
5555
int flags);
5656

57-
typedef int (*_Py_simple_func)(void *);
58-
extern int _Py_CallInInterpreter(
59-
PyInterpreterState *interp,
60-
_Py_simple_func func,
61-
void *arg);
62-
extern int _Py_CallInInterpreterAndRawFree(
63-
PyInterpreterState *interp,
64-
_Py_simple_func func,
65-
void *arg);
66-
6757
extern void _PyEval_SignalAsyncExc(PyInterpreterState *interp);
6858
#ifdef HAVE_FORK
6959
extern PyStatus _PyEval_ReInitThreads(PyThreadState *tstate);

Include/internal/pycore_code.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ extern int _PyStaticCode_Init(PyCodeObject *co);
283283
do { if (_Py_stats && PyFunction_Check(callable)) _Py_stats->call_stats.eval_calls[name]++; } while (0)
284284
#define GC_STAT_ADD(gen, name, n) do { if (_Py_stats) _Py_stats->gc_stats[(gen)].name += (n); } while (0)
285285
#define OPT_STAT_INC(name) do { if (_Py_stats) _Py_stats->optimization_stats.name++; } while (0)
286-
#define UOP_EXE_INC(opname) do { if (_Py_stats) _Py_stats->optimization_stats.opcode[opname].execution_count++; } while (0)
286+
#define UOP_STAT_INC(opname, name) do { if (_Py_stats) { assert(opname < 512); _Py_stats->optimization_stats.opcode[opname].name++; } } while (0)
287287
#define OPT_UNSUPPORTED_OPCODE(opname) do { if (_Py_stats) _Py_stats->optimization_stats.unsupported_opcode[opname]++; } while (0)
288288
#define OPT_HIST(length, name) \
289289
do { \
@@ -308,7 +308,7 @@ PyAPI_FUNC(PyObject*) _Py_GetSpecializationStats(void);
308308
#define EVAL_CALL_STAT_INC_IF_FUNCTION(name, callable) ((void)0)
309309
#define GC_STAT_ADD(gen, name, n) ((void)0)
310310
#define OPT_STAT_INC(name) ((void)0)
311-
#define UOP_EXE_INC(opname) ((void)0)
311+
#define UOP_STAT_INC(opname, name) ((void)0)
312312
#define OPT_UNSUPPORTED_OPCODE(opname) ((void)0)
313313
#define OPT_HIST(length, name) ((void)0)
314314
#endif // !Py_STATS

Include/internal/pycore_crossinterp.h

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
#ifndef Py_INTERNAL_CROSSINTERP_H
2+
#define Py_INTERNAL_CROSSINTERP_H
3+
#ifdef __cplusplus
4+
extern "C" {
5+
#endif
6+
7+
#ifndef Py_BUILD_CORE
8+
# error "this header requires Py_BUILD_CORE define"
9+
#endif
10+
11+
12+
/***************************/
13+
/* cross-interpreter calls */
14+
/***************************/
15+
16+
typedef int (*_Py_simple_func)(void *);
17+
extern int _Py_CallInInterpreter(
18+
PyInterpreterState *interp,
19+
_Py_simple_func func,
20+
void *arg);
21+
extern int _Py_CallInInterpreterAndRawFree(
22+
PyInterpreterState *interp,
23+
_Py_simple_func func,
24+
void *arg);
25+
26+
27+
/**************************/
28+
/* cross-interpreter data */
29+
/**************************/
30+
31+
typedef struct _xid _PyCrossInterpreterData;
32+
typedef PyObject *(*xid_newobjectfunc)(_PyCrossInterpreterData *);
33+
typedef void (*xid_freefunc)(void *);
34+
35+
// _PyCrossInterpreterData is similar to Py_buffer as an effectively
36+
// opaque struct that holds data outside the object machinery. This
37+
// is necessary to pass safely between interpreters in the same process.
38+
struct _xid {
39+
// data is the cross-interpreter-safe derivation of a Python object
40+
// (see _PyObject_GetCrossInterpreterData). It will be NULL if the
41+
// new_object func (below) encodes the data.
42+
void *data;
43+
// obj is the Python object from which the data was derived. This
44+
// is non-NULL only if the data remains bound to the object in some
45+
// way, such that the object must be "released" (via a decref) when
46+
// the data is released. In that case the code that sets the field,
47+
// likely a registered "crossinterpdatafunc", is responsible for
48+
// ensuring it owns the reference (i.e. incref).
49+
PyObject *obj;
50+
// interp is the ID of the owning interpreter of the original
51+
// object. It corresponds to the active interpreter when
52+
// _PyObject_GetCrossInterpreterData() was called. This should only
53+
// be set by the cross-interpreter machinery.
54+
//
55+
// We use the ID rather than the PyInterpreterState to avoid issues
56+
// with deleted interpreters. Note that IDs are never re-used, so
57+
// each one will always correspond to a specific interpreter
58+
// (whether still alive or not).
59+
int64_t interpid;
60+
// new_object is a function that returns a new object in the current
61+
// interpreter given the data. The resulting object (a new
62+
// reference) will be equivalent to the original object. This field
63+
// is required.
64+
xid_newobjectfunc new_object;
65+
// free is called when the data is released. If it is NULL then
66+
// nothing will be done to free the data. For some types this is
67+
// okay (e.g. bytes) and for those types this field should be set
68+
// to NULL. However, for most the data was allocated just for
69+
// cross-interpreter use, so it must be freed when
70+
// _PyCrossInterpreterData_Release is called or the memory will
71+
// leak. In that case, at the very least this field should be set
72+
// to PyMem_RawFree (the default if not explicitly set to NULL).
73+
// The call will happen with the original interpreter activated.
74+
xid_freefunc free;
75+
};
76+
77+
PyAPI_FUNC(_PyCrossInterpreterData *) _PyCrossInterpreterData_New(void);
78+
PyAPI_FUNC(void) _PyCrossInterpreterData_Free(_PyCrossInterpreterData *data);
79+
80+
81+
/* defining cross-interpreter data */
82+
83+
PyAPI_FUNC(void) _PyCrossInterpreterData_Init(
84+
_PyCrossInterpreterData *data,
85+
PyInterpreterState *interp, void *shared, PyObject *obj,
86+
xid_newobjectfunc new_object);
87+
PyAPI_FUNC(int) _PyCrossInterpreterData_InitWithSize(
88+
_PyCrossInterpreterData *,
89+
PyInterpreterState *interp, const size_t, PyObject *,
90+
xid_newobjectfunc);
91+
PyAPI_FUNC(void) _PyCrossInterpreterData_Clear(
92+
PyInterpreterState *, _PyCrossInterpreterData *);
93+
94+
95+
/* using cross-interpreter data */
96+
97+
PyAPI_FUNC(int) _PyObject_CheckCrossInterpreterData(PyObject *);
98+
PyAPI_FUNC(int) _PyObject_GetCrossInterpreterData(PyObject *, _PyCrossInterpreterData *);
99+
PyAPI_FUNC(PyObject *) _PyCrossInterpreterData_NewObject(_PyCrossInterpreterData *);
100+
PyAPI_FUNC(int) _PyCrossInterpreterData_Release(_PyCrossInterpreterData *);
101+
PyAPI_FUNC(int) _PyCrossInterpreterData_ReleaseAndRawFree(_PyCrossInterpreterData *);
102+
103+
104+
/* cross-interpreter data registry */
105+
106+
// For now we use a global registry of shareable classes. An
107+
// alternative would be to add a tp_* slot for a class's
108+
// crossinterpdatafunc. It would be simpler and more efficient.
109+
110+
typedef int (*crossinterpdatafunc)(PyThreadState *tstate, PyObject *,
111+
_PyCrossInterpreterData *);
112+
113+
struct _xidregitem;
114+
115+
struct _xidregitem {
116+
struct _xidregitem *prev;
117+
struct _xidregitem *next;
118+
/* This can be a dangling pointer, but only if weakref is set. */
119+
PyTypeObject *cls;
120+
/* This is NULL for builtin types. */
121+
PyObject *weakref;
122+
size_t refcount;
123+
crossinterpdatafunc getdata;
124+
};
125+
126+
struct _xidregistry {
127+
PyThread_type_lock mutex;
128+
struct _xidregitem *head;
129+
};
130+
131+
PyAPI_FUNC(int) _PyCrossInterpreterData_RegisterClass(PyTypeObject *, crossinterpdatafunc);
132+
PyAPI_FUNC(int) _PyCrossInterpreterData_UnregisterClass(PyTypeObject *);
133+
PyAPI_FUNC(crossinterpdatafunc) _PyCrossInterpreterData_Lookup(PyObject *);
134+
135+
136+
#ifdef __cplusplus
137+
}
138+
#endif
139+
#endif /* !Py_INTERNAL_CROSSINTERP_H */

0 commit comments

Comments
 (0)
0