Skip to content

Commit

Permalink
Trac #26992: Fix new (lib) gap on py3
Browse files Browse the repository at this point in the history
There are py3-specific bugs in the new lib gap, as of #22626.
Some of them stem from error handler not being fully string/bytes clean.
{{{
3$ ./sage -tp src/sage/libs/gap/util.pyx
Running doctests with ID 2019-01-02-09-11-48-97f4ca0c.
Git branch: HEAD
Using --optional=dochtml,memlimit,mpir,python2,sage
Doctesting 1 file using 8 threads.
sage -t --warn-long 46.7 src/sage/libs/gap/util.pyx
**********************************************************************
File "src/sage/libs/gap/util.pyx", line 389, in sage.libs.gap.util.NULL
Failed example:
    libgap.eval('Complex Field with 53 bits of precision;')
Expected:
    Traceback (most recent call last):
    ...
    ValueError: libGAP: Error, Variable: 'Complex' must have a value
    Syntax error: ; expected in stream:1
    Complex Field with 53 bits of precision;;
     ^^^^^^^^^^^^
    Error, Variable: 'with' must have a value
    Syntax error: ; expected in stream:1
    Complex Field with 53 bits of precision;;
     ^^^^^^^^^^^^^^^^^^^^
    Error, Variable: 'bits' must have a value
    Syntax error: ; expected in stream:1
    Complex Field with 53 bits of precision;;
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    Error, Variable: 'precision' must have a value
Got:
    RuntimeError: Error, Variable: 'Complex' must have a value
    <BLANKLINE>
    The above exception was the direct cause of the following exception:
    <BLANKLINE>
    Traceback (most recent call last):
      File "sage/libs/gap/util.pyx", line 510, in
sage.libs.gap.util.extract_libgap_errout
(build/cythonized/sage/libs/gap/util.c:6662)
    SystemError: <built-in method replace of str object at
0x7fd29cec5af8> returned a result with an error set
    Exception ignored in: 'sage.libs.gap.util.error_handler'
    Traceback (most recent call last):
      File "sage/libs/gap/util.pyx", line 510, in
sage.libs.gap.util.extract_libgap_errout
(build/cythonized/sage/libs/gap/util.c:6662)
    SystemError: <built-in method replace of str object at
0x7fd29cec5af8> returned a result with an error set
    RuntimeError: Syntax error: ; expected in stream:1
    Complex Field with 53 bits of precision;;
     ^^^^^^^^^^^^^^^^^^^^
    Error, Variable: 'bits' must have a value
    <BLANKLINE>
    The above exception was the direct cause of the following exception:
    <BLANKLINE>
    Traceback (most recent call last):
      File "sage/libs/gap/util.pyx", line 510, in
sage.libs.gap.util.extract_libgap_errout
(build/cythonized/sage/libs/gap/util.c:6662)
    SystemError: <built-in method replace of str object at
0x7fd29cc76030> returned a result with an error set
    Exception ignored in: 'sage.libs.gap.util.error_handler'
    Traceback (most recent call last):
      File "sage/libs/gap/util.pyx", line 510, in
sage.libs.gap.util.extract_libgap_errout
(build/cythonized/sage/libs/gap/util.c:6662)
    SystemError: <built-in method replace of str object at
0x7fd29cc76030> returned a result with an error set
    Traceback (most recent call last):
      File "/home/dimpase/sagepy3/local/lib/python3.6/site-
packages/sage/doctest/forker.py", line 671, in _run
        self.compile_and_execute(example, compiler, test.globs)
      File "/home/dimpase/sagepy3/local/lib/python3.6/site-
packages/sage/doctest/forker.py", line 1086, in compile_and_execute
        exec(compiled, globs)
      File "<doctest sage.libs.gap.util.NULL[4]>", line 1, in <module>
        libgap.eval('Complex Field with 53 bits of precision;')
      File "sage/libs/gap/libgap.pyx", line 410, in
sage.libs.gap.libgap.Gap.eval
(build/cythonized/sage/libs/gap/libgap.c:4360)
        elem = make_any_gap_element(self, gap_eval(gap_command))
      File "sage/libs/gap/util.pyx", line 442, in
sage.libs.gap.util.gap_eval (build/cythonized/sage/libs/gap/util.c:6328)
        raise ValueError('can only evaluate a single statement')
    ValueError: can only evaluate a single statement
**********************************************************************
File "src/sage/libs/gap/util.pyx", line 410, in sage.libs.gap.util.NULL
Failed example:
    libgap.eval('Complex Field with 53 bits of precision;')
Expected:
    Traceback (most recent call last):
    ...
    ValueError: libGAP: Error, Variable: 'Complex' must have a value
    ...
    Error, Variable: 'precision' must have a value
Got:
    RuntimeError: Error, Variable: 'Complex' must have a value
    <BLANKLINE>
    The above exception was the direct cause of the following exception:
    <BLANKLINE>
    Traceback (most recent call last):
      File "sage/libs/gap/util.pyx", line 510, in
sage.libs.gap.util.extract_libgap_errout
(build/cythonized/sage/libs/gap/util.c:6662)
    SystemError: <built-in method replace of str object at
0x7fd29cec5bb0> returned a result with an error set
    Exception ignored in: 'sage.libs.gap.util.error_handler'
    Traceback (most recent call last):
      File "sage/libs/gap/util.pyx", line 510, in
sage.libs.gap.util.extract_libgap_errout
(build/cythonized/sage/libs/gap/util.c:6662)
    SystemError: <built-in method replace of str object at
0x7fd29cec5bb0> returned a result with an error set
    RuntimeError: Syntax error: ; expected in stream:1
    Complex Field with 53 bits of precision;;
     ^^^^^^^^^^^^^^^^^^^^
    Error, Variable: 'bits' must have a value
    <BLANKLINE>
    The above exception was the direct cause of the following exception:
    <BLANKLINE>
    Traceback (most recent call last):
      File "sage/libs/gap/util.pyx", line 510, in
sage.libs.gap.util.extract_libgap_errout
(build/cythonized/sage/libs/gap/util.c:6662)
    SystemError: <built-in method replace of str object at
0x7fd29cc77030> returned a result with an error set
    Exception ignored in: 'sage.libs.gap.util.error_handler'
    Traceback (most recent call last):
      File "sage/libs/gap/util.pyx", line 510, in
sage.libs.gap.util.extract_libgap_errout
(build/cythonized/sage/libs/gap/util.c:6662)
    SystemError: <built-in method replace of str object at
0x7fd29cc77030> returned a result with an error set
    Traceback (most recent call last):
      File "/home/dimpase/sagepy3/local/lib/python3.6/site-
packages/sage/doctest/forker.py", line 671, in _run
        self.compile_and_execute(example, compiler, test.globs)
      File "/home/dimpase/sagepy3/local/lib/python3.6/site-
packages/sage/doctest/forker.py", line 1086, in compile_and_execute
        exec(compiled, globs)
      File "<doctest sage.libs.gap.util.NULL[5]>", line 1, in <module>
        libgap.eval('Complex Field with 53 bits of precision;')
      File "sage/libs/gap/libgap.pyx", line 410, in
sage.libs.gap.libgap.Gap.eval
(build/cythonized/sage/libs/gap/libgap.c:4360)
        elem = make_any_gap_element(self, gap_eval(gap_command))
      File "sage/libs/gap/util.pyx", line 442, in
sage.libs.gap.util.gap_eval (build/cythonized/sage/libs/gap/util.c:6328)
        raise ValueError('can only evaluate a single statement')
    ValueError: can only evaluate a single statement
**********************************************************************
1 item had failures:
   2 of   8 in sage.libs.gap.util.NULL
    [21 tests, 2 failures, 1.75 s]
----------------------------------------------------------------------
sage -t --warn-long 46.7 src/sage/libs/gap/util.pyx  # 2 doctests failed
----------------------------------------------------------------------
Total time for all tests: 1.8 seconds
    cpu time: 1.8 seconds
    cumulative wall time: 1.8 seconds
}}}

URL: https://trac.sagemath.org/26992
Reported by: dimpase
Ticket author(s): Erik Bray
Reviewer(s): Dima Pasechnik
  • Loading branch information
Release Manager authored and vbraun committed Feb 5, 2019
2 parents 337b33a + 369fade commit 3e7302b
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/sage/libs/gap/element.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -1428,7 +1428,7 @@ cdef class GapElement_Integer(GapElement):
sage: int(libgap(3))
3
sage: type(_)
<... 'int'>
<type 'int'>
sage: int(libgap(2)**128)
340282366920938463463374607431768211456L
Expand Down
2 changes: 1 addition & 1 deletion src/sage/libs/gap/util.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ cdef void reference_obj(Obj obj)
cdef void dereference_obj(Obj obj)

# callback from the GAP memory manager so we can mark all_gap_elements.values()
cdef void gasman_callback()
cdef void gasman_callback() with gil


############################################################################
Expand Down
20 changes: 13 additions & 7 deletions src/sage/libs/gap/util.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ cdef void dereference_obj(Obj obj):
owned_objects_refcount[wrapped] = refcount - 1


cdef void gasman_callback():
cdef void gasman_callback() with gil:
"""
Callback before each GAP garbage collection
"""
Expand Down Expand Up @@ -516,7 +516,7 @@ cdef object extract_libgap_errout():
return msg_py


cdef void error_handler():
cdef void error_handler() with gil:
"""
The libgap error handler.
Expand All @@ -528,25 +528,31 @@ cdef void error_handler():
handling code below it could result in a stack overflow.
"""
cdef PyObject* exc_type
cdef PyObject* exc_val
cdef PyObject* exc_val = NULL
cdef PyObject* exc_tb
cdef PyObject* err_occurred

# Close the error stream: This flushes any remaining output and closes
# the stream for further writing; reset ERROR_OUTPUT to something sane
# just in case (trying to print to a closed stream segfaults GAP)
try:
GAP_EnterStack()
GAP_EvalStringNoExcept(_close_error_output_cmd)
msg = extract_libgap_errout()

if PyErr_Occurred() != NULL and msg:
if PyErr_Occurred() != NULL:
# Sometimes error_handler() can be called multiple times from a
# single GAP_EvalString call before it returns; in this case we
# just update the exception by appending to the existing exception
# message
#
# Fetch any existing exception before calling
# extract_libgap_errout() so that the exception indicator is
# cleared
PyErr_Fetch(&exc_type, &exc_val, &exc_tb)
if exc_val != NULL:
msg = str(<object>exc_val) + '\n' + msg

msg = extract_libgap_errout()
if exc_val != NULL:
msg = str(<object>exc_val) + '\n' + msg
elif not msg:
msg = "An unknown error occurred in libGAP"

Expand Down

0 comments on commit 3e7302b

Please sign in to comment.