diff -r f35b3a86ade3 Modules/gcmodule.c --- a/Modules/gcmodule.c Tue Jan 14 16:48:31 2014 -0600 +++ b/Modules/gcmodule.c Wed Jan 15 15:10:02 2014 +0800 @@ -228,6 +228,11 @@ #define IS_TENTATIVELY_UNREACHABLE(o) ( \ _PyGC_REFS(o) == GC_TENTATIVELY_UNREACHABLE) +/*[clinic input] +module gc +[clinic start generated code]*/ +/*[clinic end generated code: checksum=da39a3ee5e6b4b0d3255bfef95601890afd80709]*/ + /*** list functions ***/ static void @@ -1192,25 +1197,57 @@ return PyBool_FromLong((long)enabled); } +/*[clinic input] +gc.collect + + generation: int(c_default="NUM_GENERATIONS - 1") = 2 + +With no arguments, run a full collection. + +The optional argument may be an integer specifying which generation to collect. +A ValueError is raised if the generation number is invalid. The number of +unreachable objects is returned. + +[clinic start generated code]*/ + PyDoc_STRVAR(gc_collect__doc__, -"collect([generation]) -> n\n" +"collect(generation=2)\n" +"With no arguments, run a full collection.\n" "\n" -"With no arguments, run a full collection. The optional argument\n" -"may be an integer specifying which generation to collect. A ValueError\n" -"is raised if the generation number is invalid.\n\n" -"The number of unreachable objects is returned.\n"); +"The optional argument may be an integer specifying which generation to collect.\n" +"A ValueError is raised if the generation number is invalid. The number of\n" +"unreachable objects is returned."); + +#define GC_COLLECT_METHODDEF \ + {"collect", (PyCFunction)gc_collect, METH_VARARGS|METH_KEYWORDS, gc_collect__doc__}, static PyObject * -gc_collect(PyObject *self, PyObject *args, PyObject *kws) +gc_collect_impl(PyModuleDef *module, int generation); + +static PyObject * +gc_collect(PyModuleDef *module, PyObject *args, PyObject *kwargs) { - static char *keywords[] = {"generation", NULL}; - int genarg = NUM_GENERATIONS - 1; + PyObject *return_value = NULL; + static char *_keywords[] = {"generation", NULL}; + int generation = NUM_GENERATIONS - 1; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, + "|i:collect", _keywords, + &generation)) + goto exit; + return_value = gc_collect_impl(module, generation); + +exit: + return return_value; +} + +static PyObject * +gc_collect_impl(PyModuleDef *module, int generation) +/*[clinic end generated code: checksum=2c1e4e801c6c95d682b2b6e6badf9b78d6d107e2]*/ +{ Py_ssize_t n; - if (!PyArg_ParseTupleAndKeywords(args, kws, "|i", keywords, &genarg)) - return NULL; - - else if (genarg < 0 || genarg >= NUM_GENERATIONS) { + if (generation < 0 || generation >= NUM_GENERATIONS) { PyErr_SetString(PyExc_ValueError, "invalid generation"); return NULL; } @@ -1219,32 +1256,72 @@ n = 0; /* already collecting, don't do anything */ else { collecting = 1; - n = collect_with_callback(genarg); + n = collect_with_callback(generation); collecting = 0; } return PyLong_FromSsize_t(n); } +/*[clinic input] +gc.set_debug + + flags: int + / + +Set the garbage collection debugging flags. + +Debugging information is written to sys.stderr. flags is an integer and can +have the following bits turned on: + + DEBUG_STATS - Print statistics during collection. + DEBUG_COLLECTABLE - Print collectable objects found. + DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects found. + DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them. + DEBUG_LEAK - Debug leaking programs (everything but STATS). + +[clinic start generated code]*/ + PyDoc_STRVAR(gc_set_debug__doc__, -"set_debug(flags) -> None\n" +"set_debug(flags)\n" +"Set the garbage collection debugging flags.\n" "\n" -"Set the garbage collection debugging flags. Debugging information is\n" -"written to sys.stderr.\n" -"\n" -"flags is an integer and can have the following bits turned on:\n" +"Debugging information is written to sys.stderr. flags is an integer and can\n" +"have the following bits turned on:\n" "\n" " DEBUG_STATS - Print statistics during collection.\n" " DEBUG_COLLECTABLE - Print collectable objects found.\n" " DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects found.\n" " DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them.\n" -" DEBUG_LEAK - Debug leaking programs (everything but STATS).\n"); +" DEBUG_LEAK - Debug leaking programs (everything but STATS)."); + +#define GC_SET_DEBUG_METHODDEF \ + {"set_debug", (PyCFunction)gc_set_debug, METH_VARARGS, gc_set_debug__doc__}, static PyObject * -gc_set_debug(PyObject *self, PyObject *args) +gc_set_debug_impl(PyModuleDef *module, int flags); + +static PyObject * +gc_set_debug(PyModuleDef *module, PyObject *args) { - if (!PyArg_ParseTuple(args, "i:set_debug", &debug)) - return NULL; + PyObject *return_value = NULL; + int flags; + + if (!PyArg_ParseTuple(args, + "i:set_debug", + &flags)) + goto exit; + return_value = gc_set_debug_impl(module, flags); + +exit: + return return_value; +} + +static PyObject * +gc_set_debug_impl(PyModuleDef *module, int flags) +/*[clinic end generated code: checksum=afce9056ed53a0c9ab8a9542462276ed61082fcd]*/ +{ + debug = flags; Py_INCREF(Py_None); return Py_None; @@ -1261,21 +1338,81 @@ return Py_BuildValue("i", debug); } -PyDoc_STRVAR(gc_set_thresh__doc__, -"set_threshold(threshold0, [threshold1, threshold2]) -> None\n" +/*[clinic input] +gc.set_threshold + + threshold0: int + [ + threshold1: int + [ + threshold2: int + ] + ] + / + +Sets the collection thresholds. + +Setting threshold0 to zero disables collection. + +[clinic start generated code]*/ + +PyDoc_STRVAR(gc_set_threshold__doc__, +"set_threshold(threshold0, [threshold1, [threshold2]])\n" +"Sets the collection thresholds.\n" "\n" -"Sets the collection thresholds. Setting threshold0 to zero disables\n" -"collection.\n"); +"Setting threshold0 to zero disables collection."); + +#define GC_SET_THRESHOLD_METHODDEF \ + {"set_threshold", (PyCFunction)gc_set_threshold, METH_VARARGS, gc_set_threshold__doc__}, static PyObject * -gc_set_thresh(PyObject *self, PyObject *args) +gc_set_threshold_impl(PyModuleDef *module, int threshold0, int group_right_1, int threshold1, int group_right_2, int threshold2); + +static PyObject * +gc_set_threshold(PyModuleDef *module, PyObject *args) +{ + PyObject *return_value = NULL; + int threshold0; + int group_right_1 = 0; + int threshold1 = 0; + int group_right_2 = 0; + int threshold2 = 0; + + switch (PyTuple_Size(args)) { + case 1: + if (!PyArg_ParseTuple(args, "i:set_threshold", &threshold0)) + return NULL; + break; + case 2: + if (!PyArg_ParseTuple(args, "ii:set_threshold", &threshold0, &threshold1)) + return NULL; + group_right_1 = 1; + break; + case 3: + if (!PyArg_ParseTuple(args, "iii:set_threshold", &threshold0, &threshold1, &threshold2)) + return NULL; + group_right_1 = 1; + group_right_2 = 1; + break; + default: + PyErr_SetString(PyExc_TypeError, "gc.set_threshold requires 1 to 3 arguments"); + return NULL; + } + return_value = gc_set_threshold_impl(module, threshold0, group_right_1, threshold1, group_right_2, threshold2); + + return return_value; +} + +static PyObject * +gc_set_threshold_impl(PyModuleDef *module, int threshold0, int group_right_1, int threshold1, int group_right_2, int threshold2) +/*[clinic end generated code: checksum=45832692512184497f99cd8c4b2d4698ce24b8fc]*/ { int i; - if (!PyArg_ParseTuple(args, "i|ii:set_threshold", - &generations[0].threshold, - &generations[1].threshold, - &generations[2].threshold)) - return NULL; + + generations[0].threshold = threshold0; + generations[1].threshold = threshold1; + generations[2].threshold = threshold2; + for (i = 2; i < NUM_GENERATIONS; i++) { /* generations higher than 2 get the same threshold */ generations[i].threshold = generations[2].threshold; @@ -1512,13 +1649,12 @@ {"enable", gc_enable, METH_NOARGS, gc_enable__doc__}, {"disable", gc_disable, METH_NOARGS, gc_disable__doc__}, {"isenabled", gc_isenabled, METH_NOARGS, gc_isenabled__doc__}, - {"set_debug", gc_set_debug, METH_VARARGS, gc_set_debug__doc__}, + GC_SET_DEBUG_METHODDEF {"get_debug", gc_get_debug, METH_NOARGS, gc_get_debug__doc__}, {"get_count", gc_get_count, METH_NOARGS, gc_get_count__doc__}, - {"set_threshold", gc_set_thresh, METH_VARARGS, gc_set_thresh__doc__}, + GC_SET_THRESHOLD_METHODDEF {"get_threshold", gc_get_thresh, METH_NOARGS, gc_get_thresh__doc__}, - {"collect", (PyCFunction)gc_collect, - METH_VARARGS | METH_KEYWORDS, gc_collect__doc__}, + GC_COLLECT_METHODDEF {"get_objects", gc_get_objects,METH_NOARGS, gc_get_objects__doc__}, {"get_stats", gc_get_stats, METH_NOARGS, gc_get_stats__doc__}, {"is_tracked", gc_is_tracked, METH_O, gc_is_tracked__doc__},