Opened 8 years ago

Closed 5 years ago

#10774 closed defect (duplicate)

RuntimeError message for numerical infinite loop is printed, not thrown

Reported by: niles Owned by: jason, jkantor
Priority: major Milestone: sage-duplicate/invalid/wontfix
Component: numerical Keywords: RuntimeError numerics recursion-depth
Cc: Merged in:
Authors: Reviewers: Jeroen Demeyer
Report Upstream: N/A Work issues:
Branch: Commit:
Dependencies: Stopgaps:

Description

Reported in this question at Ask Sage, there is a bug in some infinite loops which causes a RuntimeError to be printed, but not thrown as an exception. This means it cannot be caught by try/except blocks.

def number(expr):
    try:    
        n = N(expr)
    except RuntimeError:
        n = 0
    return n
sage: expr=log(arcsin(e))
sage: a=number(expr)
Exception RuntimeError: 'maximum recursion depth exceeded in __subclasscheck__' in <type 'exceptions.RuntimeError'> ignored
sage: a
0

Similar problems are reported with N(log(NaN)).

Change History (4)

comment:1 Changed 8 years ago by nbruin

This is probably a python exception that occurs in a cython routine that does have any means to report the exception (see http://docs.cython.org/src/userguide/language_basics.html ) further up. This example illustrates the behaviour:

%cython
def error_raiser():
    raise RuntimeError, "my error"

cdef int unreportable_error_producer():
    error_raiser()
    return 1

cdef int reportable_error_producer() except -1:
    error_raiser()
    return 1
    
def call_this(reportable=0):
    if reportable:
        return reportable_error_producer()
    else:
        return unreportable_error_producer()

which results in

sage: call_this(reportable=1)
Traceback (most recent call last):
...
RuntimeError: my error
sage: call_this()
Exception RuntimeError: 'my error' in '[...]unreportable_error_producer' ignored
0

The 0 return value there is rather arbitrary, I assume.

You can investigate the errors that arise a little easier by calling:

sys.setrecursionlimit(100)
N(log(NaN))
log(arcsin(e)).n()

The traceback clearly shows a ping-pong between sage.rings.real_mpfr.RealNumber?.log and sage.rings.complex_number.ComplexNumber.log so that's the real source of the error. It looks like a cython routine involved in creating the corresponding error object subsequently gets bitten by the already exhausted recursion depth and has no way of propagating that exception up.

comment:2 Changed 5 years ago by jdemeyer

  • Milestone set to sage-duplicate/invalid/wontfix
  • Reviewers set to Jeroen Demeyer
  • Status changed from new to needs_review

Duplicate of #15388.

comment:3 Changed 5 years ago by jdemeyer

  • Status changed from needs_review to positive_review

comment:4 Changed 5 years ago by vbraun

  • Resolution set to duplicate
  • Status changed from positive_review to closed
Note: See TracTickets for help on using tickets.