Skip to content

Commit d3c38ff

Browse files
committed
SF patch #1443865; gc.get_count() added and optional argument 'generation'
added to gc.collect(). Updated docs, unit test, and NEWS entry. (Also, fixed a typo in NEWS.)
1 parent 995acdf commit d3c38ff

File tree

4 files changed

+69
-9
lines changed

4 files changed

+69
-9
lines changed

Doc/lib/libgc.tex

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,13 @@ \section{\module{gc} ---
3232
Returns true if automatic collection is enabled.
3333
\end{funcdesc}
3434

35-
\begin{funcdesc}{collect}{}
36-
Run a full collection. All generations are examined and the
37-
number of unreachable objects found is returned.
35+
\begin{funcdesc}{collect}{\optional{generation}}
36+
With no arguments, run a full collection. The optional argument
37+
\var{generation} may be an integer specifying which generation to collect
38+
(from 0 to 2). A ValueError is raised if the generation number is invalid.
39+
The number of unreachable objects found is returned.
40+
41+
\versionchanged[The optional \var{generation} argument was added]{2.5}
3842
\end{funcdesc}
3943

4044
\begin{funcdesc}{set_debug}{flags}
@@ -76,6 +80,12 @@ \section{\module{gc} ---
7680
\code{1} before collecting generation \code{2}.
7781
\end{funcdesc}
7882

83+
\begin{funcdesc}{get_count}{}
84+
Return the current collection counts as a tuple of
85+
\code{(\var{count0}, \var{count1}, \var{count2})}.
86+
\versionadded{2.5}
87+
\end{funcdesc}
88+
7989
\begin{funcdesc}{get_threshold}{}
8090
Return the current collection thresholds as a tuple of
8191
\code{(\var{threshold0}, \var{threshold1}, \var{threshold2})}.

Lib/test/test_gc.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,22 @@ def __del__(self):
219219
gc.disable()
220220
gc.set_threshold(*thresholds)
221221

222+
def test_get_count():
223+
gc.collect()
224+
expect(gc.get_count(), (0, 0, 0), "get_count()")
225+
a = dict()
226+
expect(gc.get_count(), (1, 0, 0), "get_count()")
227+
228+
def test_collect_generations():
229+
gc.collect()
230+
a = dict()
231+
gc.collect(0)
232+
expect(gc.get_count(), (0, 1, 0), "collect(0)")
233+
gc.collect(1)
234+
expect(gc.get_count(), (0, 0, 1), "collect(1)")
235+
gc.collect(2)
236+
expect(gc.get_count(), (0, 0, 0), "collect(1)")
237+
222238
class Ouch:
223239
n = 0
224240
def __del__(self):
@@ -571,6 +587,8 @@ def test_all():
571587
run_test("finalizers (new class)", test_finalizer_newclass)
572588
run_test("__del__", test_del)
573589
run_test("__del__ (new class)", test_del_newclass)
590+
run_test("get_count()", test_get_count)
591+
run_test("collect(n)", test_collect_generations)
574592
run_test("saveall", test_saveall)
575593
run_test("trashcan", test_trashcan)
576594
run_test("boom", test_boom)

Misc/NEWS

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ Core and builtins
7878
This was not portable. float('0x3') now raises a ValueError.
7979

8080
- Patch #1382163: Expose Subversion revision number to Python. New C API
81-
function Py_GetBuildNumber(). New attribute sys.build_number. Build number
81+
function Py_GetBuildNumber(). New attribute sys.subversion. Build number
8282
is now displayed in interactive prompt banner.
8383

8484
- Implementation of PEP 341 - Unification of try/except and try/finally.
@@ -427,6 +427,9 @@ Extension Modules
427427
Library
428428
-------
429429

430+
- The function get_count() has been added to the gc module, and gc.collect()
431+
grew an optional 'generation' argument.
432+
430433
- A library msilib to generate Windows Installer files, and a distutils
431434
command bdist_msi have been added.
432435

Modules/gcmodule.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -925,20 +925,33 @@ gc_isenabled(PyObject *self, PyObject *noargs)
925925
}
926926

927927
PyDoc_STRVAR(gc_collect__doc__,
928-
"collect() -> n\n"
928+
"collect([generation]) -> n\n"
929929
"\n"
930-
"Run a full collection. The number of unreachable objects is returned.\n");
930+
"With no arguments, run a full collection. The optional argument\n"
931+
"may be an integer specifying which generation to collect. A ValueError\n"
932+
"is raised if the generation number is invalid.\n\n"
933+
"The number of unreachable objects is returned.\n");
931934

932935
static PyObject *
933-
gc_collect(PyObject *self, PyObject *noargs)
936+
gc_collect(PyObject *self, PyObject *args, PyObject *kws)
934937
{
938+
static char *keywords[] = {"generation", NULL};
939+
int genarg = NUM_GENERATIONS - 1;
935940
Py_ssize_t n;
936941

942+
if (!PyArg_ParseTupleAndKeywords(args, kws, "|i", keywords, &genarg))
943+
return NULL;
944+
945+
else if (genarg < 0 || genarg >= NUM_GENERATIONS) {
946+
PyErr_SetString(PyExc_ValueError, "invalid generation");
947+
return NULL;
948+
}
949+
937950
if (collecting)
938951
n = 0; /* already collecting, don't do anything */
939952
else {
940953
collecting = 1;
941-
n = collect(NUM_GENERATIONS - 1);
954+
n = collect(genarg);
942955
collecting = 0;
943956
}
944957

@@ -1020,6 +1033,20 @@ gc_get_thresh(PyObject *self, PyObject *noargs)
10201033
generations[2].threshold);
10211034
}
10221035

1036+
PyDoc_STRVAR(gc_get_count__doc__,
1037+
"get_count() -> (count0, count1, count2)\n"
1038+
"\n"
1039+
"Return the current collection counts\n");
1040+
1041+
static PyObject *
1042+
gc_get_count(PyObject *self, PyObject *noargs)
1043+
{
1044+
return Py_BuildValue("(iii)",
1045+
generations[0].count,
1046+
generations[1].count,
1047+
generations[2].count);
1048+
}
1049+
10231050
static int
10241051
referrersvisit(PyObject* obj, PyObject *objs)
10251052
{
@@ -1150,9 +1177,11 @@ static PyMethodDef GcMethods[] = {
11501177
{"isenabled", gc_isenabled, METH_NOARGS, gc_isenabled__doc__},
11511178
{"set_debug", gc_set_debug, METH_VARARGS, gc_set_debug__doc__},
11521179
{"get_debug", gc_get_debug, METH_NOARGS, gc_get_debug__doc__},
1180+
{"get_count", gc_get_count, METH_NOARGS, gc_get_count__doc__},
11531181
{"set_threshold", gc_set_thresh, METH_VARARGS, gc_set_thresh__doc__},
11541182
{"get_threshold", gc_get_thresh, METH_NOARGS, gc_get_thresh__doc__},
1155-
{"collect", gc_collect, METH_NOARGS, gc_collect__doc__},
1183+
{"collect", (PyCFunction)gc_collect,
1184+
METH_VARARGS | METH_KEYWORDS, gc_collect__doc__},
11561185
{"get_objects", gc_get_objects,METH_NOARGS, gc_get_objects__doc__},
11571186
{"get_referrers", gc_get_referrers, METH_VARARGS,
11581187
gc_get_referrers__doc__},

0 commit comments

Comments
 (0)