Python-list Digest, Vol 35, Issue 160

Brendon Towle btowle at carnegielearning.com
Thu Aug 10 09:27:31 EDT 2006


> Date: Thu, 10 Aug 2006 08:51:12 -0400
> From: Brendon Towle <btowle at carnegielearning.com>
> Subject: Re: Eval (was Re: Question about using python as a scripting
> 	language)
>
>> Date: 9 Aug 2006 14:12:01 -0700
>> From: "Simon Forman" <rogue_pedro at yahoo.com>
>> Subject: Re: Eval (was Re: Question about using python as a scripting
>> 	language)
>> To: python-list at python.org
>> Message-ID: <1155157921.662196.11210 at 75g2000cwc.googlegroups.com>
>> Content-Type: text/plain; charset="iso-8859-1"
>>
>> Fredrik Lundh posted a great piece of code to parse a subset of  
>> python
>> safely:
>>
>> http://groups.google.ca/group/comp.lang.python/browse_frm/thread/
>> 8e427c5e6da35c/a34397ba74892b4e
>
> This, as it turns out, was the most helpful pointer of them all --
> thanks!

Actually, I spoke too soon. (I should have known better -- always  
test first.) But:

 >>>import SafeEval as se

 >>>se.safeEval('[["AAPL", 35.5, 0.45],["YHOO", 75.68, 0.01]]')
[['AAPL', 35.5, 0.45000000000000001], ['YHOO', 75.680000000000007,  
0.01]]

 >>>se.safeEval('[["AAPL", 35.5, 0.45],["YHOO", 75.68, -0.01]]')
SyntaxError: malformed expression (-)

Seems that parsing negative numbers is outside of the scope of this  
routine. Here's the source (which is Frederik's source with one minor  
renaming; I take no credit here); anyone have any ideas?

B.

==== start source ====

import cStringIO, tokenize

def sequence(next, token, end):
    out = []
    token = next()
    while token[1] != end:
        out.append(atom(next, token))
        token = next()
        if token[1] == "," or token[1] == ":":
            token = next()
    return out

def atom(next, token):
    if token[1] == "(":
        return tuple(sequence(next, token, ")"))
    elif token[1] == "[":
        return sequence(next, token, "]")
    elif token[1] == "{":
        seq = sequence(next, token, "}")
        res = {}
        for i in range(0, len(seq), 2):
            res[seq[i]] = seq[i+1]
        return res
    elif token[0] in (tokenize.STRING, tokenize.NUMBER):
        return eval(token[1]) # safe use of eval!
    raise SyntaxError("malformed expression (%s)" % token[1])

def safeEval(source):
    src = cStringIO.StringIO(source).readline
    src = tokenize.generate_tokens(src)
    src = (token for token in src if token[0] is not tokenize.NL)
    res = atom(src.next, src.next())
    if src.next()[0] is not tokenize.ENDMARKER:
        raise SyntaxError("bogus data after expression")
    return res

==== end source ====


-- 
Brendon Towle, PhD
Cognitive Scientist
+1-412-690-2442x127
Carnegie Learning, Inc.
The Cognitive Tutor Company ®
Helping over 375,000 students in 1000 school districts succeed in math.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-list/attachments/20060810/b63115c0/attachment.html>


More information about the Python-list mailing list