Home > Software engineering >  Confusing error message when passing bytes to print with file pointing to a binary file
Confusing error message when passing bytes to print with file pointing to a binary file

Time:10-17

The documentation for the print function specifies that the input argument is coerced to string. However, if bytes are passed and the file= parameter points to a file open for binary write, the error message produced is:

>>> out = open('temp', 'wb')
>>> print(b'abc', file=out)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: write() argument 1 must be bytes or buffer, not str

which is, to say the least, confusing, since I clearly passed print a bytes object as argument 1.

CodePudding user response:

As you said, print coerces its arguments to strings, meaning it is no longer bytes when the write is attempted, but the string "b'abc'". If you're planning to write bytes, out.write(b'abc') is one easy way to do that.

CodePudding user response:

If you check the documentation in detail here it specifies, that:

Since printed arguments are converted to text strings, print() cannot be used with binary mode file objects. For these, use file.write(...) instead.

From here on out, I'm guessing, but in reality, what your code is doing is:

  1. Receives a byte string in the print statement
  2. Coerce the byte string into string
  3. Tries to write the string to the file
  4. The file.write() method raises an error, because you are trying to write a string into a file, which is opened in binary write

This can be seen in the error message. Note the err is not coming from the print() method it is raised by the write() method

CodePudding user response:

Use .write() instead of print(). Don't forget to close file after writing.

out = open('temp', 'wb')
out.write(b'abc')
out.close()

CodePudding user response:

I think you want to write in a file. This is my example code, try this out.

with open('temp','wb') as out:
    out.write(b'abc')

It automatically closes the file, no need to close the file again.

CodePudding user response:

The problem here is not the bytes object: it is correctly coerced to a string.

The problem is the binary stream, which cannot accept strings.

We could maybe detect common errors and add a check at the beginning of the print() function? something like

 if isinstance(file, (BufferedWriter, RawIOBase)):
        raise ValueError("file should be a text stream")
  • Related