2 answers

In my previous answer, i guessed that the problem comes from cython, that does not handle the Python signal correctly, as if it runs too fast to hear it ;) Here is a workaround: the timetout() function should operate at a lower level. We will launch the computation as a new process, and kill the process after timeout_duration. The kill signal is not sent at the Python level, but at the kernel level.

To compute a function in a separate process, Sage has a @fork decorator, here is how to use it in your framework:

The first reason why this does not work is that the expression factor(Primes().next(2^400)*Primes().next(2^500)) is an object of the class sage.structure.factorization_integer.IntegerFactorization, but not a function. Hence, if you send this expression to the timeout() function, it will be computed before being sent to the timeout() function, which won't kill the computation.
Hence, you will experience the same problem as if you did:

Comments

Thanks for the investigation. I guess I prefer to avoid the notebook for now, since it adds a level of complexity while tracking the problem. As I mentioned loop forever can be killed in a sage session in the terminal in contrast to the factor() function. In reality the call to factor is never made directly from the timeout() but through another function that calls factor() and is itself passed to the timeout()

I proposed to use the notebook to ease the use of the `%cython` markup (not available in the Sage command line), see [this page](http://www.sagemath.org/doc/developer/coding_in_cython.html#writing-cython-code-in-sage). You can reproduce the investigation completely from the Sage command line by doing the following:
Create a file named `/tmp/loop.spyx` and add the following content to it:
def loop_forever():
import time
while True:
time.sleep(1)
return 1;
Then in the Sage command line, do
sage: %attach /tmp/loop.spyx
Compiling /tmp/loop.spyx...
and do your test. You will see that `timeout(loop_forever)` will not stop either !