an eval()-like exec()

A

Abel Daniel

Hi!

A python interactive interpreter works by having the user type in some
code, compiling and running that code, then printing the results. For
printing, the results are turned into strings.

I would like make an interpreter which does this, without the last
part: i.e. where the results are returned as objects, instead of as
strings. I.e. have I would like to see something that behaves like
this:
True

Neither exec() or eval() is usable for this, as far as I see, because
eval can't handle arbitrary python code (eval("import math") ), and
exec() doesn't return the results.

Subclassing an code.InteractiveInterpreter or code.InteractiveConsole
seems like a usable idea, but I couldn't find out what to do to get
the results before they are turned into strings.

Using compile() and then eval() didn't seem usable either.

Any ideas?

Thanks in advance,
Daniel Abel
 
M

Matt McCredie

A python interactive interpreter works by having the user type in some
code, compiling and running that code, then printing the results. For
printing, the results are turned into strings.

I would like make an interpreter which does this, without the last
part: i.e. where the results are returned as objects, instead of as
strings. I.e. have I would like to see something that behaves like
this:

True

Neither exec() or eval() is usable for this, as far as I see, because
eval can't handle arbitrary python code (eval("import math") ), and
exec() doesn't return the results.

Subclassing an code.InteractiveInterpreter or code.InteractiveConsole
seems like a usable idea, but I couldn't find out what to do to get
the results before they are turned into strings.

Using compile() and then eval() didn't seem usable either.

Any ideas?

Well, my first thought is that exec and eval serve two different
purposes, and you should just have both of them and use the
appropriate one based on the situation. However, I think it is
possible to enable the behavior you want:

Code:
def myeval(statement, globals_=None, locals_=None):
    try:
        return eval(statement, globals_, locals_)
    except SyntaxError:
        if locals_ is None:
            import inspect
            locals_ = inspect.currentframe().f_back.f_locals
        exec statement in globals_, locals_

It seems to work for me.

Matt
 
G

Gabriel Genellina

Hi!

A python interactive interpreter works by having the user type in some
code, compiling and running that code, then printing the results. For
printing, the results are turned into strings.

This last stage is done by calling sys.displayhook - you can replace that
function with your own one, and get the object to be printed.
Any of your previous attempts (using compile(...,"single")+eval, using
exec, or creating your own code.InteractiveInterpreter) should work with
this.
 
D

Dustan

A python interactive interpreter works by having the user type in some
code, compiling and running that code, then printing the results. For
printing, the results are turned into strings.
I would like make an interpreter which does this, without the last
part: i.e. where the results are returned as objects, instead of as
strings. I.e. have I would like to see something that behaves like
this:
# this started a new interpreter

Neither exec() or eval() is usable for this, as far as I see, because
eval can't handle arbitrary python code (eval("import math") ), and
exec() doesn't return the results.
Subclassing an code.InteractiveInterpreter or code.InteractiveConsole
seems like a usable idea, but I couldn't find out what to do to get
the results before they are turned into strings.
Using compile() and then eval() didn't seem usable either.
Any ideas?

Well, my first thought is that exec and eval serve two different
purposes, and you should just have both of them and use the
appropriate one based on the situation. However, I think it is
possible to enable the behavior you want:

Code:
def myeval(statement, globals_=None, locals_=None):
try:
return eval(statement, globals_, locals_)
except SyntaxError:
if locals_ is None:
import inspect
locals_ = inspect.currentframe().f_back.f_locals
exec statement in globals_, locals_

It seems to work for me.

Matt

Unless it's something like:

raise_(SyntaxError)

where raise_ is a function equivalent to the corresponding statement.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top