Prompted by Jeff Senn's problems I decided to add a unit test to stackless.
The stackless module already has a test_outside() function which emulates being
called from outside and does a PyStackless_Schedule() call.
The test is as follows:
#test_outside.py
import unittest
import stackless
class TestOutside(unittest.TestCase):
def testOutside1(self):
def null():
pass
stackless.tasklet(null)()
stackless.test_outside()
if __name__ == '__main__':
import sys
if not sys.argv[1:]:
sys.argv.append('-v')
unittest.main()
Now, running this in debug triggers an assertion. After much digging, I found
that it is caused by this code, in PyObject_Call() (which is called by the
cframe executing the "schedule" call.:
if (Py_EnterRecursiveCall(" while calling a Python object"))
return NULL;
result = (STACKLESS_PROMOTE(func), (*call)(func, arg, kw));
STACKLESS_ASSERT();
Py_LeaveRecursiveCall();
The problem is, that once the *call returns, we have softswitched, and so the
Py_LeaveRecursiveCall() is modifying ts->recursion_level belonging to a
different tasklet. In this case the freshly initialized tasklet, and lowering
it to -1.
As expected, this screws up the recursion level accounting and throws an
assertion in debug builds.
I am as of yet unsure as to how I should proceed. It seems as though
PyObject_Call is incompatible with methods that can perform softswitching.
Perhaps we could undo the recursion bookkeeping in this case by decrementing
and incremeting it in run_cframe (line 225), but it seems like a cludge. Any
thoughts?
K
_______________________________________________
Stackless mailing list
[email protected]
http://www.stackless.com/mailman/listinfo/stackless