Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!ecngs!feeder2.ecngs.de!newsfeed.freenet.ag!news2.euro.net!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'context': 0.05; 'defines': 0.07; 'expressions': 0.07; 'skip:/ 10': 0.07; 'table.': 0.07; 'python': 0.09; 'assembler': 0.09; 'handling,': 0.09; 'literal': 0.09; 'substitution': 0.09; 'terry': 0.09; 'variables,': 0.09; 'looked': 0.10; 'def': 0.10; '"right"': 0.16; 'lexical': 0.16; 'received:10.225': 0.16; 'received:10.225.4': 0.16; 'received:74.55.86': 0.16; 'received:74.55.86.74': 0.16; 'received:smtp.webfaction.com': 0.16; 'received:webfaction.com': 0.16; 'reedy': 0.16; 'wrote:': 0.17; 'integer': 0.17; 'jan': 0.18; '>>>': 0.18; 'written': 0.20; 'bit': 0.21; 'assignment': 0.22; 'names.': 0.22; 'this:': 0.23; "i've": 0.23; 'seems': 0.23; 'header:In-Reply-To:1': 0.25; 'header:User-Agent:1': 0.26; 'values': 0.26; 'am,': 0.27; 'replace': 0.27; 'rest': 0.28; 'arithmetic': 0.29; 'attempting': 0.29; "d'aprano": 0.29; 'delayed': 0.29; 'steven': 0.29; 'table,': 0.29; 'probably': 0.29; 'fri,': 0.30; 'performing': 0.30; 'error': 0.30; 'code': 0.31; "skip:' 20": 0.32; 'symbol': 0.33; 'problem': 0.33; 'to:addr :python-list': 0.33; 'pm,': 0.35; 'table': 0.35; 'something': 0.35; 'but': 0.36; 'rather': 0.37; 'subject:: ': 0.38; 'easier': 0.38; 'received:10': 0.38; 'to:addr:python.org': 0.39; 'back': 0.62; 'evaluate': 0.62; 'more': 0.63; 'header:Reply-To:1': 0.68; 'reply-to:no real name:2**0': 0.72; '2013': 0.84; 'capability': 0.91; 'edwards': 0.91; 'safer': 0.91 Date: Thu, 14 Mar 2013 20:02:04 -0700 From: Ken Seehart User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20130307 Thunderbird/17.0.4 MIME-Version: 1.0 To: python-list@python.org Subject: Re: Yet another attempt at a safe eval() call References: <50e6da35$0$30003$c3e8da3$5496439d@news.astraweb.com> In-Reply-To: <50e6da35$0$30003$c3e8da3$5496439d@news.astraweb.com> Content-Type: multipart/alternative; boundary="------------080507040908010808010308" X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: ken@seehart.com List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 118 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1363316529 news.xs4all.nl 6875 [2001:888:2000:d::a6]:53372 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:41255 This is a multi-part message in MIME format. --------------080507040908010808010308 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable On 1/4/2013 5:33 AM, Steven D'Aprano wrote: > On Fri, 04 Jan 2013 07:24:04 -0500, Terry Reedy wrote: > >> On 1/3/2013 6:25 PM, Grant Edwards wrote: >>> I've written a small assembler in Python 2.[67], and it needs to >>> evaluate integer-valued arithmetic expressions in the context of a >>> symbol table that defines integer values for a set of names. The >>> "right" thing is probably an expression parser/evaluator using ast, b= ut >>> it looked like that would take more code that the rest of the assembl= er >>> combined, and I've got other higher-priority tasks to get back to. >> Will ast.literal_eval do what you want? > No. Grant needs to support variables, not just literal constants, hence= =20 > the symbol table. > > Apologies for the delayed response... Seems like it would be a bit safer and easier to approach this problem by stretching the capability of ast.literal_eval() rather than attempting to sandbox eval(). How about ast.literal_eval after performing lexical substitution using the symbol table? Assignment into the symbol table, and error handling, are exercises left to the reader. Something vaguely like this: /pseudocode:/ def safe_eval(s, symbols=3D{}): while search(s, r'\w+'): replace match with '('+repr(symbols[match])+')' in s return ast.literal_eval(s) - Ken --------------080507040908010808010308 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit
On 1/4/2013 5:33 AM, Steven D'Aprano wrote:
On Fri, 04 Jan 2013 07:24:04 -0500, Terry Reedy wrote:

On 1/3/2013 6:25 PM, Grant Edwards wrote:
I've written a small assembler in Python 2.[67], and it needs to
evaluate integer-valued arithmetic expressions in the context of a
symbol table that defines integer values for a set of names.  The
"right" thing is probably an expression parser/evaluator using ast, but
it looked like that would take more code that the rest of the assembler
combined, and I've got other higher-priority tasks to get back to.
Will ast.literal_eval do what you want?
No. Grant needs to support variables, not just literal constants, hence 
the symbol table.


Apologies for the delayed response...

Seems like it would be a bit safer and easier to approach this problem by stretching the capability of ast.literal_eval() rather than attempting to sandbox eval().

How about ast.literal_eval after performing lexical substitution using the symbol table?

Assignment into the symbol table, and error handling, are exercises left to the reader.

Something vaguely like this:
pseudocode:

def safe_eval(s, symbols={}):
    while search(s, r'\w+'):
        replace match with '('+repr(symbols[match])+')' in s
    return ast.literal_eval(s)

- Ken

--------------080507040908010808010308--