From da541cdad3456a729bc65b45cc081037b2e0b533 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Thu, 19 Dec 2024 16:05:31 +0700 Subject: [PATCH] Weird situation with 'exception ignored' --- src/sage/doctest/util.py | 98 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/src/sage/doctest/util.py b/src/sage/doctest/util.py index 4e36a541d3f..545917da7ca 100644 --- a/src/sage/doctest/util.py +++ b/src/sage/doctest/util.py @@ -27,6 +27,7 @@ from os import sysconf, times from contextlib import contextmanager from cysignals.alarm import alarm, cancel_alarm, AlarmInterrupt +from cysignals.signals import python_check_interrupt def count_noun(number, noun, plural=None, pad_number=False, pad_noun=False): @@ -808,6 +809,102 @@ def ensure_interruptible_after(seconds: float, max_wait_after_interrupt: float = TESTS:: + :: + + sage: cython(r''' + ....: from posix.unistd cimport usleep, useconds_t + ....: from posix.time cimport clock_gettime, CLOCK_REALTIME, timespec + ....: from cysignals.signals cimport sig_check + ....: from time import time as walltime + ....: from time import sleep + ....: + ....: cpdef sleep_(double t): usleep((t * 1e6)) # cython makes this interruptible + ....: + ....: cpdef void interruptible_sleep(double seconds): + ....: cdef timespec start_time, target_time + ....: start_walltime = walltime() + ....: clock_gettime(CLOCK_REALTIME, &start_time) + ....: + ....: cdef int floor_seconds = seconds + ....: target_time.tv_sec = start_time.tv_sec + floor_seconds + ....: target_time.tv_nsec = start_time.tv_nsec + ((seconds - floor_seconds) * 1e9) + ....: if target_time.tv_nsec >= 1000000000: + ....: target_time.tv_nsec -= 1000000000 + ....: target_time.tv_sec += 1 + ....: + ....: while True: + ....: sig_check() + ....: clock_gettime(CLOCK_REALTIME, &start_time) + ....: if start_time.tv_sec > target_time.tv_sec or (start_time.tv_sec == target_time.tv_sec and start_time.tv_nsec >= target_time.tv_nsec): + ....: break + ....: + ....: cpdef test1(object ensure_interruptible_after): + ....: with ensure_interruptible_after(2) as data: sleep(1) + ....: + ....: cpdef test2(object ensure_interruptible_after): + ....: with ensure_interruptible_after(2) as data: sleep_(1) + ....: + ....: cpdef test3(object ensure_interruptible_after): + ....: with ensure_interruptible_after(2) as data: interruptible_sleep(1) + ....: + ....: cpdef test4(object ensure_interruptible_after): + ....: with ensure_interruptible_after(1) as data: sleep(3) + ....: + ....: cpdef test5(object ensure_interruptible_after): + ....: with ensure_interruptible_after(1) as data: sleep_(3) + ....: + ....: cpdef test6(object ensure_interruptible_after): + ....: with ensure_interruptible_after(1) as data: interruptible_sleep(3) + ....: ''') + sage: with ensure_interruptible_after(2) as data: sleep(1r) + Traceback (most recent call last): + ... + RuntimeError: Function terminates early after 1.00... < 2.0000 seconds + sage: with ensure_interruptible_after(2) as data: sleep_(1r) + Traceback (most recent call last): + ... + RuntimeError: Function terminates early after 1.00... < 2.0000 seconds + sage: with ensure_interruptible_after(2) as data: uninterruptible_sleep(1r) + Traceback (most recent call last): + ... + RuntimeError: Function terminates early after 1.00... < 2.0000 seconds + sage: with ensure_interruptible_after(2) as data: interruptible_sleep(1r) + Traceback (most recent call last): + ... + RuntimeError: Function terminates early after 1.00... < 2.0000 seconds + sage: with ensure_interruptible_after(1) as data: sleep(3r) + sage: with ensure_interruptible_after(1) as data: sleep_(3r) + sage: with ensure_interruptible_after(1) as data: uninterruptible_sleep(3r) + Traceback (most recent call last): + ... + RuntimeError: Function is not interruptible within 1.0000 seconds, only after 3.00... seconds + sage: with ensure_interruptible_after(1) as data: interruptible_sleep(3r) + sage: test1(ensure_interruptible_after) + Traceback (most recent call last): + ... + RuntimeError: Function terminates early after 1.00... < 2.0000 seconds + sage: test2(ensure_interruptible_after) + Traceback (most recent call last): + ... + RuntimeError: Function terminates early after 1.00... < 2.0000 seconds + sage: test3(ensure_interruptible_after) + Traceback (most recent call last): + ... + RuntimeError: Function terminates early after 1.00... < 2.0000 seconds + sage: test4(ensure_interruptible_after) + sage: test5(ensure_interruptible_after) + Traceback (most recent call last): + ... + cysignals.signals.AlarmInterrupt + sage: test6(ensure_interruptible_after) + Traceback (most recent call last): + ... + cysignals.signals.AlarmInterrupt: + + :: + + :: + sage: # we use 1r instead of 1 to avoid unexplained slowdown sage: with ensure_interruptible_after(2) as data: sleep(1r) Traceback (most recent call last): @@ -849,6 +946,7 @@ def ensure_interruptible_after(seconds: float, max_wait_after_interrupt: float = try: yield data + python_check_interrupt(None, None) # equivalent to sig_check() (this is implementation detail!) except AlarmInterrupt: alarm_raised = True finally: