diff options
-rw-r--r-- | coverage/tracer.c | 18 | ||||
-rw-r--r-- | tests/test_concurrency.py | 18 |
2 files changed, 33 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); diff --git a/tests/test_concurrency.py b/tests/test_concurrency.py index 5ea756f6..6fbac4a6 100644 --- a/tests/test_concurrency.py +++ b/tests/test_concurrency.py @@ -201,6 +201,24 @@ class ConcurrencyTest(CoverageTest): def test_greenlet_simple_code(self): self.try_some_code(self.SIMPLE, "greenlet", greenlet) + def test_bug_330(self): + BUG_330 = """\ + from weakref import WeakKeyDictionary + import eventlet + + def do(): + eventlet.sleep(.01) + + gts = WeakKeyDictionary() + for _ in range(100): + gts[eventlet.spawn(do)] = True + eventlet.sleep(.005) + + eventlet.sleep(.1) + print len(gts) + """ + self.try_some_code(BUG_330, "eventlet", eventlet, "0\n") + def print_simple_annotation(code, linenos): """Print the lines in `code` with X for each line number in `linenos`.""" |