From 0b7afc7ba9b5c28608431f1f6aa5d92d69ec6f0b Mon Sep 17 00:00:00 2001
From: Phillip Berndt <phillip.berndt@googlemail.com>
Date: Sat, 5 Nov 2016 16:25:16 +0100
Subject: [PATCH] Do not raise an exception if a calculation is interrupted by
 the user

---
 pyradau13.c |  2 +-
 test.py     | 12 ++++++++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/pyradau13.c b/pyradau13.c
index 2b0d2a0..21405b0 100644
--- a/pyradau13.c
+++ b/pyradau13.c
@@ -423,7 +423,7 @@ static PyObject *radau13(PyObject *self, PyObject *args, PyObject *kwargs) {
 	Py_DECREF(abstol_array);
 	if(mass_matrix_array) Py_DECREF(mass_matrix_array);
 
-	if(idid != 1 || y_out == NULL) {
+	if((idid != 1 && (idid != 2 || PyErr_Occurred() != NULL)) || y_out == NULL) {
 		if(PyErr_Occurred() == NULL) {
 			int i;
 			for(i=sizeof(errbuf)-1; i>0 && (errbuf[i] == ' ' || errbuf[i] == '\n' || errbuf[i] == 0 || errbuf[i] == '\t'); i--) {
diff --git a/test.py b/test.py
index 2c84165..388723a 100755
--- a/test.py
+++ b/test.py
@@ -21,6 +21,18 @@ class TestIntegration(unittest.TestCase):
         self.assertRaises(_TestException,
                           lambda: radau13(lambda t, x: 1, 0, 1, dense_callback=_dense_cb))
 
+    def test_intentional_abort(self):
+        """radau13 should not raise if dense callback returns True, but it should
+        if an exception occurs there."""
+        def _rhs(t, x):
+            return 1
+        def _dense_cb(told, t, x, cont):
+            return True
+        def _dense_cb_err(told, t, x, cont):
+            return 1/0
+        self.assertEqual(radau13(_rhs, 0, 1, dense_callback=_dense_cb), 0)
+        self.assertRaises(ZeroDivisionError, lambda: radau13(_rhs, 0, 1, dense_callback=_dense_cb_err))
+
     def test_exp(self):
         self.assertAlmostEqual(float(radau13(lambda t, x: x, 1, 1)), np.exp(1))
 
-- 
GitLab