Skip to content

Commit eb16a6f

Browse files
authored
Merge branch 'main' into c-api-pyrun-string-doc
2 parents 86fa4f9 + 94cd2e0 commit eb16a6f

File tree

9 files changed

+81
-51
lines changed

9 files changed

+81
-51
lines changed

Doc/library/logging.rst

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -592,10 +592,12 @@ subclasses. However, the :meth:`!__init__` method in subclasses needs to call
592592

593593
.. method:: Handler.close()
594594

595-
Tidy up any resources used by the handler. This version does no output but
596-
removes the handler from an internal list of handlers which is closed when
597-
:func:`shutdown` is called. Subclasses should ensure that this gets called
598-
from overridden :meth:`close` methods.
595+
Tidy up any resources used by the handler. This version does no output
596+
but removes the handler from an internal map of handlers, which is used
597+
for handler lookup by name.
598+
599+
Subclasses should ensure that this gets called from overridden :meth:`close`
600+
methods.
599601

600602

601603
.. method:: Handler.handle(record)

Include/internal/pycore_object.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ PyAPI_DATA(Py_ssize_t) _Py_RefTotal;
121121

122122
extern void _Py_AddRefTotal(PyThreadState *, Py_ssize_t);
123123
extern PyAPI_FUNC(void) _Py_IncRefTotal(PyThreadState *);
124-
extern void _Py_DecRefTotal(PyThreadState *);
124+
extern PyAPI_FUNC(void) _Py_DecRefTotal(PyThreadState *);
125125

126126
# define _Py_DEC_REFTOTAL(interp) \
127127
interp->object_state.reftotal--
@@ -710,7 +710,7 @@ _PyObject_SetMaybeWeakref(PyObject *op)
710710
}
711711
}
712712

713-
extern int _PyObject_ResurrectEndSlow(PyObject *op);
713+
extern PyAPI_FUNC(int) _PyObject_ResurrectEndSlow(PyObject *op);
714714
#endif
715715

716716
// Temporarily resurrects an object during deallocation. The refcount is set

Lib/ensurepip/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212
__all__ = ["version", "bootstrap"]
13-
_PIP_VERSION = "24.3.1"
13+
_PIP_VERSION = "25.0.1"
1414

1515
# Directory of system wheel packages. Some Linux distribution packaging
1616
# policies recommend against bundling dependencies. For example, Fedora
1.74 MB
Binary file not shown.

Lib/test/test_asyncio/test_tasks.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2296,6 +2296,22 @@ async def kill_me(loop):
22962296

22972297
self.assertEqual(self.all_tasks(loop=self.loop), set())
22982298

2299+
def test_task_not_crash_without_finalization(self):
2300+
Task = self.__class__.Task
2301+
2302+
class Subclass(Task):
2303+
def __del__(self):
2304+
pass
2305+
2306+
async def coro():
2307+
await asyncio.sleep(0.01)
2308+
2309+
task = Subclass(coro(), loop = self.loop)
2310+
task._log_destroy_pending = False
2311+
2312+
del task
2313+
2314+
support.gc_collect()
22992315

23002316
@mock.patch('asyncio.base_events.logger')
23012317
def test_tb_logger_not_called_after_cancel(self, m_log):

Lib/test/test_ctypes/test_dlerror.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,14 @@ def test_null_dlsym(self):
5858
import subprocess
5959
import tempfile
6060

61-
retcode = subprocess.call(["gcc", "--version"],
62-
stdout=subprocess.DEVNULL,
63-
stderr=subprocess.DEVNULL)
64-
if retcode != 0:
61+
try:
62+
retcode = subprocess.call(["gcc", "--version"],
63+
stdout=subprocess.DEVNULL,
64+
stderr=subprocess.DEVNULL)
65+
except OSError:
6566
self.skipTest("gcc is missing")
67+
if retcode != 0:
68+
self.skipTest("gcc --version failed")
6669

6770
pipe_r, pipe_w = os.pipe()
6871
self.addCleanup(os.close, pipe_r)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Update bundled pip to 25.0.1

Modules/_asynciomodule.c

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2938,15 +2938,6 @@ _asyncio_Task_set_name_impl(TaskObj *self, PyObject *value)
29382938
static void
29392939
TaskObj_finalize(TaskObj *task)
29402940
{
2941-
asyncio_state *state = get_asyncio_state_by_def((PyObject *)task);
2942-
// Unregister the task from the linked list of tasks.
2943-
// Since task is a native task, we directly call the
2944-
// unregister_task function. Third party event loops
2945-
// should use the asyncio._unregister_task function.
2946-
// See https://docs.python.org/3/library/asyncio-extending.html#task-lifetime-support
2947-
2948-
unregister_task(state, task);
2949-
29502941
PyObject *context;
29512942
PyObject *message = NULL;
29522943
PyObject *func;
@@ -3071,8 +3062,15 @@ TaskObj_dealloc(PyObject *self)
30713062
{
30723063
TaskObj *task = (TaskObj *)self;
30733064

3074-
if (PyObject_CallFinalizerFromDealloc(self) < 0) {
3075-
// resurrected.
3065+
_PyObject_ResurrectStart(self);
3066+
// Unregister the task here so that even if any subclass of Task
3067+
// which doesn't end up calling TaskObj_finalize not crashes.
3068+
asyncio_state *state = get_asyncio_state_by_def(self);
3069+
unregister_task(state, task);
3070+
3071+
PyObject_CallFinalizer(self);
3072+
3073+
if (_PyObject_ResurrectEnd(self)) {
30763074
return;
30773075
}
30783076

@@ -3991,6 +3989,19 @@ static inline int
39913989
add_one_task(asyncio_state *state, PyObject *tasks, PyObject *task, PyObject *loop)
39923990
{
39933991
assert(PySet_CheckExact(tasks));
3992+
if (Task_CheckExact(state, task)) {
3993+
int pending = 0;
3994+
Py_BEGIN_CRITICAL_SECTION(task);
3995+
pending = ((TaskObj *)task)->task_state == STATE_PENDING && ((TaskObj *)task)->task_loop == loop;
3996+
Py_END_CRITICAL_SECTION();
3997+
if (pending) {
3998+
if (PySet_Add(tasks, task) < 0) {
3999+
return -1;
4000+
}
4001+
}
4002+
return 0;
4003+
}
4004+
39944005
PyObject *done = PyObject_CallMethodNoArgs(task, &_Py_ID(done));
39954006
if (done == NULL) {
39964007
return -1;
@@ -4102,6 +4113,12 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop)
41024113
Py_DECREF(loop);
41034114
return NULL;
41044115
}
4116+
if (PyList_Extend(tasks, state->non_asyncio_tasks) < 0) {
4117+
Py_DECREF(tasks);
4118+
Py_DECREF(loop);
4119+
return NULL;
4120+
}
4121+
41054122
PyInterpreterState *interp = PyInterpreterState_Get();
41064123
// Stop the world and traverse the per-thread linked list
41074124
// of asyncio tasks for every thread, as well as the
@@ -4127,24 +4144,7 @@ _asyncio_all_tasks_impl(PyObject *module, PyObject *loop)
41274144
Py_DECREF(loop);
41284145
return NULL;
41294146
}
4130-
PyObject *scheduled_iter = PyObject_GetIter(state->non_asyncio_tasks);
4131-
if (scheduled_iter == NULL) {
4132-
Py_DECREF(tasks);
4133-
Py_DECREF(loop);
4134-
return NULL;
4135-
}
4136-
PyObject *item;
4137-
while ((item = PyIter_Next(scheduled_iter)) != NULL) {
4138-
if (PyList_Append(tasks, item) < 0) {
4139-
Py_DECREF(tasks);
4140-
Py_DECREF(loop);
4141-
Py_DECREF(item);
4142-
Py_DECREF(scheduled_iter);
4143-
return NULL;
4144-
}
4145-
Py_DECREF(item);
4146-
}
4147-
Py_DECREF(scheduled_iter);
4147+
41484148
// All the tasks are now in the list, now filter the tasks which are done
41494149
PyObject *res = PySet_New(NULL);
41504150
if (res == NULL) {

Modules/_dbmmodule.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ typedef struct {
6464
DBM *di_dbm;
6565
} dbmobject;
6666

67+
#define dbmobject_CAST(op) ((dbmobject *)(op))
68+
6769
#include "clinic/_dbmmodule.c.h"
6870

6971
#define check_dbmobject_open(v, err) \
@@ -94,15 +96,16 @@ newdbmobject(_dbm_state *state, const char *file, int flags, int mode)
9496

9597
/* Methods */
9698
static int
97-
dbm_traverse(dbmobject *dp, visitproc visit, void *arg)
99+
dbm_traverse(PyObject *dp, visitproc visit, void *arg)
98100
{
99101
Py_VISIT(Py_TYPE(dp));
100102
return 0;
101103
}
102104

103105
static void
104-
dbm_dealloc(dbmobject *dp)
106+
dbm_dealloc(PyObject *self)
105107
{
108+
dbmobject *dp = dbmobject_CAST(self);
106109
PyObject_GC_UnTrack(dp);
107110
if (dp->di_dbm) {
108111
dbm_close(dp->di_dbm);
@@ -113,8 +116,9 @@ dbm_dealloc(dbmobject *dp)
113116
}
114117

115118
static Py_ssize_t
116-
dbm_length(dbmobject *dp)
119+
dbm_length(PyObject *self)
117120
{
121+
dbmobject *dp = dbmobject_CAST(self);
118122
_dbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
119123
assert(state != NULL);
120124
if (dp->di_dbm == NULL) {
@@ -135,8 +139,9 @@ dbm_length(dbmobject *dp)
135139
}
136140

137141
static int
138-
dbm_bool(dbmobject *dp)
142+
dbm_bool(PyObject *self)
139143
{
144+
dbmobject *dp = dbmobject_CAST(self);
140145
_dbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
141146
assert(state != NULL);
142147

@@ -166,10 +171,11 @@ dbm_bool(dbmobject *dp)
166171
}
167172

168173
static PyObject *
169-
dbm_subscript(dbmobject *dp, PyObject *key)
174+
dbm_subscript(PyObject *self, PyObject *key)
170175
{
171176
datum drec, krec;
172177
Py_ssize_t tmp_size;
178+
dbmobject *dp = dbmobject_CAST(self);
173179
_dbm_state *state = PyType_GetModuleState(Py_TYPE(dp));
174180
assert(state != NULL);
175181
if (!PyArg_Parse(key, "s#", &krec.dptr, &tmp_size)) {
@@ -192,10 +198,11 @@ dbm_subscript(dbmobject *dp, PyObject *key)
192198
}
193199

194200
static int
195-
dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w)
201+
dbm_ass_sub(PyObject *self, PyObject *v, PyObject *w)
196202
{
197203
datum krec, drec;
198204
Py_ssize_t tmp_size;
205+
dbmobject *dp = dbmobject_CAST(self);
199206

200207
if ( !PyArg_Parse(v, "s#", &krec.dptr, &tmp_size) ) {
201208
PyErr_SetString(PyExc_TypeError,
@@ -305,7 +312,7 @@ _dbm_dbm_keys_impl(dbmobject *self, PyTypeObject *cls)
305312
static int
306313
dbm_contains(PyObject *self, PyObject *arg)
307314
{
308-
dbmobject *dp = (dbmobject *)self;
315+
dbmobject *dp = dbmobject_CAST(self);
309316
datum key, val;
310317
Py_ssize_t size;
311318

@@ -452,15 +459,16 @@ _dbm_dbm_clear_impl(dbmobject *self, PyTypeObject *cls)
452459
}
453460

454461
static PyObject *
455-
dbm__enter__(PyObject *self, PyObject *args)
462+
dbm__enter__(PyObject *self, PyObject *Py_UNUSED(dummy))
456463
{
457464
return Py_NewRef(self);
458465
}
459466

460467
static PyObject *
461-
dbm__exit__(PyObject *self, PyObject *args)
468+
dbm__exit__(PyObject *self, PyObject *Py_UNUSED(args))
462469
{
463-
return _dbm_dbm_close_impl((dbmobject *)self);
470+
dbmobject *dp = dbmobject_CAST(self);
471+
return _dbm_dbm_close_impl(dp);
464472
}
465473

466474
static PyMethodDef dbm_methods[] = {
@@ -610,7 +618,7 @@ _dbm_module_clear(PyObject *module)
610618
static void
611619
_dbm_module_free(void *module)
612620
{
613-
_dbm_module_clear((PyObject *)module);
621+
(void)_dbm_module_clear((PyObject *)module);
614622
}
615623

616624
static PyModuleDef_Slot _dbmmodule_slots[] = {

0 commit comments

Comments
 (0)