replacement of rexec?

John Roth newsgroups at jhrothjr.com
Wed Nov 5 09:01:53 CET 2003


This looks rather interesting. I frankly think we need it
as a built-in.

John Roth

"Huaiyu Zhu" <huaiyu at gauss.almaden.ibm.com> wrote in message
news:slrnbqgpsd.5m4.huaiyu at gauss.almaden.ibm.com...
> In article <698f09f8.0310301113.356fd637 at posting.google.com>, Jeremy
> Fincher wrote:
> > Skip Montanaro <skip at pobox.com> wrote in message
news:<mailman.242.1067527420.702.python-list at python.org>...
> >> I'm not aware of anything.  Assuming your inspection process shows the
file
> >> is okay, why not just call execfile()?
> >
> >
> > Probably because that won't get him a useful value :)  He'd have to
> > use eval (but you probably knew that and just typo'ed execfile; I'm
> > mostly just saying it to try and prevent confusion on his part).
>
> That's the point - the file contains multiple strings to be converted to
> python objects.  I've written the following code over the weekend.  It is
> more complicated than I'd like.  Hopefully someone can replace part or all
> of it by some builtin functionality.
>
> #-------------------------------------------------------
> import compiler
> def safe_eval(s):
>     """
>     Evaluate strings that only contains the following structures:
>     const,  tuple,  list,   dict
>     """
>     stmts = compiler.parse(s).node.nodes
>     #print stmts
>     assert len(stmts) == 1
>     node = compiler.parse(s).node.nodes[0]
>     assert node.__class__ == compiler.ast.Discard
>     nodes = node.getChildNodes()
>     assert len(nodes) == 1
>     return safe_assemble(nodes[0])
>
> seq_types = {
>     compiler.ast.Tuple: tuple,
>     compiler.ast.List: list,
>     }
> map_types = {
>     compiler.ast.Dict: dict,
>     }
>
> def safe_assemble(node):
>     """ Recursively assemble parsed ast node """
>     cls = node.__class__
>     if cls == compiler.ast.Const:
>         return node.value
>     elif cls in seq_types:
>         nodes = node.nodes
>         args = map(safe_assemble, nodes)
>         return seq_types[cls](args)
>     elif cls in map_types:
>         keys, values = zip(*node.items)
>         keys = map(safe_assemble, keys)
>         values = map(safe_assemble, values)
>         return map_types[cls](zip(keys, values))
>     else:
>         raise "Type not allowed", cls
>
>
> if __name__ == '__main__':
>     tests = [
>         "3j",
>         "1, 2.5",
>         "['abc', 0xF7]",
>         "1, ['abc', [2,3]], {(4,5):[6.5, 8]}",
>         ]
>     for s in tests:
>         print safe_eval(s)
> #-------------------------------------------------------
>
>
> Huaiyu






More information about the Python-list mailing list