summaryrefslogtreecommitdiff
path: root/coverage/tracer.c
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2014-11-08 18:42:32 -0500
committerNed Batchelder <ned@nedbatchelder.com>2014-11-08 18:42:32 -0500
commit81f5697e7cb2f5a064fd891617c0c8caf5ab21d9 (patch)
treedd15fff5b8c4b75667d66d526312c9ba85f40aa7 /coverage/tracer.c
parent81aa202a558a02b4a2b3d17b4a1764f79a3194e9 (diff)
downloadpython-coveragepy-git-81f5697e7cb2f5a064fd891617c0c8caf5ab21d9.tar.gz
Use a WeakKeyDictionary to track coroutine objects to prevent leaks. Fixes #330.
Diffstat (limited to 'coverage/tracer.c')
-rw-r--r--coverage/tracer.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/coverage/tracer.c b/coverage/tracer.c
index 5a463fcb..79040d07 100644
--- a/coverage/tracer.c
+++ b/coverage/tracer.c
@@ -177,6 +177,8 @@ DataStack_grow(CTracer *self, DataStack *pdata_stack)
static int
CTracer_init(CTracer *self, PyObject *args_unused, PyObject *kwds_unused)
{
+ PyObject * weakref = NULL;
+
#if COLLECT_STATS
self->stats.calls = 0;
self->stats.lines = 0;
@@ -203,7 +205,14 @@ CTracer_init(CTracer *self, PyObject *args_unused, PyObject *kwds_unused)
if (DataStack_init(self, &self->data_stack)) {
return RET_ERROR;
}
- self->data_stack_index = PyDict_New();
+
+ weakref = PyImport_ImportModule("weakref");
+ if (weakref == NULL) {
+ return RET_ERROR;
+ }
+ self->data_stack_index = PyObject_CallMethod(weakref, "WeakKeyDictionary", NULL);
+ Py_XDECREF(weakref);
+
if (self->data_stack_index == NULL) {
STATS( self->stats.errors++; )
return RET_ERROR;
@@ -336,12 +345,15 @@ CTracer_set_pdata_stack(CTracer *self)
if (co_obj == NULL) {
return RET_ERROR;
}
- stack_index = PyDict_GetItem(self->data_stack_index, co_obj);
+ stack_index = PyObject_GetItem(self->data_stack_index, co_obj);
if (stack_index == NULL) {
+ /* PyObject_GetItem sets an exception if it didn't find the thing. */
+ PyErr_Clear();
+
/* A new concurrency object. Make a new data stack. */
the_index = self->data_stacks_used;
stack_index = MyInt_FromLong(the_index);
- if (PyDict_SetItem(self->data_stack_index, co_obj, stack_index) < 0) {
+ if (PyObject_SetItem(self->data_stack_index, co_obj, stack_index) < 0) {
STATS( self->stats.errors++; )
Py_XDECREF(co_obj);
Py_XDECREF(stack_index);