I have this code which runs fine in Python 2.5 but not in 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"
""")
And I get:
string argument expected, got 'str' Traceback (most recent call last): File "D:\3.py", line 13, in CaptureExec exec(stmt, globals(), globals()) File "", line 3, in TypeError: string argument expected, got 'str'
Python's built-in exec() function allows you to execute arbitrary Python code from a string or compiled code input.
The py Command The default Python interpreter is referenced on Windows using the command py. Using the Command Prompt, you can use the -V option to print out the version. You can also specify the version of Python you'd like to run. For Windows, you can just provide an option like -2.7 to run version 2.7.
io.StringIO
is confusing in Python 2.7 because it's backported from the 3.x bytes/string world. This code gets the same error as yours:
from io import StringIO
sio = StringIO()
sio.write("Hello\n")
causes:
Traceback (most recent call last):
File "so2.py", line 3, in <module>
sio.write("Hello\n")
TypeError: string argument expected, got 'str'
If you are only using Python 2.x, then skip the io
module altogether, and stick with StringIO. If you really want to use io
, change your import to:
from io import BytesIO as StringIO
It's bad news
io.StringIO wants to work with unicode. You might think you can fix it by putting a u
in front of the string you want to print like this
print "%s" % CaptureExec("""
import random
print u"hello world"
""")
however print
is really broken for this as it causes 2 writes to the StringIO. The first one is u"hello world"
which is fine, but then it follows with "\n"
so instead you need to write something like this
print "%s" % CaptureExec("""
import random
sys.stdout.write(u"hello world\n")
""")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With