8000 bpo-31356: Fix multiple errors in gc.ensure_disabled() · python/cpython@2117784 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2117784

Browse files
committed
bpo-31356: Fix multiple errors in gc.ensure_disabled()
1 parent a29ddf4 commit 2117784

File tree

2 files changed

+34
-17
lines changed

2 files changed

+34
-17
lines changed

Lib/test/test_gc.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,19 +1054,16 @@ def disabling_thread():
10541054

10551055
original_status = gc.isenabled()
10561056

1057-
with warnings.catch_warnings(record=True) as w, gc.ensure_disabled():
1058-
inside_status_before_thread = gc.isenabled()
1059-
thread = threading.Thread(target=disabling_thread)
1060-
thread.start()
1061-
inside_status_after_thread = gc.isenabled()
1057+
with self.assertWarnsRegex(RuntimeWarning, "enabled while another"):
1058+
with gc.ensure_disabled():
1059+
inside_status_before_thread = gc.isenabled()
1060+
thread = threading.Thread(target=disabling_thread)
1061+
thread.start()
1062+
inside_status_after_thread = gc.isenabled()
10621063

10631064
after_status = gc.isenabled()
10641065
thread.join()
10651066

1066-
self.assertEqual(len(w), 1)
1067-
self.assertTrue(issubclass(w[-1].category, RuntimeWarning))
1068-
self.assertEqual("Garbage collector enabled while another thread is "
1069-
"inside gc.ensure_enabled", str(w[-1].message))
10701067
self.assertEqual(original_status, True)
10711068
self.assertEqual(inside_status_before_thread, False)
10721069
self.assertEqual(thread_original_status, False)

Modules/gcmodule.c

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,8 +1068,13 @@ gc_enable_impl(PyObject *module)
10681068
/*[clinic end generated code: output=45a427e9dce9155c input=81ac4940ca579707]*/
10691069
{
10701070
if(_PyRuntime.gc.disabled_threads){
1071-
PyErr_WarnEx(PyExc_RuntimeWarning, "Garbage collector enabled while another "
1072-
"thread is inside gc.ensure_enabled",1);
1071+
if (PyErr_WarnEx(
1072+
PyExc_RuntimeWarning,
1073+
"Garbage collector enabled while another "
1074+
"thread is inside gc.ensure_enabled", 1) < 0)
1075+
{
1076+
return NULL;
1077+
}
10731078
}
10741079
_PyRuntime.gc.enabled = 1;
10751080
Py_RETURN_NONE;
@@ -1530,8 +1535,13 @@ ensure_disabled__enter__method(ensure_disabled_object *self, PyObject *args)
15301535
PyGILState_STATE gstate = PyGILState_Ensure();
15311536
++_PyRuntime.gc.disabled_threads;
15321537
self->previous_gc_state = _PyRuntime.gc.enabled;
1533-
gc_disable_impl(NULL);
1538+
1539+
PyObject *ret = gc_disable_impl(NULL);
15341540
PyGILState_Release(gstate);
1541+
if (ret == NULL) {
1542+
return NULL;
1543+
}
1544+
Py_DECREF(ret);
15351545
Py_RETURN_NONE;
15361546
}
15371547

@@ -1540,12 +1550,19 @@ ensure_disabled__exit__method(ensure_disabled_object *self, PyObject *args)
15401550
{
15411551
PyGILState_STATE gstate = PyGILState_Ensure();
15421552
--_PyRuntime.gc.disabled_threads;
1543-
if(self->previous_gc_state){
1544-
gc_enable_impl(NULL);
1545-
}else{
1546-
gc_disable_impl(NULL);
1553+
1554+
PyObject *ret;
1555+
if (self->previous_gc_state) {
1556+
ret = gc_enable_impl(NULL);
< 8000 /code>1557+
}
1558+
else {
1559+
ret = gc_disable_impl(NULL);
15471560
}
15481561
PyGILState_Release(gstate);
1562+
if (ret == NULL) {
1563+
return NULL;
1564+
}
1565+
Py_DECREF(ret);
15491566
Py_RETURN_NONE;
15501567
}
15511568

@@ -1650,8 +1667,11 @@ PyInit_gc(void)
16501667

16511668
if (PyType_Ready(&gc_ensure_disabled_type) < 0)
16521669
return NULL;
1653-
if (PyModule_AddObject(m, "ensure_disabled", (PyObject*) &gc_ensure_disabled_type) < 0)
1670+
if (PyModule_AddObject(m, "ensure_disabled",
1671+
(PyObject*) &gc_ensure_disabled_type) < 0)
1672+
{
16541673
return NULL;
1674+
}
16551675

16561676

16571677
#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return NULL

0 commit comments

Comments
 (0)
0