Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #45619

Re: Question about ast.literal_eval

From Frank Millman <frank@chagford.com>
Subject Re: Question about ast.literal_eval
Date 2013-05-20 15:26 +0200
References <knci07$jol$1@ger.gmane.org> <BLU176-W37EB377C73CD6D7306247DD7AF0@phx.gbl> <knckj0$cft$1@ger.gmane.org> <CAPTjJmpb073XFH5ksNhzRyAJNSJF=6WNq5pGzed4PXqBrJBN=A@mail.gmail.com> <knclk6$lva$1@ger.gmane.org>
Newsgroups comp.lang.python
Message-ID <mailman.1888.1369056365.3114.python-list@python.org> (permalink)

Show all headers | View raw


On 20/05/2013 10:07, Frank Millman wrote:
> On 20/05/2013 09:55, Chris Angelico wrote:
>> Is it a requirement that they be able to key in a constraint as a
>> single string? We have a similar situation in one of the systems at
>> work, so we divided the input into three(ish) parts: pick a field,
>> pick an operator (legal operators vary according to field type -
>> integers can't be compared against regular expressions, timestamps can
>> use >= and < only), then enter the other operand. Sure, that cuts out
>> a few possibilities, but you get 99.9%+ of all usage and it's easy to
>> sanitize.
>>
>> ChrisA
>>
>
> It is not a requirement, no. I just thought it would be a convenient
> short-cut.
>
> I had in mind something similar to your scheme above, so I guess I will
> have to bite the bullet and implement it.
>

Can anyone see anything wrong with the following approach. I have not 
definitely decided to do it this way, but I have been experimenting and 
it seems to work.

I store the boolean test as a json'd list of 6-part tuples. Each element 
of the tuple is a string, defined as follows -

0 - for the first entry in the list, the word 'check' (a placeholder - 
it is discarded at evaluation time), for any subsequent entries the word 
'and' or 'or'.

1 - left bracket - either '(' or ''.

2 - column name to check - it will be validated on entry.

3 - operator - must be one of '=', '!=', '<', '>', '<=', '>=', 'in', 
'is', 'is not'. At evaluation time, '=' is changed to '=='.

4 - value to compare - at evaluation time I call 
str(literal_eval(value)) to ensure that it is safe.

5 - right bracket - either ')' or ''.

At evaluation time I loop through the list, construct the boolean test 
as a string, and call eval() on it.

Here are some examples -

check = []
check.append(('check', '', 'name', 'in', "('abc', 'xyz')", ''))

check = []
check.append(('check', '', 'value', '>=', '0', ''))

check = []
check.append(('check', '(', 'descr', 'is not', 'None', ''))
check.append(('and', '', 'alt', 'is', 'None', ')'))
check.append(('or', '(', 'descr', 'is', 'None', ''))
check.append(('and', '', 'alt', 'is not', 'None', ')'))

I don't plan to check the logic - I will just display the exception if 
it does not evaluate.

It seems safe to me. Can anyone see a problem with it?

Frank

Back to comp.lang.python | Previous | NextNext in thread | Find similar | Unroll thread


Thread

Re: Question about ast.literal_eval Frank Millman <frank@chagford.com> - 2013-05-20 15:26 +0200
  Re: Question about ast.literal_eval Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-20 16:12 +0000
    Re: Question about ast.literal_eval Chris Angelico <rosuav@gmail.com> - 2013-05-21 02:23 +1000
    Re: Question about ast.literal_eval Frank Millman <frank@chagford.com> - 2013-05-21 08:30 +0200
      Re: Question about ast.literal_eval Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-05-21 07:21 +0000
        Re: Question about ast.literal_eval Frank Millman <frank@chagford.com> - 2013-05-21 10:06 +0200
        Re: Question about ast.literal_eval Fábio Santos <fabiosantosart@gmail.com> - 2013-05-21 09:23 +0100
        Re: Question about ast.literal_eval Mark Lawrence <breamoreboy@yahoo.co.uk> - 2013-05-21 10:00 +0100

csiph-web