tox: TypeError: write() argument must be str, not bytes
I get the following traceback when there is an error on Linux and Windows with Python 3.5.
Not sure which tox version is used. I guess the current one, because I use devpi test and it creates a fresh virtualenv.
The only info I have is: platform win32 – Python 3.5.2, pytest-3.0.5, py-1.4.31, pluggy-0.4.0
Traceback (most recent call last):
File "/home/devpi/devpi/bin/devpi", line 11, in <module>
sys.exit(main())
File "/home/devpi/devpi/local/lib/python3.5/site-packages/devpi/main.py", line 30, in main
return method(hub, hub.args)
File "/home/devpi/devpi/local/lib/python3.5/site-packages/devpi/test.py", line 223, in main
ret = devindex.runtox(*args)
File "/home/devpi/devpi/local/lib/python3.5/site-packages/devpi/test.py", line 92, in runtox
ret = toxrunner(toxargs)
File "/home/devpi/devpi/local/lib/python3.5/site-packages/tox/session.py", line 39, in main
retcode = Session(config).runcommand()
File "/home/devpi/devpi/local/lib/python3.5/site-packages/tox/session.py", line 375, in runcommand
return self.subcommand_test()
File "/home/devpi/devpi/local/lib/python3.5/site-packages/tox/session.py", line 526, in subcommand_test
if self.setupenv(venv):
File "/home/devpi/devpi/local/lib/python3.5/site-packages/tox/session.py", line 434, in setupenv
status = venv.update(action=action)
File "/home/devpi/devpi/local/lib/python3.5/site-packages/tox/venv.py", line 142, in update
action.setactivity("create", self.envconfig.envdir)
File "/home/devpi/devpi/local/lib/python3.5/site-packages/tox/session.py", line 96, in setactivity
self.report.verbosity0("%s %s: %s" % (self.venvname, name, msg), bold=True)
File "/home/devpi/devpi/local/lib/python3.5/site-packages/tox/session.py", line 301, in verbosity0
self.logline("%s" % msg, **opts)
File "/home/devpi/devpi/local/lib/python3.5/site-packages/tox/session.py", line 297, in logline
self.tw.line("%s" % msg, **opts)
File "/home/devpi/devpi/local/lib/python3.5/site-packages/py/_io/terminalwriter.py", line 201, in line
self.write(s, **kw)
File "/home/devpi/devpi/local/lib/python3.5/site-packages/py/_io/terminalwriter.py", line 198, in write
write_out(self._file, markupmsg)
File "/home/devpi/devpi/local/lib/python3.5/site-packages/py/_io/terminalwriter.py", line 333, in write_out
fil.write(msg)
File "/home/devpi/devpi/lib/python3.5/codecs.py", line 377, in write
self.stream.write(data)
TypeError: write() argument must be str, not bytes
About this issue
- Original URL
- State: closed
- Created 8 years ago
- Comments: 17 (10 by maintainers)
Commits related to this issue
- not reproducing https://github.com/tox-dev/tox/issues/426 yet ... — committed to obestwalter/tox-reproducers by obestwalter 7 years ago
- Fix #426 by writing directly to stdout buffer if possible to prevent str vs bytes issues. — committed to fschulze/tox by fschulze 6 years ago
- Fix #426 by writing directly to stdout buffer if possible to prevent str vs bytes issues. — committed to fschulze/tox by fschulze 6 years ago
I’ve spent a few hours trying to figure this out, here is where I’m up to:
The issue is within the TextIOWrapper (
stdout)."TypeError: write() argument must be str, not bytesdoes not mean that the argument you passed was actually bytes,sys.stdoutis a buffered stream with.line_bufferingenabled, which means something written to the line earlier could be the bytes, not the string you just submitted.So, the issue is that something has sent bytes to the stdout stream that shouldn’t have.
My strong suspicion is that it’s related to the Popen/stdout/stderr buffer for the threads that Tox instantiates. Since Tox is designed to call Python 3 and Python 2 equally, it’s probably in a subprocess that’s the issue, not in the main tox application.
There are 2 places that concern me, one is- https://github.com/tox-dev/tox/blob/master/tox/session.py#L129-L146 which calls
sys.stdoutinstead of using thestdoutas overridden by the user.The second and I think the culprit (because this is almost impossible to properly debug is https://github.com/tox-dev/tox/blob/master/tox/interpreters.py#L74-L77
Here is my tox.ini
If I call my process with the environments, py27 it’s fine, py36 is fine, py36,p27 is fine.
Whenever I include the environment ‘lint’ it crashes. Yes, I know this tox.ini doesn’t make any sense because I haven’t defined what the lint environment should run. It calls by default Python 3.6, because that’s what my virtualenv is configured with.
The error from Tox is on invocation
Note, my test suite is supposed to fail, I’m checking that it fails properly.
So, in summary if you are getting this issue, try selecting only certain environments then try running your lint/pylint etc. environments under Python 2.7 virtualenv’s instead of 3+ @obestwalter
Just “for the record” or in case somebody else runs into the same isse: I’ve adjusted a small project to use Python 3 and running
toxgave me the same error message. I’ve reproduced the issue with a fairly small setup:foo.py:test_foo.py:setup.py:tox.ini:Running
toxgave me this:Without the
import pdb; pdb.set_trace()line things were fine. But of course at that point — i.e. after removing pretty much everything else — I already had suspect, and as it turns out, after removingpdbppfrom the setup, I get my pdb prompt back… 😃Now I wonder if we could or rather should try to detect the presence of
pdbppand issue a big warning that might save some other people from spending time on this (or merely wondering if Python 3.6’spdbis broken? 😃)