Ticket #3484: trac3484-sage_eval.patch

File trac3484-sage_eval.patch, 6.1 kB (added by cwitty, 7 months ago)
  • a/sage/misc/sage_eval.py

    old new  
    1010#                  http://www.gnu.org/licenses/ 
    1111#***************************************************************************** 
    1212 
    13 from preparser import preparse 
     13from copy import copy 
     14import preparser 
    1415 
    15 def sage_eval(source, locals={}): 
     16def sage_eval(source, locals=None, cmds='', preparse=True): 
    1617    r""" 
    17     Obtain a \SAGE object from the input string by evaluate it using 
    18     SAGE.  This means calling eval after preparsing and with 
     18    Obtain a \SAGE object from the input string by evaluating it using 
     19    Sage.  This means calling eval after preparsing and with 
    1920    globals equal to everything included in the scope of 
    2021    \code{from sage.all import *}.). 
    21  
    22     If the object has an _sage_ method it is called and the value is 
    23     returned.  Otherwise str is called on the object, and all 
    24     preparsing is applied and the resulting expression is evaluated in the 
    25     context of \code{from sage.all import *}.  To evaluate the 
    26     expression with certain variables set, use the locals argument, 
    27     which should be a dictionary. 
    2822 
    2923    EXAMPLES: 
    3024    This example illustrates that preparsing is applied. 
     
    3327        sage: sage_eval('2^3') 
    3428        8 
    3529 
    36     Note that you have explicitly define variables and pass 
     30    However, preparsing can be turned off. 
     31 
     32        sage: sage_eval('2^3', preparse=False) 
     33        1 
     34 
     35    Note that you can explicitly define variables and pass 
    3736    them as the second option: 
    3837 
    3938        sage: x = PolynomialRing(RationalField(),"x").gen() 
    4039        sage: sage_eval('x^2+1', locals={'x':x}) 
    4140        x^2 + 1 
    42  
    43     This illustrates interfaces: 
    44         sage: f = gp('2/3') 
    45         sage: type(f) 
    46         <class 'sage.interfaces.gp.GpElement'> 
    47         sage: f._sage_() 
    48         2/3 
    49         sage: type(f._sage_()) 
    50         <type 'sage.rings.rational.Rational'> 
    51         sage: a = gap(939393/2433) 
    52         sage: a._sage_() 
    53         313131/811 
    54         sage: type(a._sage_()) 
    55         <type 'sage.rings.rational.Rational'> 
    5641 
    5742    This example illustrates that evaluation occurs in the context of 
    5843    \code{from sage.all import *}.  Even though bernoulli has been 
     
    8368        sage: sage_eval('4/3 + x',  locals={'x':25}) 
    8469        79/3 
    8570 
     71    You can also specify a sequence of commands to be run before the 
     72    expression is evaluated: 
     73        sage: sage_eval('p', cmds='K.<x> = QQ[]\np = x^2 + 1') 
     74        x^2 + 1 
     75 
     76    If you give commands to execute and a dictionary of variables, then 
     77    the dictionary will be modified by assignments in the commands: 
     78        sage: vars = {} 
     79        sage: sage_eval('None', cmds='y = 3', locals=vars) 
     80        sage: vars['y'], parent(vars['y']) 
     81        (3, Integer Ring) 
     82 
     83    You can also specify the object to evaluate as a tuple.  A 2-tuple 
     84    is assumed to be a pair of a command sequence and an expression; 
     85    a 3-tuple is assumed to be a triple of a command sequence, an expression, 
     86    and a dictionary holding local variables.  (In this case, the given  
     87    dictionary will not be modified by assignments in the commands.) 
     88        sage: sage_eval(('f(x) = x^2', 'f(3)')) 
     89        9 
     90        sage: vars = {'rt2': sqrt(2.0)} 
     91        sage: sage_eval(('rt2 += 1', 'rt2', vars)) 
     92        2.41421356237309 
     93        sage: vars['rt2'] 
     94        1.41421356237310 
     95 
    8696    This example illustrates how \code{sage_eval} can be useful 
    8797    when evaluating the output of other computer algebra systems. 
    8898     
     
    101111 
    102112    Here you can see eval simply will not work but \code{sage_eval} will. 
    103113    """ 
     114    if isinstance(source, (list, tuple)): 
     115        cmds = source[0] 
     116        if len(source) > 2: 
     117            locals = copy(source[2]) 
     118        source = source[1] 
     119 
    104120    if not isinstance(source, basestring): 
    105121        raise TypeError, "source must be a string." 
    106122         
     123    if locals is None: 
     124        locals = {} 
     125 
    107126    import sage.all 
    108     p = preparse(source) 
     127    if len(cmds): 
     128        cmd_seq = cmds + '\n_sage_eval_returnval_ = ' + source 
     129        if preparse: 
     130            cmd_seq = preparser.preparse_file(cmd_seq) 
     131    else: 
     132        if preparse: 
     133            source = preparser.preparse(source) 
    109134    try: 
    110         return eval(p, sage.all.__dict__, locals) 
     135        if len(cmds): 
     136            exec cmd_seq in sage.all.__dict__, locals 
     137            return locals['_sage_eval_returnval_'] 
     138        else: 
     139            return eval(source, sage.all.__dict__, locals) 
    111140    except SyntaxError, msg: 
    112         raise SyntaxError, "%s\nError using SAGE to evaluate '%s'"%(msg, p
     141        raise SyntaxError, "%s\nError using SAGE to evaluate '%s'"%(msg, cmd_seq if len(cmds) else source
    113142     
    114143         
    115144 
     
    118147    Return a native SAGE object associated to x, if possible 
    119148    and implemented. 
    120149 
    121     If x is a string it is evaluated with SAGE preparsing.  
     150    If the object has an _sage_ method it is called and the value is 
     151    returned.  Otherwise str is called on the object, and all 
     152    preparsing is applied and the resulting expression is evaluated in the 
     153    context of \code{from sage.all import *}.  To evaluate the 
     154    expression with certain variables set, use the vars argument, 
     155    which should be a dictionary. 
    122156 
    123157    EXAMPLES: 
    124158        sage: type(sageobj(gp('34/56'))) 
     
    130164        512 
    131165        sage: type(k) 
    132166        <type 'sage.rings.integer.Integer'> 
     167 
     168    This illustrates interfaces: 
     169        sage: f = gp('2/3') 
     170        sage: type(f) 
     171        <class 'sage.interfaces.gp.GpElement'> 
     172        sage: f._sage_() 
     173        2/3 
     174        sage: type(f._sage_()) 
     175        <type 'sage.rings.rational.Rational'> 
     176        sage: a = gap(939393/2433) 
     177        sage: a._sage_() 
     178        313131/811 
     179        sage: type(a._sage_()) 
     180        <type 'sage.rings.rational.Rational'> 
    133181    """ 
    134182    try: 
    135183       return x._sage_()