diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in
index 8e66576b5c5f00..95409d48c0da02 100644
--- a/Modules/Setup.stdlib.in
+++ b/Modules/Setup.stdlib.in
@@ -169,7 +169,7 @@
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c
-@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c _testcapi/getargs.c _testcapi/pytime.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyos.c _testcapi/immortal.c _testcapi/heaptype_relative.c
+@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c _testcapi/getargs.c _testcapi/pytime.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c _testcapi/buffer.c _testcapi/pyos.c _testcapi/immortal.c _testcapi/heaptype_relative.c _testcapi/gc.c
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c
# Some testing modules MUST be built as shared libraries.
diff --git a/Modules/_testcapi/gc.c b/Modules/_testcapi/gc.c
new file mode 100644
index 00000000000000..829200ad12cd3c
--- /dev/null
+++ b/Modules/_testcapi/gc.c
@@ -0,0 +1,344 @@
+#include "parts.h"
+
+static PyObject*
+test_gc_control(PyObject *self, PyObject *Py_UNUSED(ignored))
+{
+ int orig_enabled = PyGC_IsEnabled();
+ const char* msg = "ok";
+ int old_state;
+
+ old_state = PyGC_Enable();
+ msg = "Enable(1)";
+ if (old_state != orig_enabled) {
+ goto failed;
+ }
+ msg = "IsEnabled(1)";
+ if (!PyGC_IsEnabled()) {
+ goto failed;
+ }
+
+ old_state = PyGC_Disable();
+ msg = "disable(2)";
+ if (!old_state) {
+ goto failed;
+ }
+ msg = "IsEnabled(2)";
+ if (PyGC_IsEnabled()) {
+ goto failed;
+ }
+
+ old_state = PyGC_Enable();
+ msg = "enable(3)";
+ if (old_state) {
+ goto failed;
+ }
+ msg = "IsEnabled(3)";
+ if (!PyGC_IsEnabled()) {
+ goto failed;
+ }
+
+ if (!orig_enabled) {
+ old_state = PyGC_Disable();
+ msg = "disable(4)";
+ if (old_state) {
+ goto failed;
+ }
+ msg = "IsEnabled(4)";
+ if (PyGC_IsEnabled()) {
+ goto failed;
+ }
+ }
+
+ Py_RETURN_NONE;
+
+failed:
+ /* Try to clean up if we can. */
+ if (orig_enabled) {
+ PyGC_Enable();
+ } else {
+ PyGC_Disable();
+ }
+ PyErr_Format(PyExc_ValueError, "GC control failed in %s", msg);
+ return NULL;
+}
+
+static PyObject *
+without_gc(PyObject *Py_UNUSED(self), PyObject *obj)
+{
+ PyTypeObject *tp = (PyTypeObject*)obj;
+ if (!PyType_Check(obj) || !PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) {
+ return PyErr_Format(PyExc_TypeError, "heap type expected, got %R", obj);
+ }
+ if (PyType_IS_GC(tp)) {
+ // Don't try this at home, kids:
+ tp->tp_flags -= Py_TPFLAGS_HAVE_GC;
+ tp->tp_free = PyObject_Del;
+ tp->tp_traverse = NULL;
+ tp->tp_clear = NULL;
+ }
+ assert(!PyType_IS_GC(tp));
+ return Py_NewRef(obj);
+}
+
+static void
+slot_tp_del(PyObject *self)
+{
+ PyObject *del, *res;
+
+ /* Temporarily resurrect the object. */
+ assert(Py_REFCNT(self) == 0);
+ Py_SET_REFCNT(self, 1);
+
+ /* Save the current exception, if any. */
+ PyObject *exc = PyErr_GetRaisedException();
+
+ PyObject *tp_del = PyUnicode_InternFromString("__tp_del__");
+ if (tp_del == NULL) {
+ PyErr_WriteUnraisable(NULL);
+ PyErr_SetRaisedException(exc);
+ return;
+ }
+ /* Execute __del__ method, if any. */
+ del = _PyType_Lookup(Py_TYPE(self), tp_del);
+ Py_DECREF(tp_del);
+ if (del != NULL) {
+ res = PyObject_CallOneArg(del, self);
+ if (res == NULL)
+ PyErr_WriteUnraisable(del);
+ else
+ Py_DECREF(res);
+ }
+
+ /* Restore the saved exception. */
+ PyErr_SetRaisedException(exc);
+
+ /* Undo the temporary resurrection; can't use DECREF here, it would
+ * cause a recursive call.
+ */
+ assert(Py_REFCNT(self) > 0);
+ Py_SET_REFCNT(self, Py_REFCNT(self) - 1);
+ if (Py_REFCNT(self) == 0) {
+ /* this is the normal path out */
+ return;
+ }
+
+ /* __del__ resurrected it! Make it look like the original Py_DECREF
+ * never happened.
+ */
+ {
+ Py_ssize_t refcnt = Py_REFCNT(self);
+ _Py_NewReferenceNoTotal(self);
+ Py_SET_REFCNT(self, refcnt);
+ }
+ assert(!PyType_IS_GC(Py_TYPE(self)) || PyObject_GC_IsTracked(self));
+}
+
+static PyObject *
+with_tp_del(PyObject *self, PyObject *args)
+{
+ PyObject *obj;
+ PyTypeObject *tp;
+
+ if (!PyArg_ParseTuple(args, "O:with_tp_del", &obj))
+ return NULL;
+ tp = (PyTypeObject *) obj;
+ if (!PyType_Check(obj) || !PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) {
+ PyErr_Format(PyExc_TypeError,
+ "heap type expected, got %R", obj);
+ return NULL;
+ }
+ tp->tp_del = slot_tp_del;
+ return Py_NewRef(obj);
+}
+
+
+struct gc_visit_state_basic {
+ PyObject *target;
+ int found;
+};
+
+static int
+gc_visit_callback_basic(PyObject *obj, void *arg)
+{
+ struct gc_visit_state_basic *state = (struct gc_visit_state_basic *)arg;
+ if (obj == state->target) {
+ state->found = 1;
+ return 0;
+ }
+ return 1;
+}
+
+static PyObject *
+test_gc_visit_objects_basic(PyObject *Py_UNUSED(self),
+ PyObject *Py_UNUSED(ignored))
+{
+ PyObject *obj;
+ struct gc_visit_state_basic state;
+
+ obj = PyList_New(0);
+ if (obj == NULL) {
+ return NULL;
+ }
+ state.target = obj;
+ state.found = 0;
+
+ PyUnstable_GC_VisitObjects(gc_visit_callback_basic, &state);
+ Py_DECREF(obj);
+ if (!state.found) {
+ PyErr_SetString(
+ PyExc_AssertionError,
+ "test_gc_visit_objects_basic: Didn't find live list");
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static int
+gc_visit_callback_exit_early(PyObject *obj, void *arg)
+ {
+ int *visited_i = (int *)arg;
+ (*visited_i)++;
+ if (*visited_i == 2) {
+ return 0;
+ }
+ return 1;
+}
+
+static PyObject *
+test_gc_visit_objects_exit_early(PyObject *Py_UNUSED(self),
+ PyObject *Py_UNUSED(ignored))
+{
+ int visited_i = 0;
+ PyUnstable_GC_VisitObjects(gc_visit_callback_exit_early, &visited_i);
+ if (visited_i != 2) {
+ PyErr_SetString(
+ PyExc_AssertionError,
+ "test_gc_visit_objects_exit_early: did not exit when expected");
+ }
+ Py_RETURN_NONE;
+}
+
+typedef struct {
+ PyObject_HEAD
+} ObjExtraData;
+
+static PyObject *
+obj_extra_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ size_t extra_size = sizeof(PyObject *);
+ PyObject *obj = PyUnstable_Object_GC_NewWithExtraData(type, extra_size);
+ if (obj == NULL) {
+ return PyErr_NoMemory();
+ }
+ PyObject_GC_Track(obj);
+ return obj;
+}
+
+static PyObject **
+obj_extra_data_get_extra_storage(PyObject *self)
+{
+ return (PyObject **)((char *)self + Py_TYPE(self)->tp_basicsize);
+}
+
+static PyObject *
+obj_extra_data_get(PyObject *self, void *Py_UNUSED(ignored))
+{
+ PyObject **extra_storage = obj_extra_data_get_extra_storage(self);
+ PyObject *value = *extra_storage;
+ if (!value) {
+ Py_RETURN_NONE;
+ }
+ return Py_NewRef(value);
+}
+
+static int
+obj_extra_data_set(PyObject *self, PyObject *newval, void *Py_UNUSED(ignored))
+{
+ PyObject **extra_storage = obj_extra_data_get_extra_storage(self);
+ Py_CLEAR(*extra_storage);
+ if (newval) {
+ *extra_storage = Py_NewRef(newval);
+ }
+ return 0;
+}
+
+static PyGetSetDef obj_extra_data_getset[] = {
+ {"extra", (getter)obj_extra_data_get, (setter)obj_extra_data_set, NULL},
+ {NULL}
+};
+
+static int
+obj_extra_data_traverse(PyObject *self, visitproc visit, void *arg)
+{
+ PyObject **extra_storage = obj_extra_data_get_extra_storage(self);
+ PyObject *value = *extra_storage;
+ Py_VISIT(value);
+ return 0;
+}
+
+static int
+obj_extra_data_clear(PyObject *self)
+{
+ PyObject **extra_storage = obj_extra_data_get_extra_storage(self);
+ Py_CLEAR(*extra_storage);
+ return 0;
+}
+
+static void
+obj_extra_data_dealloc(PyObject *self)
+{
+ PyTypeObject *tp = Py_TYPE(self);
+ PyObject_GC_UnTrack(self);
+ obj_extra_data_clear(self);
+ tp->tp_free(self);
+ Py_DECREF(tp);
+}
+
+static PyType_Slot ObjExtraData_Slots[] = {
+ {Py_tp_getset, obj_extra_data_getset},
+ {Py_tp_dealloc, obj_extra_data_dealloc},
+ {Py_tp_traverse, obj_extra_data_traverse},
+ {Py_tp_clear, obj_extra_data_clear},
+ {Py_tp_new, obj_extra_data_new},
+ {Py_tp_free, PyObject_GC_Del},
+ {0, NULL},
+};
+
+static PyType_Spec ObjExtraData_TypeSpec = {
+ .name = "_testcapi.ObjExtraData",
+ .basicsize = sizeof(ObjExtraData),
+ .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
+ .slots = ObjExtraData_Slots,
+};
+
+static PyMethodDef test_methods[] = {
+ {"test_gc_control", test_gc_control, METH_NOARGS},
+ {"test_gc_visit_objects_basic", test_gc_visit_objects_basic, METH_NOARGS, NULL},
+ {"test_gc_visit_objects_exit_early", test_gc_visit_objects_exit_early, METH_NOARGS, NULL},
+ {"without_gc", without_gc, METH_O, NULL},
+ {"with_tp_del", with_tp_del, METH_VARARGS, NULL},
+ {NULL}
+};
+
+int _PyTestCapi_Init_GC(PyObject *mod)
+{
+ if (PyModule_AddFunctions(mod, test_methods) < 0) {
+ return -1;
+ }
+ if (PyModule_AddFunctions(mod, test_methods) < 0) {
+ return -1;
+ }
+
+ PyObject *ObjExtraData_Type = PyType_FromModuleAndSpec(
+ mod, &ObjExtraData_TypeSpec, NULL);
+ if (ObjExtraData_Type == 0) {
+ return -1;
+ }
+ int ret = PyModule_AddType(mod, (PyTypeObject*)ObjExtraData_Type);
+ Py_DECREF(ObjExtraData_Type);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h
index 663d4f2255de88..d1991ac6b464f2 100644
--- a/Modules/_testcapi/parts.h
+++ b/Modules/_testcapi/parts.h
@@ -41,6 +41,7 @@ int _PyTestCapi_Init_Code(PyObject *module);
int _PyTestCapi_Init_Buffer(PyObject *module);
int _PyTestCapi_Init_PyOS(PyObject *module);
int _PyTestCapi_Init_Immortal(PyObject *module);
+int _PyTestCapi_Init_GC(PyObject *mod);
#ifdef LIMITED_API_AVAILABLE
int _PyTestCapi_Init_VectorcallLimited(PyObject *module);
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 79ab7d3f5555c2..c29d29c4791134 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -154,68 +154,6 @@ test_sizeof_c_types(PyObject *self, PyObject *Py_UNUSED(ignored))
#endif
}
-static PyObject*
-test_gc_control(PyObject *self, PyObject *Py_UNUSED(ignored))
-{
- int orig_enabled = PyGC_IsEnabled();
- const char* msg = "ok";
- int old_state;
-
- old_state = PyGC_Enable();
- msg = "Enable(1)";
- if (old_state != orig_enabled) {
- goto failed;
- }
- msg = "IsEnabled(1)";
- if (!PyGC_IsEnabled()) {
- goto failed;
- }
-
- old_state = PyGC_Disable();
- msg = "disable(2)";
- if (!old_state) {
- goto failed;
- }
- msg = "IsEnabled(2)";
- if (PyGC_IsEnabled()) {
- goto failed;
- }
-
- old_state = PyGC_Enable();
- msg = "enable(3)";
- if (old_state) {
- goto failed;
- }
- msg = "IsEnabled(3)";
- if (!PyGC_IsEnabled()) {
- goto failed;
- }
-
- if (!orig_enabled) {
- old_state = PyGC_Disable();
- msg = "disable(4)";
- if (old_state) {
- goto failed;
- }
- msg = "IsEnabled(4)";
- if (PyGC_IsEnabled()) {
- goto failed;
- }
- }
-
- Py_RETURN_NONE;
-
-failed:
- /* Try to clean up if we can. */
- if (orig_enabled) {
- PyGC_Enable();
- } else {
- PyGC_Disable();
- }
- PyErr_Format(TestError, "GC control failed in %s", msg);
- return NULL;
-}
-
static PyObject*
test_list_api(PyObject *self, PyObject *Py_UNUSED(ignored))
{
@@ -1627,95 +1565,6 @@ restore_crossinterp_data(PyObject *self, PyObject *args)
return _PyCrossInterpreterData_NewObject(data);
}
-static void
-slot_tp_del(PyObject *self)
-{
- PyObject *del, *res;
-
- /* Temporarily resurrect the object. */
- assert(Py_REFCNT(self) == 0);
- Py_SET_REFCNT(self, 1);
-
- /* Save the current exception, if any. */
- PyObject *exc = PyErr_GetRaisedException();
-
- PyObject *tp_del = PyUnicode_InternFromString("__tp_del__");
- if (tp_del == NULL) {
- PyErr_WriteUnraisable(NULL);
- PyErr_SetRaisedException(exc);
- return;
- }
- /* Execute __del__ method, if any. */
- del = _PyType_Lookup(Py_TYPE(self), tp_del);
- Py_DECREF(tp_del);
- if (del != NULL) {
- res = PyObject_CallOneArg(del, self);
- if (res == NULL)
- PyErr_WriteUnraisable(del);
- else
- Py_DECREF(res);
- }
-
- /* Restore the saved exception. */
- PyErr_SetRaisedException(exc);
-
- /* Undo the temporary resurrection; can't use DECREF here, it would
- * cause a recursive call.
- */
- assert(Py_REFCNT(self) > 0);
- Py_SET_REFCNT(self, Py_REFCNT(self) - 1);
- if (Py_REFCNT(self) == 0) {
- /* this is the normal path out */
- return;
- }
-
- /* __del__ resurrected it! Make it look like the original Py_DECREF
- * never happened.
- */
- {
- Py_ssize_t refcnt = Py_REFCNT(self);
- _Py_NewReferenceNoTotal(self);
- Py_SET_REFCNT(self, refcnt);
- }
- assert(!PyType_IS_GC(Py_TYPE(self)) || PyObject_GC_IsTracked(self));
-}
-
-static PyObject *
-with_tp_del(PyObject *self, PyObject *args)
-{
- PyObject *obj;
- PyTypeObject *tp;
-
- if (!PyArg_ParseTuple(args, "O:with_tp_del", &obj))
- return NULL;
- tp = (PyTypeObject *) obj;
- if (!PyType_Check(obj) || !PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) {
- PyErr_Format(PyExc_TypeError,
- "heap type expected, got %R", obj);
- return NULL;
- }
- tp->tp_del = slot_tp_del;
- return Py_NewRef(obj);
-}
-
-static PyObject *
-without_gc(PyObject *Py_UNUSED(self), PyObject *obj)
-{
- PyTypeObject *tp = (PyTypeObject*)obj;
- if (!PyType_Check(obj) || !PyType_HasFeature(tp, Py_TPFLAGS_HEAPTYPE)) {
- return PyErr_Format(PyExc_TypeError, "heap type expected, got %R", obj);
- }
- if (PyType_IS_GC(tp)) {
- // Don't try this at home, kids:
- tp->tp_flags -= Py_TPFLAGS_HAVE_GC;
- tp->tp_free = PyObject_Del;
- tp->tp_traverse = NULL;
- tp->tp_clear = NULL;
- }
- assert(!PyType_IS_GC(tp));
- return Py_NewRef(obj);
-}
-
static PyMethodDef ml;
static PyObject *
@@ -3342,165 +3191,6 @@ function_set_kw_defaults(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
-struct gc_visit_state_basic {
- PyObject *target;
- int found;
-};
-
-static int
-gc_visit_callback_basic(PyObject *obj, void *arg)
-{
- struct gc_visit_state_basic *state = (struct gc_visit_state_basic *)arg;
- if (obj == state->target) {
- state->found = 1;
- return 0;
- }
- return 1;
-}
-
-static PyObject *
-test_gc_visit_objects_basic(PyObject *Py_UNUSED(self),
- PyObject *Py_UNUSED(ignored))
-{
- PyObject *obj;
- struct gc_visit_state_basic state;
-
- obj = PyList_New(0);
- if (obj == NULL) {
- return NULL;
- }
- state.target = obj;
- state.found = 0;
-
- PyUnstable_GC_VisitObjects(gc_visit_callback_basic, &state);
- Py_DECREF(obj);
- if (!state.found) {
- PyErr_SetString(
- PyExc_AssertionError,
- "test_gc_visit_objects_basic: Didn't find live list");
- return NULL;
- }
- Py_RETURN_NONE;
-}
-
-static int
-gc_visit_callback_exit_early(PyObject *obj, void *arg)
- {
- int *visited_i = (int *)arg;
- (*visited_i)++;
- if (*visited_i == 2) {
- return 0;
- }
- return 1;
-}
-
-static PyObject *
-test_gc_visit_objects_exit_early(PyObject *Py_UNUSED(self),
- PyObject *Py_UNUSED(ignored))
-{
- int visited_i = 0;
- PyUnstable_GC_VisitObjects(gc_visit_callback_exit_early, &visited_i);
- if (visited_i != 2) {
- PyErr_SetString(
- PyExc_AssertionError,
- "test_gc_visit_objects_exit_early: did not exit when expected");
- }
- Py_RETURN_NONE;
-}
-
-typedef struct {
- PyObject_HEAD
-} ObjExtraData;
-
-static PyObject *
-obj_extra_data_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- size_t extra_size = sizeof(PyObject *);
- PyObject *obj = PyUnstable_Object_GC_NewWithExtraData(type, extra_size);
- if (obj == NULL) {
- return PyErr_NoMemory();
- }
- PyObject_GC_Track(obj);
- return obj;
-}
-
-static PyObject **
-obj_extra_data_get_extra_storage(PyObject *self)
-{
- return (PyObject **)((char *)self + Py_TYPE(self)->tp_basicsize);
-}
-
-static PyObject *
-obj_extra_data_get(PyObject *self, void *Py_UNUSED(ignored))
-{
- PyObject **extra_storage = obj_extra_data_get_extra_storage(self);
- PyObject *value = *extra_storage;
- if (!value) {
- Py_RETURN_NONE;
- }
- return Py_NewRef(value);
-}
-
-static int
-obj_extra_data_set(PyObject *self, PyObject *newval, void *Py_UNUSED(ignored))
-{
- PyObject **extra_storage = obj_extra_data_get_extra_storage(self);
- Py_CLEAR(*extra_storage);
- if (newval) {
- *extra_storage = Py_NewRef(newval);
- }
- return 0;
-}
-
-static PyGetSetDef obj_extra_data_getset[] = {
- {"extra", (getter)obj_extra_data_get, (setter)obj_extra_data_set, NULL},
- {NULL}
-};
-
-static int
-obj_extra_data_traverse(PyObject *self, visitproc visit, void *arg)
-{
- PyObject **extra_storage = obj_extra_data_get_extra_storage(self);
- PyObject *value = *extra_storage;
- Py_VISIT(value);
- return 0;
-}
-
-static int
-obj_extra_data_clear(PyObject *self)
-{
- PyObject **extra_storage = obj_extra_data_get_extra_storage(self);
- Py_CLEAR(*extra_storage);
- return 0;
-}
-
-static void
-obj_extra_data_dealloc(PyObject *self)
-{
- PyTypeObject *tp = Py_TYPE(self);
- PyObject_GC_UnTrack(self);
- obj_extra_data_clear(self);
- tp->tp_free(self);
- Py_DECREF(tp);
-}
-
-static PyType_Slot ObjExtraData_Slots[] = {
- {Py_tp_getset, obj_extra_data_getset},
- {Py_tp_dealloc, obj_extra_data_dealloc},
- {Py_tp_traverse, obj_extra_data_traverse},
- {Py_tp_clear, obj_extra_data_clear},
- {Py_tp_new, obj_extra_data_new},
- {Py_tp_free, PyObject_GC_Del},
- {0, NULL},
-};
-
-static PyType_Spec ObjExtraData_TypeSpec = {
- .name = "_testcapi.ObjExtraData",
- .basicsize = sizeof(ObjExtraData),
- .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
- .slots = ObjExtraData_Slots,
-};
-
struct atexit_data {
int called;
};
@@ -3538,7 +3228,6 @@ static PyMethodDef TestMethods[] = {
{"set_errno", set_errno, METH_VARARGS},
{"test_config", test_config, METH_NOARGS},
{"test_sizeof_c_types", test_sizeof_c_types, METH_NOARGS},
- {"test_gc_control", test_gc_control, METH_NOARGS},
{"test_list_api", test_list_api, METH_NOARGS},
{"test_dict_iteration", test_dict_iteration, METH_NOARGS},
{"dict_getitem_knownhash", dict_getitem_knownhash, METH_VARARGS},
@@ -3590,7 +3279,6 @@ static PyMethodDef TestMethods[] = {
METH_VARARGS | METH_KEYWORDS},
{"get_crossinterp_data", get_crossinterp_data, METH_VARARGS},
{"restore_crossinterp_data", restore_crossinterp_data, METH_VARARGS},
- {"with_tp_del", with_tp_del, METH_VARARGS},
{"create_cfunction", create_cfunction, METH_NOARGS},
{"call_in_temporary_c_thread", call_in_temporary_c_thread, METH_VARARGS,
PyDoc_STR("set_error_class(error_class) -> None")},
@@ -3641,7 +3329,6 @@ static PyMethodDef TestMethods[] = {
{"meth_fastcall", _PyCFunction_CAST(meth_fastcall), METH_FASTCALL},
{"meth_fastcall_keywords", _PyCFunction_CAST(meth_fastcall_keywords), METH_FASTCALL|METH_KEYWORDS},
{"pynumber_tobase", pynumber_tobase, METH_VARARGS},
- {"without_gc", without_gc, METH_O},
{"test_set_type_size", test_set_type_size, METH_NOARGS},
{"test_py_clear", test_py_clear, METH_NOARGS},
{"test_py_setref", test_py_setref, METH_NOARGS},
@@ -3675,8 +3362,6 @@ static PyMethodDef TestMethods[] = {
{"function_set_defaults", function_set_defaults, METH_VARARGS, NULL},
{"function_get_kw_defaults", function_get_kw_defaults, METH_O, NULL},
{"function_set_kw_defaults", function_set_kw_defaults, METH_VARARGS, NULL},
- {"test_gc_visit_objects_basic", test_gc_visit_objects_basic, METH_NOARGS, NULL},
- {"test_gc_visit_objects_exit_early", test_gc_visit_objects_exit_early, METH_NOARGS, NULL},
{"test_atexit", test_atexit, METH_NOARGS},
{NULL, NULL} /* sentinel */
};
@@ -4223,17 +3908,6 @@ PyInit__testcapi(void)
Py_INCREF(&MethStatic_Type);
PyModule_AddObject(m, "MethStatic", (PyObject *)&MethStatic_Type);
- PyObject *ObjExtraData_Type = PyType_FromModuleAndSpec(
- m, &ObjExtraData_TypeSpec, NULL);
- if (ObjExtraData_Type == 0) {
- return NULL;
- }
- int ret = PyModule_AddType(m, (PyTypeObject*)ObjExtraData_Type);
- Py_DECREF(ObjExtraData_Type);
- if (ret < 0) {
- return NULL;
- }
-
PyModule_AddObject(m, "CHAR_MAX", PyLong_FromLong(CHAR_MAX));
PyModule_AddObject(m, "CHAR_MIN", PyLong_FromLong(CHAR_MIN));
PyModule_AddObject(m, "UCHAR_MAX", PyLong_FromLong(UCHAR_MAX));
@@ -4327,6 +4001,9 @@ PyInit__testcapi(void)
if (_PyTestCapi_Init_Immortal(m) < 0) {
return NULL;
}
+ if (_PyTestCapi_Init_GC(m) < 0) {
+ return NULL;
+ }
#ifndef LIMITED_API_AVAILABLE
PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_False);
diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj
index 350f97f8ff41aa..3db9426d1a25ff 100644
--- a/PCbuild/_testcapi.vcxproj
+++ b/PCbuild/_testcapi.vcxproj
@@ -113,6 +113,7 @@
+
diff --git a/PCbuild/_testcapi.vcxproj.filters b/PCbuild/_testcapi.vcxproj.filters
index af80f1eebb3c4d..8df4874659fa1c 100644
--- a/PCbuild/_testcapi.vcxproj.filters
+++ b/PCbuild/_testcapi.vcxproj.filters
@@ -66,6 +66,9 @@
Source Files
+
+ Source Files
+