Problems with "Tarfile.close()"

Chris Angelico rosuav at gmail.com
Fri Dec 20 10:34:28 EST 2019


On Sat, Dec 21, 2019 at 2:29 AM Dr Rainer Woitok
<rainer.woitok at gmail.com> wrote:
>
> Greetings,
>
> One of my Python scripts basically does the following:
>
> source = tarfile.open(name=tar_archive  , mode='r|*')
> dest   = tarfile.open(fileobj=sys.stdout, mode='w|', format=fmt)
>
>  .
>  .
>  .
>
> source.close()
> dest.close()
>
> In an attempt to move my Python scripts  from Python 2.7 to Python 3.6 I
> ran into the problem  that under Python 3.6  the call to  "dest.close()"
> fails:

(I think the fact that it fails when you close the file is a red
herring; it would fail at some point, and it happens to hold things
over until it closes.)

> Traceback (most recent call last):
>  File ".../tar_archive.copy", line 137, in <module>
>  dest.close()
>  File "/usr/lib64/python3.6/tarfile.py", line 1742, in close
>  self.fileobj.close()
>  File "/usr/lib64/python3.6/tarfile.py", line 467, in close
>  self.fileobj.write(self.buf)
> TypeError: write() argument must be str, not bytes
>
> What am I doing wrong?   By the way:  since on some hosts this script is
> running on  the transition from Python 2.7 to Python 3.x will not happen
> immediately, I need a solution which works with both versions.
>

Possibly the easiest fix would be to open all files in binary mode. I
think your content is binary anyway by the look of it. Just add the
letter "b" to the end of your open file modes, and on Py2, it'll
ensure that no newline conversion happens (mainly an issue on Windows,
which is why you probably don't feel the need to do this), but on Py3,
it means that it expects bytestrings everywhere.

If that *doesn't* work, then you may need to mark some of your strings
as binary, if you have unadorned strings containing ASCII data.

ChrisA


More information about the Python-list mailing list