getting values from an "exec" statement

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Toby Donaldson

    getting values from an "exec" statement

    Hi all,

    I'm designing an educational application that will run Python code and
    check the output against a pre-define answer. I want to use the "exec"
    statement to run the code, but I don't know how to get output from it.

    For instance, exec works like this:
    [color=blue][color=green][color=darkred]
    >>> code = """[/color][/color][/color]
    for i in xrange(1, 5):
    print i
    """[color=blue][color=green][color=darkred]
    >>> exec code[/color][/color][/color]
    1
    2
    3
    4

    I want to store the values output by the print statement in a list. Is
    there anyway to re-direct the output of the exec statement?

    Also, it would be nice if exec had a timeout that automatically
    haulted code that ran for too long. Is there a standard trick for
    this? I expect I would have to run it in its own thread and kill the
    thread when it takes too long (which reminds me I don't know anything
    about Python threads!).

    Toby
  • Greg Krohn

    #2
    Re: getting values from an "exec&quot ; statement


    "Toby Donaldson" <tjd@sfu.ca> wrote in message
    news:ad32251c.0 309301513.1b11a 8ce@posting.goo gle.com...[color=blue]
    > Hi all,
    >
    > I'm designing an educational application that will run Python code and
    > check the output against a pre-define answer. I want to use the "exec"
    > statement to run the code, but I don't know how to get output from it.
    >
    > For instance, exec works like this:
    >[color=green][color=darkred]
    > >>> code = """[/color][/color]
    > for i in xrange(1, 5):
    > print i
    > """[color=green][color=darkred]
    > >>> exec code[/color][/color]
    > 1
    > 2
    > 3
    > 4
    >
    > I want to store the values output by the print statement in a list. Is
    > there anyway to re-direct the output of the exec statement?[/color]

    The code run by exec is run in the same scope as the exec (by default). So
    anything done "in" the exec is visible to things "outside" the exec. Like
    this:

    l = []
    code = """for i in xrange(1, 5):
    l.append(i)"""
    exec code
    print l


    greg


    Comment

    • Paul Rubin

      #3
      Re: getting values from an &quot;exec&quot ; statement

      Python isn't really set up for what you're doing. The exec'd code can
      too easily mess around with the calling code, if it's malicious.
      You're best off just running the student's program in a separate
      process and capturing the output.

      Comment

      • Erik Max Francis

        #4
        Re: getting values from an &quot;exec&quot ; statement

        Toby Donaldson wrote:
        [color=blue]
        > I'm designing an educational application that will run Python code and
        > check the output against a pre-define answer. I want to use the "exec"
        > statement to run the code, but I don't know how to get output from it.[/color]

        Override sys.stdout with a proxy that will capture what's send to stdout
        so you can do something with it. Of course, this won't help your second
        problem -- trying to set up a useful sandbox -- but it's a start for
        non-malicious code.

        --
        Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
        __ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
        / \ I am still learning.
        \__/ (Michaelangelo' s motto)

        Comment

        • Miki Tebeka

          #5
          Re: getting values from an &quot;exec&quot ; statement

          Hello Toby,
          [color=blue]
          > I'm designing an educational application that will run Python code and
          > check the output against a pre-define answer. I want to use the "exec"
          > statement to run the code, but I don't know how to get output from it.[/color]
          [...]

          The battaries are there already...


          HTH.
          Miki

          Comment

          • Alex Martelli

            #6
            Re: getting values from an &quot;exec&quot ; statement

            Toby Donaldson wrote:
            [color=blue]
            > Hi all,
            >
            > I'm designing an educational application that will run Python code and
            > check the output against a pre-define answer. I want to use the "exec"
            > statement to run the code, but I don't know how to get output from it.[/color]

            I see you already received answers to this part.
            [color=blue]
            > I want to store the values output by the print statement in a list. Is
            > there anyway to re-direct the output of the exec statement?[/color]

            I would suggest sys.stdout=cStr ingIO.StringIO( ) right before the
            exec (and store it somewhere, and restore the previous value, in
            a finally clause -- you DO want to have the exec inside a try
            clause, of course, since it's so likely that exec will raise
            exceptions!).

            [color=blue]
            > Also, it would be nice if exec had a timeout that automatically
            > haulted code that ran for too long. Is there a standard trick for
            > this? I expect I would have to run it in its own thread and kill the
            > thread when it takes too long (which reminds me I don't know anything
            > about Python threads!).[/color]

            In Python 2.3, you can run the exec in the main thread after
            setting up a secondary "watchdog" thread that calls function
            thread.interrup t_main() after sleeping for a given length of
            time; this will raise a KeyboardInterru pt in the main thread,
            just as if somebody at the kbd had banged on Ctrl-C or the like.

            Of course, this does NOT protect you against MALICIOUS code in
            the exec -- THAT might easily capture and ignore the exception.
            Your code will be MUCH more solid if you can arrange to execute
            the untrusted code in a separate process (not hard on Linux,
            BSD, and the like; possible -- though not quite as trivial -- on
            Windows, too). But for "normal mistakes", it's reasonably OK.


            Alex

            Comment

            Working...