python 2.7 / exec / ¿qué está mal?

Tengo este código que funciona bien en Python 2.5 pero no en 2.7:

import sys import traceback try: from io import StringIO except: from StringIO import StringIO def CaptureExec(stmt): oldio = (sys.stdin, sys.stdout, sys.stderr) sio = StringIO() sys.stdout = sys.stderr = sio try: exec(stmt, globals(), globals()) out = sio.getvalue() except Exception, e: out = str(e) + "\n" + traceback.format_exc() sys.stdin, sys.stdout, sys.stderr = oldio return out print "%s" % CaptureExec(""" import random print "hello world" """) 

Y me sale:

 Se esperaba un argumento de cadena, se obtuvo 'str'
 Rastreo (llamadas recientes más última):
   Archivo "D: \ 3.py", línea 13, en CaptureExec
     exec (stmt, globals (), globals ())
   Archivo "", línea 3, en 
 TypeError: argumento de cadena esperado, obtuve 'str'

Related of "python 2.7 / exec / ¿qué está mal?"

io.StringIO es confuso en Python 2.7 porque está portada desde el mundo de 3.x bytes / cadena. Este código recibe el mismo error que el tuyo:

 from io import StringIO sio = StringIO() sio.write("Hello\n") 

causas:

 Traceback (most recent call last): File "so2.py", line 3, in  sio.write("Hello\n") TypeError: string argument expected, got 'str' 

Si solo está utilizando Python 2.x, omita el módulo io completo y siga con StringIO. Si realmente quieres usar io , cambia tu importación a:

 from io import BytesIO as StringIO 

son malas noticias

io.StringIO quiere trabajar con unicode. Podría pensar que puede arreglarlo colocando una u delante de la cadena que desea imprimir de esta manera

 print "%s" % CaptureExec(""" import random print u"hello world" """) 

sin embargo, la print está realmente rota para esto ya que causa 2 escrituras en StringIO. El primero es u"hello world" que está bien, pero luego sigue con "\n"

así que en lugar de eso necesitas escribir algo como esto

 print "%s" % CaptureExec(""" import random sys.stdout.write(u"hello world\n") """)