Ticket #9640: 9640-pari_error_callbacks_v2.patch

File 9640-pari_error_callbacks_v2.patch, 36.0 KB (added by jdemeyer, 8 years ago)
  • c_lib/include/interrupt.h

    # HG changeset patch
    # User Peter Bruin <P.Bruin@warwick.ac.uk>
    # Date 1379013789 -3600
    # Node ID b9279a44b869ff29c4830b7b5ac632de7577ca6c
    # Parent  e35bcd430aef5003b49056500506da07e8610b95
    Trac 9640: PARI error catching using callbacks
    
    diff --git a/c_lib/include/interrupt.h b/c_lib/include/interrupt.h
    a b  
    114114 */
    115115void setup_sage_signal_handler(void);
    116116
    117 /* This calls the externally defined function _signals.raise_exception
    118  * to actually raise the exception. It may only be called synchronously
    119  * with the Global Interpreter Lock held. */
    120 void do_raise_exception(int sig);
    121 
    122117
    123118/**********************************************************************
    124119 * SAGE_SIGNALS_T STRUCTURE                                           *
     
    303298}
    304299
    305300
    306 
    307301/**********************************************************************
    308302 * USER MACROS/FUNCTIONS                                              *
    309303 **********************************************************************/
     
    413407    siglongjmp(_signals.env, -1);
    414408}
    415409
     410/* Used in error callbacks from C code (in particular NTL and PARI).
     411 * This should be used after an exception has been raised to jump back
     412 * to sig_on() where the exception will be seen. */
     413static inline void sig_error()
     414{
     415    if (unlikely(_signals.sig_on_count <= 0))
     416    {
     417        fprintf(stderr, "sig_error() without sig_on()\n");
     418    }
     419    abort();
     420}
     421
    416422
    417423/*
    418424 * This function does nothing, but it is declared cdef except *, so it
  • c_lib/src/interrupt.c

    diff --git a/c_lib/src/interrupt.c b/c_lib/src/interrupt.c
    a b  
    5858/* default_sigmask with SIGHUP, SIGINT, SIGALRM added. */
    5959static sigset_t sigmask_with_sigint;
    6060
     61static void do_raise_exception(int sig);
     62
    6163/* Does this processor support the x86 EMMS instruction? */
    6264#if defined(__i386__) || defined(__x86_64__)
    6365#define CPU_ARCH_x86
     
    211213}
    212214
    213215
    214 void do_raise_exception(int sig)
     216/* This calls the externally defined function _signals.raise_exception
     217 * to actually raise the exception. It may only be called synchronously
     218 * with the Global Interpreter Lock held. */
     219static void do_raise_exception(int sig)
    215220{
    216221#if ENABLE_DEBUG_INTERRUPT
    217222    struct timeval raisetime;
     
    224229    }
    225230#endif
    226231
    227     _signals.raise_exception(sig, _signals.s);
    228     assert(PyErr_Occurred());
     232    /* Do not raise an exception if an exception is already pending */
     233    if (!PyErr_Occurred())
     234    {
     235        _signals.raise_exception(sig, _signals.s);
     236        assert(PyErr_Occurred());
     237    }
    229238}
    230239
    231240
  • module_list.py

    diff --git a/module_list.py b/module_list.py
    a b  
    703703    Extension('sage.libs.pari.gen',
    704704              sources = ["sage/libs/pari/gen.pyx"],
    705705              libraries = ['pari', 'gmp']),
    706    
     706
     707    Extension('sage.libs.pari.handle_error',
     708              sources = ["sage/libs/pari/handle_error.pyx"],
     709              libraries = ['pari', 'gmp']),
     710
    707711    Extension('sage.libs.ppl',
    708712              sources = ['sage/libs/ppl.pyx', 'sage/libs/ppl_shim.cc'],
    709               libraries = ['ppl', 'gmpxx', 'gmp', 'm'], 
     713              libraries = ['ppl', 'gmpxx', 'gmp', 'm'],
    710714              language="c++",
    711715              depends = [SAGE_INC + "/ppl.hh"]),
    712716
  • sage/ext/interrupt.pxi

    diff --git a/sage/ext/interrupt.pxi b/sage/ext/interrupt.pxi
    a b  
    1010    int sig_check_no_except()
    1111    void sig_off()
    1212    void sig_retry()
     13    void sig_error()
    1314    void sig_block()
    1415    void sig_unblock()
    1516    void set_sage_signal_handler_message(char* s)
  • sage/libs/pari/decl.pxi

    diff --git a/sage/libs/pari/decl.pxi b/sage/libs/pari/decl.pxi
    a b  
    4747    ctypedef unsigned long pari_sp
    4848    extern pari_sp avma, bot, top
    4949
     50    # parierr.h
     51
     52    int talker2, bugparier, alarmer, openfiler, talker, flagerr, impl, \
     53        archer, notfuncer, precer, typeer, consister, user, errpile, \
     54        overflower, matinv1, mattype1, arither1, primer1, invmoder, \
     55        constpoler, notpoler, redpoler, zeropoler, operi, operf, gdiver, \
     56        memer, negexper, sqrter5, noer
     57
     58    int warner, warnprec, warnfile, warnmem
    5059
    5160    # parigen.h
    5261
     
    112121    GEN     gnil
    113122    extern int INIT_JMPm, INIT_SIGm, INIT_DFTm
    114123    extern int new_galois_format, precdl
     124    # The "except 0" here is to ensure compatibility with
     125    # _pari_handle_exception() in handle_error.pyx
     126    extern int (*cb_pari_handle_exception)(long) except 0
     127    extern void (*cb_pari_err_recover)(long)
    115128
    116129    # level1.h
    117130   
     
    10871100    void    pari_flush()
    10881101    void    pari_putc(char c)
    10891102    void    pari_puts(char *s)
     1103    int     pari_last_was_newline()
     1104    void    pari_set_last_newline(int last)
    10901105    #void    print(GEN g)   # syntax error
    10911106    void    print1(GEN g)
    10921107    void    printtex(GEN g)
     
    19091924        void (*puts)(char*)
    19101925        void (*flush)()
    19111926    extern PariOUT* pariOut
     1927    extern PariOUT* pariErr
    19121928
    19131929
    19141930cdef extern from 'pari/paripriv.h':
  • sage/libs/pari/gen.pxd

    diff --git a/sage/libs/pari/gen.pxd b/sage/libs/pari/gen.pxd
    a b  
    11include 'decl.pxi'
    22
    3 cimport sage.structure.element 
     3cimport sage.structure.element
    44cimport sage.structure.parent_base
    55
    6 cdef void _pari_trap "_pari_trap"(long errno, long retries) except *
    7 
    86cdef class gen(sage.structure.element.RingElement):
    97    cdef GEN g
    108    cdef object _refers_to
  • deleted file sage/libs/pari/gen.pxi

    diff --git a/sage/libs/pari/gen.pxi b/sage/libs/pari/gen.pxi
    deleted file mode 100644
    + -  
    1 cdef extern gen (pari(object ))
  • sage/libs/pari/gen.pyx

    diff --git a/sage/libs/pari/gen.pyx b/sage/libs/pari/gen.pyx
    a b  
    173173from sage.structure.element cimport ModuleElement, RingElement, Element
    174174from sage.structure.parent cimport Parent
    175175from sage.misc.randstate cimport randstate, current_randstate
     176from sage.libs.pari.handle_error cimport pari_error_string, \
     177        _pari_init_error_handling, _pari_check_warning, \
     178        _pari_handle_exception, _pari_err_recover
    176179
    177180from sage.misc.misc_c import is_64_bit
    178181
     
    180183include 'sage/ext/stdsage.pxi'
    181184include 'sage/ext/python.pxi'
    182185
     186cdef extern from "misc.h":
     187    int     factorint_withproof_sage(GEN* ans, GEN x, GEN cutoff)
     188    int     gcmp_sage(GEN x, GEN y)
     189
    183190cdef extern from "mpz_pylong.h":
    184191    cdef int mpz_set_pylong(mpz_t dst, src) except -1
    185192
     
    10711078            sage: J.bid_get_gen()
    10721079            Traceback (most recent call last):
    10731080            ...
    1074             PariError:  (5)
     1081            PariError: missing bid generators. Use idealstar(,,2)
    10751082        """
    10761083        pari_catch_sig_on()
    10771084        return self.new_gen(bid_get_gen(self.g))
     
    16831690            sage: pari('[2^150,1]').intvec_unsafe()
    16841691            Traceback (most recent call last):
    16851692            ...
    1686             PariError:  (15)
     1693            PariError: overflow in t_INT-->long assignment
    16871694        """
    16881695        cdef int n, L
    16891696        cdef object v
     
    17031710    def python_list_small(gen self):
    17041711        """
    17051712        Return a Python list of the PARI gens. This object must be of type
    1706         t_VECSMALL, and the resulting list contains python 'int's
     1713        t_VECSMALL, and the resulting list contains python 'int's.
    17071714       
    17081715        EXAMPLES::
    17091716       
     
    17141721            sage: type(w[0])
    17151722            <type 'int'>
    17161723        """
    1717         cdef long n
     1724        cdef long n, m
    17181725        if typ(self.g) != t_VECSMALL:
    17191726            raise TypeError, "Object (=%s) must be of type t_VECSMALL."%self
    17201727        V = []
     
    17261733    def python_list(gen self):
    17271734        """
    17281735        Return a Python list of the PARI gens. This object must be of type
    1729         t_VEC
    1730        
    1731         INPUT: NoneOUTPUT:
    1732        
     1736        t_VEC.
     1737       
     1738        INPUT: None
     1739       
     1740        OUTPUT:
    17331741       
    17341742        -  ``list`` - Python list whose elements are the
    17351743           elements of the input gen.
     
    17541762        m = glength(self.g)
    17551763        V = []
    17561764        for n from 0 <= n < m:
    1757 ##            t = P.new_ref(<GEN> (self.g[n+1]), V)
    1758 ##            V.append(t)
    17591765            V.append(self.__getitem__(n))
    17601766        return V
    17611767
     
    18551861            sage: complex(g)
    18561862            Traceback (most recent call last):
    18571863            ...
    1858             PariError: incorrect type (11)
     1864            PariError: incorrect type in greal/gimag
    18591865        """
    18601866        cdef double re, im
    18611867        pari_catch_sig_on()
     
    25132519               sage: pari('x+y').Pol('y')
    25142520               Traceback (most recent call last):
    25152521               ...
    2516                PariError:  (5)
     2522               PariError: variable must have higher priority in gtopoly
    25172523       
    25182524        INPUT:
    25192525       
     
    26322638            sage: pari(3).Qfb(7, 2)  # discriminant is 25
    26332639            Traceback (most recent call last):
    26342640            ...
    2635             PariError:  (5)
     2641            PariError: square discriminant in Qfb
    26362642        """
    26372643        t0GEN(b); t1GEN(c); t2GEN(D)
    2638         pari_catch_sig_on()       
     2644        pari_catch_sig_on()
    26392645        return P.new_gen(Qfb0(a.g, t0, t1, t2, prec))
    26402646       
    26412647   
     
    29912997            sage: pari('x^2 + 2*x + 3').Vecsmall()
    29922998            Traceback (most recent call last):
    29932999            ...
    2994             PariError: incorrect type (11)
     3000            PariError: incorrect type in vectosmall
    29953001
    29963002        We demonstate the `n` argument::
    29973003
     
    33993405            sage: pari('x').component(0)
    34003406            Traceback (most recent call last):
    34013407            ...
    3402             PariError:  (5)
     3408            PariError: nonexistent component
    34033409        """
    34043410        pari_catch_sig_on()
    34053411        return P.new_gen(compo(x.g, n))
     
    34313437            sage: pari('Mod(x,x^3-3)').conj()
    34323438            Traceback (most recent call last):
    34333439            ...
    3434             PariError: incorrect type (11)
     3440            PariError: incorrect type in gconj
    34353441        """
    34363442        pari_catch_sig_on()
    34373443        return P.new_gen(gconj(x.g))
     
    35283534            sage: pari('"hello world"').floor()
    35293535            Traceback (most recent call last):
    35303536            ...
    3531             PariError: incorrect type (11)
     3537            PariError: incorrect type in gfloor
    35323538        """
    35333539        pari_catch_sig_on()
    35343540        return P.new_gen(gfloor(x.g))
     
    35543560            sage: pari('sqrt(-2)').frac()
    35553561            Traceback (most recent call last):
    35563562            ...
    3557             PariError: incorrect type (11)
     3563            PariError: incorrect type in gfloor
    35583564        """
    35593565        pari_catch_sig_on()
    35603566        return P.new_gen(gfrac(x.g))
     
    48934899            sage: pari(-1).gamma()
    48944900            Traceback (most recent call last):
    48954901            ...
    4896             PariError:  (5)
     4902            PariError: non-positive integer argument in ggamma
    48974903        """
    48984904        pari_catch_sig_on()
    48994905        return P.new_gen(ggamma(s.g, pbw(precision)))
     
    75997605            sage: pari('x^2 + 10^100 + 1').nfinit(precision=64)
    76007606            Traceback (most recent call last):
    76017607            ...
    7602             PariError: precision too low (10)
     7608            PariError: precision too low in floorr (precision loss in truncation)
    76037609            sage: pari('x^2 + 10^100 + 1').nfinit()
    76047610            [...]
    76057611
    7606         Throw a PARI error which is not precer::
     7612        Throw a PARI error which is not of type ``precer``::
    76077613       
    76087614            sage: pari('1.0').nfinit()
    76097615            Traceback (most recent call last):
    76107616            ...
    7611             PariError: incorrect type (11)
    7612         """
    7613        
     7617            PariError: incorrect type in checknf
     7618        """
    76147619        # If explicit precision is given, use only that
    76157620        if precision:
    7616             return self._nfinit_with_prec(flag, precision)
     7621            pari_catch_sig_on()
     7622            return P.new_gen(nfinit0(self.g, flag, pbw(precision)))
    76177623       
    76187624        # Otherwise, start with 64 bits of precision and increase as needed:
    76197625        precision = 64
    76207626        while True:
    76217627            try:
    7622                 return self._nfinit_with_prec(flag, precision)
    7623             except PariError, err:
     7628                return self.nfinit(flag, precision)
     7629            except PariError as err:
    76247630                if err.errnum() == precer:
    76257631                    precision *= 2
    76267632                else:
    7627                     raise err
    7628 
    7629     # NOTE: because of the way pari_catch_sig_on() and Cython exceptions work, this
    7630     # function MUST NOT be folded into nfinit() above. It has to be a
    7631     # seperate function.
    7632     def _nfinit_with_prec(self, long flag, long precision):
    7633         """
    7634         See ``self.nfinit()``.
    7635         """
    7636         pari_catch_sig_on()
    7637         return P.new_gen(nfinit0(self.g, flag, pbw(precision)))
     7633                    raise
    76387634
    76397635    def nfisisom(self, gen other):
    76407636        """
     
    78237819            sage: pari(-12).quadhilbert()   # Not fundamental
    78247820            Traceback (most recent call last):
    78257821            ...
    7826             PariError:  (5)
     7822            PariError: quadray needs a fundamental discriminant
    78277823        """
    78287824        pari_catch_sig_on()
    78297825        # Precision argument is only used for real quadratic extensions
     
    86938689            sage: pari('x^3 - y^3').factor()
    86948690            Traceback (most recent call last):
    86958691            ...
    8696             PariError:  (7)
     8692            PariError: sorry, factor for general polynomials is not yet implemented
    86978693        """
    86988694        cdef int r
    86998695        if limit == -1 and typ(self.g) == t_INT and proof:
     
    88218817            sage: f.change_variable_name("I")
    88228818            Traceback (most recent call last):
    88238819            ...
    8824             PariError:  (5)
     8820            PariError: I already exists with incompatible valence
    88258821            sage: f.subst("x", "I")
    88268822            0
    88278823        """
     
    92429238cdef PariOUT sage_pariOut
    92439239
    92449240cdef void sage_putchar(char c):
    9245     cdef char str[2]
    9246     str[0] = c
    9247     str[1] = 0
    9248     sys.stdout.write(str)
    9249     return
     9241    cdef char s[2]
     9242    s[0] = c
     9243    s[1] = 0
     9244    sys.stdout.write(s)
     9245    # Let PARI think the last character was a newline,
     9246    # so it doesn't print one when an error occurs.
     9247    pari_set_last_newline(1)
    92509248
    92519249cdef void sage_puts(char* s):
    92529250    sys.stdout.write(s)
    9253     return
     9251    pari_set_last_newline(1)
    92549252
    92559253cdef void sage_flush():
    92569254    sys.stdout.flush()
    9257     return
     9255
     9256cdef PariOUT sage_pariErr
     9257
     9258cdef void sage_pariErr_putchar(char c):
     9259    cdef char s[2]
     9260    s[0] = c
     9261    s[1] = 0
     9262    global pari_error_string
     9263    pari_error_string += str(s)
     9264    pari_set_last_newline(1)
     9265
     9266cdef void sage_pariErr_puts(char *s):
     9267    global pari_error_string
     9268    pari_error_string += str(s)
     9269    pari_set_last_newline(1)
     9270
     9271cdef void sage_pariErr_flush():
     9272    pass
    92589273
    92599274
    92609275cdef class PariInstance(sage.structure.parent_base.ParentWithBase):
     
    93029317        global num_primes, avma, top, bot, prec
    93039318
    93049319        # The size here doesn't really matter, because we will allocate
    9305         # our own stack anyway. We ask PARI not to set up signal handlers.
    9306         pari_init_opts(10000, maxprime, INIT_JMPm | INIT_DFTm)
     9320        # our own stack anyway. We ask PARI not to set up signal and
     9321        # error handlers.
     9322        pari_init_opts(10000, maxprime, INIT_DFTm)
     9323
     9324        _pari_init_error_handling()
     9325
    93079326        num_primes = maxprime
    93089327
    9309         # NOTE: pari_catch_sig_on() can only come AFTER pari_init_opts()!
    9310         pari_catch_sig_on()
    9311 
    93129328        # Free the PARI stack and allocate our own (using Cython)
    93139329        pari_free(<void*>bot); bot = 0
    93149330        init_stack(size)
     
    93229338        GP_DATA.fmt.sigd = prec_bits_to_dec(53)
    93239339
    93249340        # Set printing functions
    9325         global pariOut
     9341        global pariOut, pariErr
     9342
    93269343        pariOut = &sage_pariOut
    93279344        pariOut.putch = sage_putchar
    93289345        pariOut.puts = sage_puts
    93299346        pariOut.flush = sage_flush
    9330         pari_catch_sig_off()
     9347
     9348        pariErr = &sage_pariErr
     9349        pariErr.putch = sage_pariErr_putchar
     9350        pariErr.puts = sage_pariErr_puts
     9351        pariErr.flush = sage_pariErr_flush
    93319352
    93329353    def __dealloc__(self):
    93339354        """
     
    99379958            sage: pari.init_primes(2^62)
    99389959            Traceback (most recent call last):
    99399960            ...
    9940             PariError: not enough memory (28)            # 64-bit
    9941             OverflowError: long int too large to convert # 32-bit
     9961            PariError: not enough memory                  # 64-bit
     9962            OverflowError: long int too large to convert  # 32-bit
    99429963            sage: pari.init_primes(200000)
    99439964        """
    99449965        cdef unsigned long M
     
    1026710288            sage: pari.setrand(0)
    1026810289            Traceback (most recent call last):
    1026910290            ...
    10270             PariError: incorrect type (11)
     10291            PariError: incorrect type in setrand
    1027110292            sage: pari.setrand("foobar")
    1027210293            Traceback (most recent call last):
    1027310294            ...
    10274             PariError: incorrect type (11)
     10295            PariError: incorrect type in setrand
    1027510296        """
    1027610297        t0GEN(seed)
    1027710298        pari_catch_sig_on()
     
    1052010541        return v
    1052110542
    1052210543
    10523 #######################
    10524 # Base gen class
    10525 #######################
    10526 
    10527 
    10528 cdef extern from "pari/pari.h":
    10529     char *errmessage[]
    10530     int talker2, bugparier, alarmer, openfiler, talker, flagerr, impl, \
    10531         archer, notfuncer, precer, typeer, consister, user, errpile, \
    10532         overflower, matinv1, mattype1, arither1, primer1, invmoder, \
    10533         constpoler, notpoler, redpoler, zeropoler, operi, operf, gdiver, \
    10534         memer, negexper, sqrter5, noer
    10535     int warner, warnprec, warnfile, warnmem
    10536 
    10537 cdef extern from "misc.h":
    10538     int     factorint_withproof_sage(GEN* ans, GEN x, GEN cutoff)
    10539     int     gcmp_sage(GEN x, GEN y)
    10540 
    10541 def __errmessage(d):
    10542     if d <= 0 or d > noer:
    10543         return "unknown"
    10544     return errmessage[d]
    10545 
    10546 # FIXME: we derive PariError from RuntimeError, for backward
    10547 # compatibility with code that catches the latter. Once this is
    10548 # in production, we should change the base class to StandardError.
    10549 from exceptions import RuntimeError
    10550 
    10551 # can we have "cdef class" ?
    10552 # because of the inheritance, need to somehow "import" the built-in
    10553 # exception class...
    10554 class PariError (RuntimeError):
    10555 
    10556     errmessage = staticmethod(__errmessage)
    10557 
     10544# We derive PariError from RuntimeError, for backward compatibility with
     10545# code that catches the latter.
     10546class PariError(RuntimeError):
     10547    """
     10548    Error raised by PARI
     10549    """
    1055810550    def errnum(self):
    1055910551        r"""
    1056010552        Return the PARI error number corresponding to this exception.
     
    1056210554        EXAMPLES::
    1056310555           
    1056410556            sage: try:
    10565             ...     pari('1/0')
    10566             ... except PariError, err:
    10567             ...     print err.errnum()
     10557            ....:     pari('1/0')
     10558            ....: except PariError as err:
     10559            ....:     print err.errnum()
    1056810560            27
    1056910561        """
    1057010562        return self.args[0]
    1057110563
     10564    def errtext(self):
     10565        """
     10566        Return the message output by PARI when this error occurred.
     10567
     10568        EXAMPLE::
     10569
     10570            sage: try:
     10571            ....:     pari('pi()')
     10572            ....: except PariError as e:
     10573            ....:     print e.errtext()
     10574            ....:
     10575              ***   at top-level: pi()
     10576              ***                 ^----
     10577              ***   not a function in function call
     10578
     10579        """
     10580        return self.args[1]
     10581
    1057210582    def __repr__(self):
    1057310583        r"""
    1057410584        TESTS::
     
    1058010590
    1058110591    def __str__(self):
    1058210592        r"""
     10593        Return a suitable message for displaying this exception.
     10594
     10595        This is the last line of ``self.errtext()``, with the leading
     10596        ``"  ***   "`` and trailing period (if any) removed.
     10597
    1058310598        EXAMPLES::
    1058410599           
    1058510600            sage: try:
    10586             ...     pari('1/0')
    10587             ... except PariError, err:
    10588             ...     print err
    10589             division by zero (27)
    10590         """
    10591         return "%s (%d)"%(self.errmessage(self.errnum()), self.errnum())
    10592 
    10593 
    10594 # We expose a trap function to C.
    10595 # If this function returns without raising an exception,
    10596 # the code is retried.
    10597 # This is a proof-of-concept example.
    10598 # THE TRY CODE IS NOT REENTRANT -- NO CALLS TO PARI FROM HERE !!!
    10599 #              - Gonzalo Tornario
    10600 
    10601 cdef void _pari_trap "_pari_trap"(long errno, long retries) except *:
    10602     if retries > 100:
    10603         pari_catch_sig_off()
    10604         raise RuntimeError("_pari_trap recursion too deep")
    10605     if errno == errpile:
    10606         P.allocatemem(silent=True)
    10607     elif errno == user:
    10608         pari_catch_sig_off()
    10609         raise RuntimeError("PARI user exception")
    10610     else:
    10611         pari_catch_sig_off()
    10612         raise PariError(errno)
    10613 
    10614 
    10615 def vecsmall_to_intlist(gen v):
    10616     """
    10617     INPUT:
    10618    
    10619    
    10620     -  ``v`` - a gen of type Vecsmall
    10621    
    10622    
    10623     OUTPUT: a Python list of Python ints
    10624     """
    10625     if typ(v.g) != t_VECSMALL:
    10626         raise TypeError, "input v must be of type vecsmall (use v.Vecsmall())"
    10627     return [v.g[k+1] for k in range(glength(v.g))]
    10628 
     10601            ....:     pari('1/0')
     10602            ....: except PariError as err:
     10603            ....:     print err
     10604            _/_: division by zero
     10605        """
     10606        lines = self.errtext().split('\n')
     10607        return lines[-1].lstrip(" *").rstrip(" .")
    1062910608
    1063010609
    1063110610cdef _factor_int_when_pari_factor_failed(x, failed_factorization):
  • sage/libs/pari/gen_py.py

    diff --git a/sage/libs/pari/gen_py.py b/sage/libs/pari/gen_py.py
    a b  
    22from sage.misc.sage_eval import sage_eval
    33
    44from sage.rings.all import *
    5 I = ComplexField().gen()
    65
    76def pari(x):
    87    """
     
    112111    t_REAL:   ComplexField(prec) for equivalent precision
    113112    t_INTMOD, t_PADIC: raise NotImplementedError
    114113
    115     EXAMPLES:
     114    EXAMPLES::
     115
    116116        sage: a = pari('(3+I)').python(); a
    117117        i + 3
    118118        sage: a.parent()
     
    155155        Complex Field with 128 bits of precision # 64-bit
    156156
    157157    For architecture-independent complex numbers, start from a
    158     suitable ComplexField:
     158    suitable ComplexField::
     159
    159160        sage: z = pari(CC(1.0+2.0*I)); z
    160161        1.00000000000000 + 2.00000000000000*I
    161162        sage: a=z.python(); a
     
    163164        sage: a.parent()
    164165        Complex Field with 64 bits of precision
    165166
     167    Vectors and matrices::
     168
    166169        sage: a = pari('[1,2,3,4]')
    167170        sage: a
    168171        [1, 2, 3, 4]
     
    182185        sage: b.parent()
    183186        Full MatrixSpace of 2 by 2 dense matrices over Integer Ring
    184187
     188        sage: a = pari('Vecsmall([1,2,3,4])')
     189        sage: a.type()
     190        't_VECSMALL'
     191        sage: a.python()
     192        [1, 2, 3, 4]
     193
    185194    We use the locals dictionary::
    186195   
    187196        sage: f = pari('(2/3)*x^3 + x - 5/7 + y')
     
    240249    elif t == "t_VEC":
    241250        return [python(x) for x in z.python_list()]
    242251    elif t == "t_VECSMALL":
    243         return [IntegerRing(x) for x in z.python_list_small()]
     252        return z.python_list_small()
    244253    elif t == "t_MAT":
    245254        from sage.matrix.constructor import matrix
    246255        return matrix(z.nrows(),z.ncols(),[python(z[i,j]) for i in range(z.nrows()) for j in range(z.ncols())])
  • new file sage/libs/pari/handle_error.pxd

    diff --git a/sage/libs/pari/handle_error.pxd b/sage/libs/pari/handle_error.pxd
    new file mode 100644
    - +  
     1cdef str pari_error_string
     2
     3cdef void _pari_init_error_handling()
     4cdef void _pari_check_warning "_pari_check_warning"()
     5cdef int _pari_handle_exception(long err) except 0
     6cdef void _pari_err_recover(long err)
  • new file sage/libs/pari/handle_error.pyx

    diff --git a/sage/libs/pari/handle_error.pyx b/sage/libs/pari/handle_error.pyx
    new file mode 100644
    - +  
     1"""
     2Functions for handling PARI errors
     3
     4AUTHORS:
     5
     6- Peter Bruin (September 2013): initial version (#9640)
     7
     8"""
     9include "sage/ext/stdsage.pxi"
     10include "sage/ext/interrupt.pxi"
     11include "decl.pxi"
     12
     13from cpython cimport PyErr_Occurred
     14
     15
     16# Global variable to record error string
     17cdef str pari_error_string
     18
     19cdef void _pari_init_error_handling():
     20    """
     21    Set up our code for handling PARI errors.
     22
     23    TEST::
     24
     25        sage: try:
     26        ....:     p = pari.polcyclo(-1)
     27        ....: except PariError as e:
     28        ....:     print e.errtext()
     29        ....:
     30          ***   argument must be positive in polcyclo.
     31
     32    """
     33    global pari_error_string
     34    global cb_pari_err_recover
     35    global cb_pari_handle_exception
     36    pari_error_string = ""
     37    cb_pari_err_recover = _pari_err_recover
     38    cb_pari_handle_exception = _pari_handle_exception
     39
     40cdef void _pari_check_warning():
     41    """
     42    Print pending PARI library warning messages to stderr.
     43
     44    TEST::
     45
     46        sage: pari('warning("test")')
     47          ***   user warning: test
     48
     49    """
     50    global pari_error_string
     51    if pari_error_string != "":
     52        import sys
     53        sys.stderr.write(pari_error_string)
     54        pari_error_string = ""
     55
     56cdef int _pari_handle_exception(long err) except 0:
     57    """
     58    Convert a PARI error into a Sage exception, unless the error was
     59    a stack overflow, in which case we enlarge the stack.
     60
     61    This function is a callback from the PARI error handler.
     62
     63    EXAMPLES::
     64
     65        sage: pari('error("test")')
     66        Traceback (most recent call last):
     67        ...
     68        RuntimeError: PARI user exception
     69          ***   at top-level: error("test")
     70          ***                 ^-------------
     71          ***   user error: test
     72
     73        sage: pari(1)/pari(0)
     74        Traceback (most recent call last):
     75        ...
     76        PariError: division by zero
     77
     78    """
     79    from sage.libs.pari.gen import pari, PariError
     80    if err == errpile:
     81        pari.allocatemem(silent=True)
     82        return 0
     83
     84    if err == user:
     85        raise RuntimeError("PARI user exception\n%s" % pari_error_string)
     86    else:
     87        raise PariError(err, pari_error_string)
     88
     89cdef void _pari_err_recover(long err):
     90    """
     91    Reset the error string and jump back to ``sig_on()``, either to
     92    retry the code (in case of no error) or to make the already-raised
     93    exception known to Python.
     94
     95    TEST:
     96
     97    Perform a computation that requires doubling the default stack
     98    several times::
     99
     100        sage: from sage.libs.pari.gen import init_pari_stack
     101        sage: init_pari_stack(2^12)
     102        sage: x = pari('2^(2^26)')
     103        sage: x == 2^(2^26)
     104        True
     105
     106    """
     107    global pari_error_string
     108    pari_error_string = ""
     109    if not PyErr_Occurred():
     110        # No exception was raised => retry the computation starting
     111        # from sig_on(). This can happen if we successfully enlarged the
     112        # PARI stack in _pari_handle_exception().
     113        sig_retry()
     114    else:
     115        # An exception was raised.  Jump to the signal-handling code
     116        # which will cause sig_on() to see the exception.
     117        sig_error()
  • sage/libs/pari/pari_err.h

    diff --git a/sage/libs/pari/pari_err.h b/sage/libs/pari/pari_err.h
    a b  
    55/*****************************************
    66   Interrupts and PARI exception handling
    77 *****************************************/
    8 #define pari_catch_sig_on() sig_on(); _pari_catch;
    9 #define pari_catch_sig_str(s) sig_str(s); _pari_catch;
    10 #define pari_catch_sig_off() _pari_endcatch; sig_off();
    118
    12 
    13 // global catch variable !
    14 // this means that the code is not reentrant -- beware !
    15 // THAT MEANS NO CALLING TO PARI from inside the trap....
    16 // Should replace by a stack, that would work.
    17 static volatile long sage_pari_catcherr = 0;
    18 
    19 /* Careful with pari_retries, it must be declared volatile!
    20  * Also note that "pari_errno = setjmp(...)" is not legal C.
    21  */
    22 #define _pari_catch                                                           \
    23     jmp_buf _pari_catch_env;                                                  \
    24     {                                                                         \
    25         volatile long pari_retries = 0;                                       \
    26         sage_pari_catcherr = 0;                                               \
    27         long pari_errno = setjmp(_pari_catch_env);                            \
    28         if (pari_errno) {                                                     \
    29             _pari_trap(pari_errno, pari_retries);                             \
    30             if(PyErr_Occurred()) {                                            \
    31                 _pari_endcatch;                                               \
    32                 return NULL;                                                  \
    33             }                                                                 \
    34             pari_retries++;                                                   \
    35         }                                                                     \
    36         sage_pari_catcherr = err_catch(CATCH_ALL, &_pari_catch_env);          \
    37     }
    38 
    39 #define _pari_endcatch {                                                      \
    40          err_leave(sage_pari_catcherr);                                       \
    41     }
    42 
     9#define pari_catch_sig_on() _sig_on_(NULL)
     10#define pari_catch_sig_str(s) _sig_on_(s)
     11#define pari_catch_sig_off() (_sig_off_(__FILE__, __LINE__), _pari_check_warning())
  • sage/libs/pari/pari_err.pxi

    diff --git a/sage/libs/pari/pari_err.pxi b/sage/libs/pari/pari_err.pxi
    a b  
    1 # We don't need anything from here, as we have PARI-specific signal
    2 # handling.  We still include this such that Cython detects the
    3 # dependency on interrupt.h for recompiling gen.pyx.
     1# Let Cython know that pari_err.h includes interrupt.h
    42cdef extern from 'interrupt.h':
    53    pass
    64
     5from sage.libs.pari.handle_error cimport _pari_check_warning
     6
    77cdef extern from 'sage/libs/pari/pari_err.h':
    88    int pari_catch_sig_on() except 0
    99    int pari_catch_sig_str(char *) except 0
    1010    void pari_catch_sig_off()
    11 
    12 from sage.libs.pari.gen cimport _pari_trap
  • sage/matrix/matrix_integer_dense.pyx

    diff --git a/sage/matrix/matrix_integer_dense.pyx b/sage/matrix/matrix_integer_dense.pyx
    a b  
    7878
    7979cdef extern from "math.h":
    8080    double log(double x)
    81     double ldexp(double x, int exp)
    82 
    83 ctypedef unsigned int uint
     81
    8482
    8583from sage.ext.multi_modular import MultiModularBasis
    8684from sage.ext.multi_modular cimport MultiModularBasis
  • sage/matrix/matrix_rational_dense.pyx

    diff --git a/sage/matrix/matrix_rational_dense.pyx b/sage/matrix/matrix_rational_dense.pyx
    a b  
    26362636            sage: matrix(QQ,2,[1,2,2,4])._invert_pari()
    26372637            Traceback (most recent call last):
    26382638            ...
    2639             PariError: non invertible matrix in gauss (16)
     2639            PariError: non invertible matrix in gauss
    26402640        """
    26412641        if self._nrows != self._ncols:
    26422642            raise ValueError("self must be a square matrix")
  • sage/rings/arith.py

    diff --git a/sage/rings/arith.py b/sage/rings/arith.py
    a b  
    1414import math
    1515import sys
    1616import sage.misc.misc as misc
    17 from sage.libs.pari.gen import pari, vecsmall_to_intlist
     17from sage.libs.pari.gen import pari
    1818import sage.libs.flint.arith as flint_arith
    1919
    2020from sage.rings.rational_field import QQ
     
    39143914            n = len(range(start, stop, step)) # stupid
    39153915            v = pari('vector(%s, i, moebius(%s*(i-1) + %s))'%(
    39163916                n, step, start))
    3917         w = vecsmall_to_intlist(v.Vecsmall())
    3918         return [Z(x) for x in w]
    3919        
     3917        return [Z(x) for x in v]
     3918
    39203919moebius = Moebius()       
    39213920
    39223921def farey(v, lim):
  • sage/rings/integer.pyx

    diff --git a/sage/rings/integer.pyx b/sage/rings/integer.pyx
    a b  
    564564            sage: ZZ(pari("1e100"))
    565565            Traceback (most recent call last):
    566566            ...
    567             PariError: precision too low (10)
     567            PariError: precision too low in truncr (precision loss in truncation)
    568568            sage: ZZ(pari("10^50"))
    569569            100000000000000000000000000000000000000000000000000
    570570            sage: ZZ(pari("Pol(3)"))
  • sage/rings/number_field/number_field.py

    diff --git a/sage/rings/number_field/number_field.py b/sage/rings/number_field/number_field.py
    a b  
    30143014            sage: k.pari_polynomial('I')
    30153015            Traceback (most recent call last):
    30163016            ...
    3017             PariError:  (5)
     3017            PariError: I already exists with incompatible valence
    30183018            sage: k.pari_polynomial('i')
    30193019            i^2 + 1
    30203020            sage: k.pari_polynomial('theta')
    30213021            Traceback (most recent call last):
    30223022            ...
    3023             PariError:  (5)
     3023            PariError: theta already exists with incompatible valence
    30243024        """
    30253025        try:
    30263026            return self.__pari_polynomial.change_variable_name(name)
  • sage/rings/number_field/number_field_element.pyx

    diff --git a/sage/rings/number_field/number_field_element.pyx b/sage/rings/number_field/number_field_element.pyx
    a b  
    622622            sage: theta._pari_('theta')
    623623            Traceback (most recent call last):
    624624            ...
    625             PariError:  (5)
     625            PariError: theta already exists with incompatible valence
    626626            sage: theta._pari_()
    627627            Mod(y, y^2 + 1)
    628628            sage: k.<I> = QuadraticField(-1)
    629629            sage: I._pari_('I')
    630630            Traceback (most recent call last):
    631631            ...
    632             PariError:  (5)
     632            PariError: I already exists with incompatible valence
    633633       
    634634        Instead, request the variable be named different for the coercion::
    635635       
     
    709709            sage: b._pari_init_('theta')
    710710            Traceback (most recent call last):
    711711            ...
    712             PariError:  (5)
     712            PariError: theta already exists with incompatible valence
    713713       
    714714        Fortunately pari_init returns everything in terms of y by
    715715        default::
  • sage/rings/number_field/number_field_rel.py

    diff --git a/sage/rings/number_field/number_field_rel.py b/sage/rings/number_field/number_field_rel.py
    a b  
    208208            sage: b
    209209            Traceback (most recent call last):
    210210            ...
    211             PariError: incorrect type (11)
     211            PariError: incorrect type in core2partial
    212212
    213213        However, if the polynomial is linear, rational coefficients should work::
    214214
  • sage/rings/polynomial/cyclotomic.pyx

    diff --git a/sage/rings/polynomial/cyclotomic.pyx b/sage/rings/polynomial/cyclotomic.pyx
    a b  
    3030include "sage/ext/interrupt.pxi"
    3131include "sage/ext/cdefs.pxi"
    3232
    33 cdef extern from *:
    34     void memset(void *, char, int)
    35 
    3633from sage.rings.arith import factor
    3734from sage.rings.infinity import infinity
    3835from sage.misc.misc import prod, subsets
  • sage/rings/polynomial/polynomial_element.pyx

    diff --git a/sage/rings/polynomial/polynomial_element.pyx b/sage/rings/polynomial/polynomial_element.pyx
    a b  
    31073107            sage: K.pari_polynomial('a').nffactor("x^2+1")
    31083108            Traceback (most recent call last):
    31093109            ...
    3110             PariError: precision too low (10)
     3110            PariError: precision too low in floorr (precision loss in truncation)
    31113111            sage: factor(x^2 + 1)
    31123112            x^2 + 1
    31133113            sage: factor( (x - a) * (x + 2*a) )
     
    43794379            sage: pari(f)
    43804380            Traceback (most recent call last):
    43814381            ...
    4382             PariError: (5)
     4382            PariError: variable must have higher priority in gtopoly
    43834383       
    43844384        Stacked polynomial rings, first with a univariate ring on the
    43854385        bottom::
  • sage/schemes/elliptic_curves/ell_generic.py

    diff --git a/sage/schemes/elliptic_curves/ell_generic.py b/sage/schemes/elliptic_curves/ell_generic.py
    a b  
    29222922            sage: E.pari_curve()
    29232923            Traceback (most recent call last):
    29242924            ...
    2925             PariError:  (5)
     2925            PariError: valuation of j must be negative in p-adic ellinit
    29262926        """
    29272927        try:
    29282928            return self._pari_curve