From 9be877319fbc4d31a54c8194b39977cf824d2b90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Fri, 10 Jan 2025 18:36:32 -0300 Subject: [PATCH 1/3] test the custom signal handler with cypari2 This test triggers the following bug on cysignals 1.12.0 - 1.12.2: ``` Python 3.13.1 (main, Dec 14 2024, 12:44:03) [GCC 13.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import cypari2 >>> from cysignals.alarm import alarm >>> try: ... alarm(0.5) ... while True: pass ... except: ... pass ... >>> cypari2.Pari() Traceback (most recent call last): File "", line 1, in cypari2.Pari() ~~~~~~~~~~~~^^ File "cypari2/pari_instance.pyx", line 471, in cypari2.pari_instance.Pari.__cinit__ File "cypari2/closure.pyx", line 138, in cypari2.closure._pari_init_closure cysignals.signals.AlarmInterrupt ``` --- pyproject.toml | 2 +- tests/test_custom_signals.py | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/test_custom_signals.py diff --git a/pyproject.toml b/pyproject.toml index d30ad23..edcb5c8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,4 +34,4 @@ requires-python = ">=3.9" [tool.pytest.ini_options] addopts = "--doctest-modules --import-mode importlib" -norecursedirs = "builddir docs example" +testpaths = "src tests" diff --git a/tests/test_custom_signals.py b/tests/test_custom_signals.py new file mode 100644 index 0000000..a385f36 --- /dev/null +++ b/tests/test_custom_signals.py @@ -0,0 +1,17 @@ +import pytest +import time + +def test_clear_pending(): + + from cysignals.alarm import alarm, AlarmInterrupt + + cypari2 = pytest.importorskip("cypari2") + + with pytest.raises(AlarmInterrupt): + alarm(0.5) + time.sleep(1) + + try: + cypari2.Pari() + except AlarmInterrupt: + pytest.fail("AlarmInterrupt was not cleared") From 6731d2c0f602dc51edb007ca4def51ee77594063 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Fri, 10 Jan 2025 01:08:22 -0300 Subject: [PATCH 2/3] fix custom signal handling, which was broken after #166 There was a typo in #181: when the pari sigint handling was converted to a general mechanism, the line ``` PARI_SIGINT_pending = 0; ``` got translated into ``` custom_signal_unblock(); ``` instead of the correct ``` custom_set_pending_signal(0); ``` This error didn't take effect until #166 removed the pari sigint handling. This causes some doctest failures in sagemath: ``` src/sage/coding/linear_code.py src/sage/geometry/integral_points.pxi src/sage/rings/integer.pyx src/sage/rings/polynomial/polynomial_element.pyx ``` related to mishandling of AlarmInterrupt. See: https://github.com/sagemath/cysignals/pull/181/files#r1904885037 --- src/cysignals/implementation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cysignals/implementation.c b/src/cysignals/implementation.c index 20a83d0..18b8144 100644 --- a/src/cysignals/implementation.c +++ b/src/cysignals/implementation.c @@ -591,7 +591,7 @@ static void _sig_on_interrupt_received(void) do_raise_exception(cysigs.interrupt_received); cysigs.sig_on_count = 0; cysigs.interrupt_received = 0; - custom_signal_unblock(); + custom_set_pending_signal(0); #if HAVE_SIGPROCMASK sigprocmask(SIG_SETMASK, &oldset, NULL); From 36844ad0d93ff25b1f1258115048d13874e7236b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Tornar=C3=ADa?= Date: Tue, 14 Jan 2025 00:48:54 -0300 Subject: [PATCH 3/3] skip new test on windows (needs cysignals.alarm) --- tests/test_custom_signals.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/test_custom_signals.py b/tests/test_custom_signals.py index a385f36..0afc36f 100644 --- a/tests/test_custom_signals.py +++ b/tests/test_custom_signals.py @@ -1,17 +1,23 @@ -import pytest +""" +Tests for custom signals. +""" + import time +import pytest def test_clear_pending(): + """ + Regression test for https://github.com/sagemath/cysignals/pull/216 + """ - from cysignals.alarm import alarm, AlarmInterrupt - + alarm = pytest.importorskip("cysignals.alarm") # n/a on windows cypari2 = pytest.importorskip("cypari2") - with pytest.raises(AlarmInterrupt): - alarm(0.5) + with pytest.raises(alarm.AlarmInterrupt): + alarm.alarm(0.01) time.sleep(1) try: cypari2.Pari() - except AlarmInterrupt: + except alarm.AlarmInterrupt: pytest.fail("AlarmInterrupt was not cleared")