Commit 770b4442 authored by Martin Panter's avatar Martin Panter

Issues #22468, #21996, #22208: Clarify gettarinfo() and TarInfo usage

* The Windows-specific binary notice was probably a Python 2 thing
* Make it more obvious gettarinfo() is based on stat(), and that non-ordinary
  files may need special care
* The file name must be text; suggest dummy arcname as a workaround
* Indicate TarInfo may be used directly, not just via gettarinfo()
parent 5bbb6cc7
...@@ -456,21 +456,28 @@ be finalized; only the internally used file object will be closed. See the ...@@ -456,21 +456,28 @@ be finalized; only the internally used file object will be closed. See the
.. method:: TarFile.addfile(tarinfo, fileobj=None) .. method:: TarFile.addfile(tarinfo, fileobj=None)
Add the :class:`TarInfo` object *tarinfo* to the archive. If *fileobj* is given, Add the :class:`TarInfo` object *tarinfo* to the archive. If *fileobj* is given,
it should be a :term:`binary file`, and
``tarinfo.size`` bytes are read from it and added to the archive. You can ``tarinfo.size`` bytes are read from it and added to the archive. You can
create :class:`TarInfo` objects using :meth:`gettarinfo`. create :class:`TarInfo` objects directly, or by using :meth:`gettarinfo`.
.. note::
On Windows platforms, *fileobj* should always be opened with mode ``'rb'`` to
avoid irritation about the file size.
.. method:: TarFile.gettarinfo(name=None, arcname=None, fileobj=None) .. method:: TarFile.gettarinfo(name=None, arcname=None, fileobj=None)
Create a :class:`TarInfo` object for either the file *name* or the :term:`file Create a :class:`TarInfo` object from the result of :func:`os.stat` or
object` *fileobj* (using :func:`os.fstat` on its file descriptor). You can modify equivalent on an existing file. The file is either named by *name*, or
some of the :class:`TarInfo`'s attributes before you add it using :meth:`addfile`. specified as a :term:`file object` *fileobj* with a file descriptor. If
If given, *arcname* specifies an alternative name for the file in the archive. given, *arcname* specifies an alternative name for the file in the
archive, otherwise, the name is taken from *fileobj*’s
:attr:`~io.FileIO.name` attribute, or the *name* argument. The name
should be a text string.
You can modify
some of the :class:`TarInfo`’s attributes before you add it using :meth:`addfile`.
If the file object is not an ordinary file object positioned at the
beginning of the file, attributes such as :attr:`~TarInfo.size` may need
modifying. This is the case for objects such as :class:`~gzip.GzipFile`.
The :attr:`~TarInfo.name` may also be modified, in which case *arcname*
could be a dummy string.
.. method:: TarFile.close() .. method:: TarFile.close()
......
...@@ -1754,11 +1754,13 @@ class TarFile(object): ...@@ -1754,11 +1754,13 @@ class TarFile(object):
return [tarinfo.name for tarinfo in self.getmembers()] return [tarinfo.name for tarinfo in self.getmembers()]
def gettarinfo(self, name=None, arcname=None, fileobj=None): def gettarinfo(self, name=None, arcname=None, fileobj=None):
"""Create a TarInfo object for either the file `name' or the file """Create a TarInfo object from the result of os.stat or equivalent
object `fileobj' (using os.fstat on its file descriptor). You can on an existing file. The file is either named by `name', or
modify some of the TarInfo's attributes before you add it using specified as a file object `fileobj' with a file descriptor. If
addfile(). If given, `arcname' specifies an alternative name for the given, `arcname' specifies an alternative name for the file in the
file in the archive. archive, otherwise, the name is taken from the 'name' attribute of
'fileobj', or the 'name' argument. The name should be a text
string.
""" """
self._check("awx") self._check("awx")
...@@ -1779,7 +1781,7 @@ class TarFile(object): ...@@ -1779,7 +1781,7 @@ class TarFile(object):
# Now, fill the TarInfo object with # Now, fill the TarInfo object with
# information specific for the file. # information specific for the file.
tarinfo = self.tarinfo() tarinfo = self.tarinfo()
tarinfo.tarfile = self tarinfo.tarfile = self # Not needed
# Use os.stat or os.lstat, depending on platform # Use os.stat or os.lstat, depending on platform
# and if symlinks shall be resolved. # and if symlinks shall be resolved.
...@@ -1946,10 +1948,9 @@ class TarFile(object): ...@@ -1946,10 +1948,9 @@ class TarFile(object):
def addfile(self, tarinfo, fileobj=None): def addfile(self, tarinfo, fileobj=None):
"""Add the TarInfo object `tarinfo' to the archive. If `fileobj' is """Add the TarInfo object `tarinfo' to the archive. If `fileobj' is
given, tarinfo.size bytes are read from it and added to the archive. given, it should be a binary file, and tarinfo.size bytes are read
You can create TarInfo objects using gettarinfo(). from it and added to the archive. You can create TarInfo objects
On Windows platforms, `fileobj' should always be opened with mode directly, or by using gettarinfo().
'rb' to avoid irritation about the file size.
""" """
self._check("awx") self._check("awx")
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment