Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!newsreader4.netcologne.de!news.netcologne.de!novso.com!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!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.007 X-Spam-Evidence: '*H*': 0.99; '*S*': 0.00; 'insert': 0.05; 'tree': 0.05; 'subject:Python': 0.06; "'',": 0.07; 'permitted': 0.07; 'expression:': 0.09; 'subject:using': 0.09; 'python': 0.11; "%s'": 0.16; '>>': 0.16; '[name': 0.16; 'ast': 0.16; 'expression.': 0.16; 'i.e': 0.16; 'namespace,': 0.16; 'simplest': 0.16; 'wrote:': 0.18; 'module': 0.19; 'parse': 0.24; 'subject: .': 0.24; '\xa0if': 0.24; '>': 0.26; 'header:In-Reply-To:1': 0.27; 'raise': 0.29; 'wonder': 0.29; "doesn't": 0.30; 'message-id:@mail.gmail.com': 0.30; "i'm": 0.30; 'code': 0.31; "skip:' 10": 0.31; '"",': 0.31; 'bug?': 0.31; 'names.': 0.31; 'object.': 0.31; 'received:google.com': 0.35; 'really': 0.36; '2.6': 0.36; 'doubt': 0.36; 'possible': 0.36; 'so,': 0.37; 'list': 0.37; 'starting': 0.37; 'step': 0.37; 'skip:& 10': 0.38; 'nov': 0.38; 'to:addr :python-list': 0.38; 'pm,': 0.38; 'subject:[': 0.39; 'to:addr:python.org': 0.39; 'expression': 0.60; 'email addr:gmail.com': 0.63; 'name': 0.63; 'story': 0.63; 'real': 0.63; 'skip:n 10': 0.64; 'determine': 0.67; 'invalid': 0.68; 'do:': 0.91; 'examine': 0.93; '2013': 0.98 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type; bh=Vq7MbLr4DFINpl/hj0aVEL31orB4QC9W8Qdkyr+sQAQ=; b=SN+5Pog1gu0zw6OokaGESqHThPgIFCNnAjoXhLazlY4r5XwmgEhzrgXH091No6b1Y8 /8tpzqhcTgLPGiPpfYRjvLq+7tg7OG2XlDJrElfyo8feOjG9Ys6+nyBbZRR89jH/sN6g DsSuu76UXEuyciayIdhJpNPAb49YeqB+dRYQXoKkzjohOn9b9u2hAGdB9Hxy9cVZgtog G54hepZe2ncrfiyHrvpxFimAZjff6kLw7wPCWP20H8afSHQEfnSt3WCpjb5SA3SeJhQj xlszV2RJ1LrLndw+VfosSb6Waj1Ha2izQiOjecen0SCcZNfVgLldQHwpbvrQKBsOyv0D X/NA== MIME-Version: 1.0 X-Received: by 10.66.161.38 with SMTP id xp6mr18233646pab.145.1385583794916; Wed, 27 Nov 2013 12:23:14 -0800 (PST) In-Reply-To: References: <6cdefe87-5703-4caf-91c0-b4a02674a1e5@googlegroups.com> Date: Wed, 27 Nov 2013 13:23:14 -0700 Subject: Re: '_[1]' in .co_names using builtin compile() in Python 2.6 From: Ian Kelly To: Python Content-Type: multipart/alternative; boundary=047d7b6d87b2e7137f04ec2e5d96 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list 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: 75 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1385583798 news.xs4all.nl 15908 [2001:888:2000:d::a6]:33084 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:60634 --047d7b6d87b2e7137f04ec2e5d96 Content-Type: text/plain; charset=ISO-8859-1 On Nov 27, 2013 2:11 PM, "Ned Batchelder" wrote: > > On 11/27/13 2:40 PM, magnus.lycka@gmail.com wrote: >> >> So, in the case of "a.b + x" I'm really just interested in a and x, not b. So the (almost) whole story is that I do: >> >> # Find names not starting with ".", i.e a & b in "a.c + b" >> abbr_expr = re.sub(r"\.\w+", "", expr) >> names = compile(abbr_expr, '', 'eval').co_names >> # Python 2.6 returns '_[1]' in co_names for list comprehension. Bug? >> names = [name for name in names if re.match(r'\w+$', name)] >> >> for name in names: >> if name not in allowed_names: >> raise NameError('Name: %s not permitted in expression: %s' % (name, expr)) >> > > I don't know of a better way to determine the real names in the expression. I doubt Python will insert a valid name into the namespace, since it doesn't want to step on real user names. The simplest way to do that is to autogenerate invalid names, like "_[1]" (I wonder why it isn't "_[0]"?) One possible alternative is to use the ast module to examine the parse tree of the expression instead of the generated code object. Hard to say whether that would be "better". --047d7b6d87b2e7137f04ec2e5d96 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable


On Nov 27, 2013 2:11 PM, "Ned Batchelder" <ned@nedbatchelder.com> wrote:
>
> On 11/27/13 2:40 PM, magnus.= lycka@gmail.com wrote:
>>
>> So, in the case of "a.b + x" I'm really just interes= ted in a and x, not b. So the (almost) whole story is that I do:
>>
>> =A0 =A0 =A0# Find names not starting with ".", i.e a &am= p; b in "a.c + b"
>> =A0 =A0 =A0abbr_expr =3D re.sub(r"\.\w+", "", = expr)
>> =A0 =A0 =A0names =3D compile(abbr_expr, '<string>', = 'eval').co_names
>> =A0 =A0 =A0# Python 2.6 returns '_[1]' in co_names for lis= t comprehension. Bug?
>> =A0 =A0 =A0names =3D [name for name in names if re.match(r'\w+= $', name)]
>>
>> =A0 =A0 =A0for name in names:
>> =A0 =A0 =A0 =A0 =A0if name not in allowed_names:
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0raise NameError('Name: %s not permi= tted in expression: %s' % (name, expr))
>>
>
> I don't know of a better way to determine the real names in the ex= pression. =A0I doubt Python will insert a valid name into the namespace, si= nce it doesn't want to step on real user names. =A0The simplest way to = do that is to autogenerate invalid names, like "_[1]" (I wonder w= hy it isn't "_[0]"?)

One possible alternative is to use the ast module to examine= the parse tree of the expression instead of the generated code object. Har= d to say whether that would be "better".

--047d7b6d87b2e7137f04ec2e5d96--