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()
This commit is contained in:
Martin Panter 2016-02-19 23:34:56 +00:00
parent 92849d1721
commit f817a48d17
2 changed files with 28 additions and 20 deletions

View File

@ -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()

View File

@ -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):
# 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):
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")