:mod:`!tarfile` --- Read and write tar archive files
====================================================

.. module:: tarfile
   :synopsis: Read and write tar-format archive files.

.. moduleauthor:: Lars Gustäbel <lars@gustaebel.de>
.. sectionauthor:: Lars Gustäbel <lars@gustaebel.de>

**Source code:** :source:`Lib/tarfile.py`

--------------

The :mod:`tarfile` module makes it possible to read and write tar
archives, including those using gzip, bz2 and lzma compression.
Use the :mod:`zipfile` module to read or write :file:`.zip` files, or the
higher-level functions in :ref:`shutil <archiving-operations>`.

Some facts and figures:

* reads and writes :mod:`gzip`, :mod:`bz2`, :mod:`compression.zstd`, and
  :mod:`lzma` compressed archives if the respective modules are available.

  ..
     The following paragraph should be similar to ../includes/optional-module.rst

  If any of these :term:`optional modules <optional module>` are missing from
  your copy of CPython, look for documentation from your distributor (that is,
  whoever provided Python to you).
  If you are the distributor, see :ref:`optional-module-requirements`.

* read/write support for the POSIX.1-1988 (ustar) format.

* read/write support for the GNU tar format including *longname* and *longlink*
  extensions, read-only support for all variants of the *sparse* extension
  including restoration of sparse files.

* read/write support for the POSIX.1-2001 (pax) format.

* handles directories, regular files, hardlinks, symbolic links, fifos,
  character devices and block devices and is able to acquire and restore file
  information like timestamp, access permissions and owner.

.. versionchanged:: 3.3
   Added support for :mod:`lzma` compression.

.. versionchanged:: 3.12
   Archives are extracted using a :ref:`filter <tarfile-extraction-filter>`,
   which makes it possible to either limit surprising/dangerous features,
   or to acknowledge that they are expected and the archive is fully trusted.

.. versionchanged:: 3.14
   Set the default extraction filter to :func:`data <data_filter>`,
   which disallows some dangerous features such as links to absolute paths
   or paths outside of the destination. Previously, the filter strategy
   was equivalent to :func:`fully_trusted <fully_trusted_filter>`.

.. versionchanged:: 3.14

   Added support for Zstandard compression using :mod:`compression.zstd`.

.. function:: open(name=None, mode='r', fileobj=None, bufsize=10240, **kwargs)

   Return a :class:`TarFile` object for the pathname *name*. For detailed
   information on :class:`TarFile` objects and the keyword arguments that are
   allowed, see :ref:`tarfile-objects`.

   *mode* has to be a string of the form ``'filemode[:compression]'``, it defaults
   to ``'r'``. Here is a full list of mode combinations:

   +------------------+---------------------------------------------+
   | mode             | action                                      |
   +==================+=============================================+
   | ``'r'`` or       | Open for reading with transparent           |
   | ``'r:*'``        | compression (recommended).                  |
   +------------------+---------------------------------------------+
   | ``'r:'``         | Open for reading exclusively without        |
   |                  | compression.                                |
   +------------------+---------------------------------------------+
   | ``'r:gz'``       | Open for reading with gzip compression.     |
   +------------------+---------------------------------------------+
   | ``'r:bz2'``      | Open for reading with bzip2 compression.    |
   +------------------+---------------------------------------------+
   | ``'r:xz'``       | Open for reading with lzma compression.     |
   +------------------+---------------------------------------------+
   | ``'r:zst'``      | Open for reading with Zstandard compression.|
   +------------------+---------------------------------------------+
   | ``'x'`` or       | Create a tarfile exclusively without        |
   | ``'x:'``         | compression.                                |
   |                  | Raise a :exc:`FileExistsError` exception    |
   |                  | if it already exists.                       |
   +------------------+---------------------------------------------+
   | ``'x:gz'``       | Create a tarfile with gzip compression.     |
   |                  | Raise a :exc:`FileExistsError` exception    |
   |                  | if it already exists.                       |
   +------------------+---------------------------------------------+
   | ``'x:bz2'``      | Create a tarfile with bzip2 compression.    |
   |                  | Raise a :exc:`FileExistsError` exception    |
   |                  | if it already exists.                       |
   +------------------+---------------------------------------------+
   | ``'x:xz'``       | Create a tarfile with lzma compression.     |
   |                  | Raise a :exc:`FileExistsError` exception    |
   |                  | if it already exists.                       |
   +------------------+---------------------------------------------+
   | ``'x:zst'``      | Create a tarfile with Zstandard compression.|
   |                  | Raise a :exc:`FileExistsError` exception    |
   |                  | if it already exists.                       |
   +------------------+---------------------------------------------+
   | ``'a'`` or       | Open for appending with no compression. The |
   | ``'a:'``         | file is created if it does not exist.       |
   +------------------+---------------------------------------------+
   | ``'w'`` or       | Open for uncompressed writing.              |
   | ``'w:'``         |                                             |
   +------------------+---------------------------------------------+
   | ``'w:gz'``       | Open for gzip compressed writing.           |
   +------------------+---------------------------------------------+
   | ``'w:bz2'``      | Open for bzip2 compressed writing.          |
   +------------------+---------------------------------------------+
   | ``'w:xz'``       | Open for lzma compressed writing.           |
   +------------------+---------------------------------------------+
   | ``'w:zst'``      | Open for Zstandard compressed writing.      |
   +------------------+---------------------------------------------+

   Note that ``'a:gz'``, ``'a:bz2'`` or ``'a:xz'`` is not possible. If *mode*
   is not suitable to open a certain (compressed) file for reading,
   :exc:`ReadError` is raised. Use *mode* ``'r'`` to avoid this.  If a
   compression method is not supported, :exc:`CompressionError` is raised.

   If *fileobj* is specified, it is used as an alternative to a :term:`file object`
   opened in binary mode for *name*. It is supposed to be at position 0.

   For modes ``'w:gz'``, ``'x:gz'``, ``'w|gz'``, ``'w:bz2'``, ``'x:bz2'``,
   ``'w|bz2'``, :func:`tarfile.open` accepts the keyword argument
   *compresslevel* (default ``6``) to specify the compression level of the file.

   For modes ``'w:xz'``, ``'x:xz'`` and ``'w|xz'``, :func:`tarfile.open` accepts the
   keyword argument *preset* to specify the compression level of the file.

   For modes ``'w:zst'``, ``'x:zst'`` and ``'w|zst'``, :func:`tarfile.open`
   accepts the keyword argument *level* to specify the compression level of
   the file. The keyword argument *options* may also be passed, providing
   advanced Zstandard compression parameters described by
   :class:`~compression.zstd.CompressionParameter`. The keyword argument
   *zstd_dict* can be passed to provide a :class:`~compression.zstd.ZstdDict`,
   a Zstandard dictionary used to improve compression of smaller amounts of
   data.

   For special purposes, there is a second format for *mode*:
   ``'filemode|[compression]'``.  :func:`tarfile.open` will return a :class:`TarFile`
   object that processes its data as a stream of blocks.  No random seeking will
   be done on the file. If given, *fileobj* may be any object that has a
   :meth:`~io.RawIOBase.read` or :meth:`~io.RawIOBase.write` method
   (depending on the *mode*) that works with bytes.
   *bufsize* specifies the blocksize and defaults to ``20 * 512`` bytes.
   Use this variant in combination with e.g. ``sys.stdin.buffer``, a socket
   :term:`file object` or a tape device.
   However, such a :class:`TarFile` object is limited in that it does
   not allow random access, see :ref:`tar-examples`.  The currently
   possible modes:

   +-------------+--------------------------------------------+
   | Mode        | Action                                     |
   +=============+============================================+
   | ``'r|*'``   | Open a *stream* of tar blocks for reading  |
   |             | with transparent compression.              |
   +-------------+--------------------------------------------+
   | ``'r|'``    | Open a *stream* of uncompressed tar blocks |
   |             | for reading.                               |
   +-------------+--------------------------------------------+
   | ``'r|gz'``  | Open a gzip compressed *stream* for        |
   |             | reading.                                   |
   +-------------+--------------------------------------------+
   | ``'r|bz2'`` | Open a bzip2 compressed *stream* for       |
   |             | reading.                                   |
   +-------------+--------------------------------------------+
   | ``'r|xz'``  | Open an lzma compressed *stream* for       |
   |             | reading.                                   |
   +-------------+--------------------------------------------+
   | ``'r|zst'`` | Open a Zstandard compressed *stream* for   |
   |             | reading.                                   |
   +-------------+--------------------------------------------+
   | ``'w|'``    | Open an uncompressed *stream* for writing. |
   +-------------+--------------------------------------------+
   | ``'w|gz'``  | Open a gzip compressed *stream* for        |
   |             | writing.                                   |
   +-------------+--------------------------------------------+
   | ``'w|bz2'`` | Open a bzip2 compressed *stream* for       |
   |             | writing.                                   |
   +-------------+--------------------------------------------+
   | ``'w|xz'``  | Open an lzma compressed *stream* for       |
   |             | writing.                                   |
   +-------------+--------------------------------------------+
   | ``'w|zst'`` | Open a Zstandard compressed *stream* for   |
   |             | writing.                                   |
   +-------------+--------------------------------------------+

   .. versionchanged:: 3.5
      The ``'x'`` (exclusive creation) mode was added.

   .. versionchanged:: 3.6
      The *name* parameter accepts a :term:`path-like object`.

   .. versionchanged:: 3.12
      The *compresslevel* keyword argument also works for streams.

   .. versionchanged:: 3.14
      The *preset* keyword argument also works for streams.

   .. versionchanged:: 3.15
      The default compression level was reduced to 6 (down from 9).
      It is the default level used by most compression tools and a better
      tradeoff between speed and performance.

.. class:: TarFile
   :noindex:

   Class for reading and writing tar archives. Do not use this class directly:
   use :func:`tarfile.open` instead. See :ref:`tarfile-objects`.


.. function:: is_tarfile(name)

   Return :const:`True` if *name* is a tar archive file, that the :mod:`tarfile`
   module can read. *name* may be a :class:`str`, file, or file-like object.

   .. versionchanged:: 3.9
      Support for file and file-like objects.


The :mod:`tarfile` module defines the following exceptions:


.. exception:: TarError

   Base class for all :mod:`tarfile` exceptions.


.. exception:: ReadError

   Is raised when a tar archive is opened, that either cannot be handled by the
   :mod:`tarfile` module or is somehow invalid.


.. exception:: CompressionError

   Is raised when a compression method is not supported or when the data cannot be
   decoded properly.


.. exception:: StreamError

   Is raised for the limitations that are typical for stream-like :class:`TarFile`
   objects.


.. exception:: ExtractError

   Is raised for *non-fatal* errors when using :meth:`TarFile.extract`, but only if
   :attr:`TarFile.errorlevel`\ ``== 2``.


.. exception:: HeaderError

   Is raised by :meth:`TarInfo.frombuf` if the buffer it gets is invalid.


.. exception:: FilterError

   Base class for members :ref:`refused <tarfile-extraction-refuse>` by
   filters.

   .. attribute:: tarinfo

      Information about the member that the filter refused to extract,
      as :ref:`TarInfo <tarinfo-objects>`.

.. exception:: AbsolutePathError

   Raised to refuse extracting a member with an absolute path.

.. exception:: OutsideDestinationError

   Raised to refuse extracting a member outside the destination directory.

.. exception:: SpecialFileError

   Raised to refuse extracting a special file (e.g. a device or pipe).

.. exception:: AbsoluteLinkError

   Raised to refuse extracting a symbolic link with an absolute path.

.. exception:: LinkOutsideDestinationError

   Raised to refuse extracting a symbolic link pointing outside the destination
   directory.

.. exception:: LinkFallbackError

   Raised to refuse emulating a link (hard or symbolic) by extracting another
   archive member, when that member would be rejected by the filter location.
   The exception that was raised to reject the replacement member is available
   as :attr:`!BaseException.__context__`.

   .. versionadded:: 3.15


The following constants are available at the module level:

.. data:: ENCODING

   The default character encoding: ``'utf-8'`` on Windows, the value returned by
   :func:`sys.getfilesystemencoding` otherwise.

.. data:: REGTYPE
          AREGTYPE

   A regular file :attr:`~TarInfo.type`.

.. data:: LNKTYPE

   A link (inside tarfile) :attr:`~TarInfo.type`.

.. data:: SYMTYPE

   A symbolic link :attr:`~TarInfo.type`.

.. data:: CHRTYPE

   A character special device :attr:`~TarInfo.type`.

.. data:: BLKTYPE

   A block special device :attr:`~TarInfo.type`.

.. data:: DIRTYPE

   A directory :attr:`~TarInfo.type`.

.. data:: FIFOTYPE

   A FIFO special device :attr:`~TarInfo.type`.

.. data:: CONTTYPE

   A contiguous file :attr:`~TarInfo.type`.

.. data:: GNUTYPE_LONGNAME

   A GNU tar longname :attr:`~TarInfo.type`.

.. data:: GNUTYPE_LONGLINK

   A GNU tar longlink :attr:`~TarInfo.type`.

.. data:: GNUTYPE_SPARSE

   A GNU tar sparse file :attr:`~TarInfo.type`.


Each of the following constants defines a tar archive format that the
:mod:`tarfile` module is able to create. See section :ref:`tar-formats` for
details.


.. data:: USTAR_FORMAT

   POSIX.1-1988 (ustar) format.


.. data:: GNU_FORMAT

   GNU tar format.


.. data:: PAX_FORMAT

   POSIX.1-2001 (pax) format.


.. data:: DEFAULT_FORMAT

   The default format for creating archives. This is currently :const:`PAX_FORMAT`.

   .. versionchanged:: 3.8
      The default format for new archives was changed to
      :const:`PAX_FORMAT` from :const:`GNU_FORMAT`.


.. seealso::

   Module :mod:`zipfile`
      Documentation of the :mod:`zipfile` standard module.

   :ref:`archiving-operations`
      Documentation of the higher-level archiving facilities provided by the
      standard :mod:`shutil` module.

   `GNU tar manual, Basic Tar Format <https://www.gnu.org/software/tar/manual/html_node/Standard.html>`_
      Documentation for tar archive files, including GNU tar extensions.


.. _tarfile-objects:

TarFile Objects
---------------

The :class:`TarFile` object provides an interface to a tar archive. A tar
archive is a sequence of blocks. An archive member (a stored file) is made up of
a header block followed by data blocks. It is possible to store a file in a tar
archive several times. Each archive member is represented by a :class:`TarInfo`
object, see :ref:`tarinfo-objects` for details.

A :class:`TarFile` object can be used as a context manager in a :keyword:`with`
statement. It will automatically be closed when the block is completed. Please
note that in the event of an exception an archive opened for writing will not
be finalized; only the internally used file object will be closed. See the
:ref:`tar-examples` section for a use case.

.. versionadded:: 3.2
   Added support for the context management protocol.

.. class:: TarFile(name=None, mode='r', fileobj=None, format=DEFAULT_FORMAT, tarinfo=TarInfo, dereference=False, ignore_zeros=False, encoding=ENCODING, errors='surrogateescape', pax_headers=None, debug=0, errorlevel=1, stream=False)

   All following arguments are optional and can be accessed as instance attributes
   as well.

   *name* is the pathname of the archive. *name* may be a :term:`path-like object`.
   It can be omitted if *fileobj* is given.
   In this case, the file object's :attr:`!name` attribute is used if it exists.

   *mode* is either ``'r'`` to read from an existing archive, ``'a'`` to append
   data to an existing file, ``'w'`` to create a new file overwriting an existing
   one, or ``'x'`` to create a new file only if it does not already exist.

   If *fileobj* is given, it is used for reading or writing data. If it can be
   determined, *mode* is overridden by *fileobj*'s mode. *fileobj* will be used
   from position 0.

   .. note::

      *fileobj* is not closed, when :class:`TarFile` is closed.

   *format* controls the archive format for writing. It must be one of the constants
   :const:`USTAR_FORMAT`, :const:`GNU_FORMAT` or :const:`PAX_FORMAT` that are
   defined at module level. When reading, format will be automatically detected, even
   if different formats are present in a single archive.

   The *tarinfo* argument can be used to replace the default :class:`TarInfo` class
   with a different one.

   If *dereference* is :const:`False`, add symbolic and hard links to the archive. If it
   is :const:`True`, add the content of the target files to the archive. This has no
   effect on systems that do not support symbolic links.

   If *ignore_zeros* is :const:`False`, treat an empty block as the end of the archive.
   If it is :const:`True`, skip empty (and invalid) blocks and try to get as many members
   as possible. This is only useful for reading concatenated or damaged archives.

   *debug* can be set from ``0`` (no debug messages) up to ``3`` (all debug
   messages). The messages are written to ``sys.stderr``.

   *errorlevel* controls how extraction errors are handled,
   see :attr:`the corresponding attribute <TarFile.errorlevel>`.

   The *encoding* and *errors* arguments define the character encoding to be
   used for reading or writing the archive and how conversion errors are going
   to be handled. The default settings will work for most users.
   See section :ref:`tar-unicode` for in-depth information.

   The *pax_headers* argument is an optional dictionary of strings which
   will be added as a pax global header if *format* is :const:`PAX_FORMAT`.

   If *stream* is set to :const:`True` then while reading the archive info about files
   in the archive are not cached, saving memory.

   .. versionchanged:: 3.2
      Use ``'surrogateescape'`` as the default for the *errors* argument.

   .. versionchanged:: 3.5
      The ``'x'`` (exclusive creation) mode was added.

   .. versionchanged:: 3.6
      The *name* parameter accepts a :term:`path-like object`.

   .. versionchanged:: 3.13
      Add the *stream* parameter.

.. classmethod:: TarFile.open(...)

   Alternative constructor. The :func:`tarfile.open` function is actually a
   shortcut to this classmethod.


.. method:: TarFile.getmember(name)

   Return a :class:`TarInfo` object for member *name*. If *name* can not be found
   in the archive, :exc:`KeyError` is raised.

   .. note::

      If a member occurs more than once in the archive, its last occurrence is assumed
      to be the most up-to-date version.


.. method:: TarFile.getmembers()

   Return the members of the archive as a list of :class:`TarInfo` objects. The
   list has the same order as the members in the archive.


.. method:: TarFile.getnames()

   Return the members as a list of their names. It has the same order as the list
   returned by :meth:`getmembers`.


.. method:: TarFile.list(verbose=True, *, members=None)

   Print a table of contents to ``sys.stdout``. If *verbose* is :const:`False`,
   only the names of the members are printed. If it is :const:`True`, output
   similar to that of :program:`ls -l` is produced. If optional *members* is
   given, it must be a subset of the list returned by :meth:`getmembers`.

   .. versionchanged:: 3.5
      Added the *members* parameter.


.. method:: TarFile.next()

   Return the next member of the archive as a :class:`TarInfo` object, when
   :class:`TarFile` is opened for reading. Return :const:`None` if there is no more
   available.


.. method:: TarFile.extractall(path=".", members=None, *, numeric_owner=False, filter=None)

   Extract all members from the archive to the current working directory or
   directory *path*. If optional *members* is given, it must be a subset of the
   list returned by :meth:`getmembers`. Directory information like owner,
   modification time and permissions are set after all members have been extracted.
   This is done to work around two problems: A directory's modification time is
   reset each time a file is created in it. And, if a directory's permissions do
   not allow writing, extracting files to it will fail.

   If *numeric_owner* is :const:`True`, the uid and gid numbers from the tarfile
   are used to set the owner/group for the extracted files. Otherwise, the named
   values from the tarfile are used.

   The *filter* argument specifies how ``members`` are modified or rejected
   before extraction.
   See :ref:`tarfile-extraction-filter` for details.
   It is recommended to set this explicitly only if specific *tar* features
   are required, or as ``filter='data'`` to support Python versions with a less
   secure default (3.13 and lower).

   .. warning::

      Never extract archives from untrusted sources without prior inspection.

      Since Python 3.14, the default (:func:`data <data_filter>`) will prevent
      the most dangerous security issues.
      However, it will not prevent *all* unintended or insecure behavior.
      Read the :ref:`tarfile-extraction-filter` section for details.

   .. versionchanged:: 3.5
      Added the *numeric_owner* parameter.

   .. versionchanged:: 3.6
      The *path* parameter accepts a :term:`path-like object`.

   .. versionchanged:: 3.12
      Added the *filter* parameter.

   .. versionchanged:: 3.14
      The *filter* parameter now defaults to ``'data'``.


.. method:: TarFile.extract(member, path="", set_attrs=True, *, numeric_owner=False, filter=None)

   Extract a member from the archive to the current working directory, using its
   full name. Its file information is extracted as accurately as possible. *member*
   may be a filename or a :class:`TarInfo` object. You can specify a different
   directory using *path*. *path* may be a :term:`path-like object`.
   File attributes (owner, mtime, mode) are set unless *set_attrs* is false.

   The *numeric_owner* and *filter* arguments are the same as
   for :meth:`extractall`.

   .. note::

      The :meth:`extract` method does not take care of several extraction issues.
      In most cases you should consider using the :meth:`extractall` method.

   .. warning::

      Never extract archives from untrusted sources without prior inspection.
      See the warning for :meth:`extractall` for details.

   .. versionchanged:: 3.2
      Added the *set_attrs* parameter.

   .. versionchanged:: 3.5
      Added the *numeric_owner* parameter.

   .. versionchanged:: 3.6
      The *path* parameter accepts a :term:`path-like object`.

   .. versionchanged:: 3.12
      Added the *filter* parameter.


.. method:: TarFile.extractfile(member)

   Extract a member from the archive as a file object. *member* may be
   a filename or a :class:`TarInfo` object. If *member* is a regular file or
   a link, an :class:`io.BufferedReader` object is returned. For all other
   existing members, :const:`None` is returned. If *member* does not appear
   in the archive, :exc:`KeyError` is raised.

   .. versionchanged:: 3.3
      Return an :class:`io.BufferedReader` object.

   .. versionchanged:: 3.13
      The returned :class:`io.BufferedReader` object has the :attr:`!mode`
      attribute which is always equal to ``'rb'``.

.. attribute:: TarFile.errorlevel
   :type: int

   If *errorlevel* is ``0``, errors are ignored when using :meth:`TarFile.extract`
   and :meth:`TarFile.extractall`.
   Nevertheless, they appear as error messages in the debug output when
   *debug* is greater than 0.
   If ``1`` (the default), all *fatal* errors are raised as :exc:`OSError` or
   :exc:`FilterError` exceptions. If ``2``, all *non-fatal* errors are raised
   as :exc:`TarError` exceptions as well.

   Some exceptions, e.g. ones caused by wrong argument types or data
   corruption, are always raised.

   Custom :ref:`extraction filters <tarfile-extraction-filter>`
   should raise :exc:`FilterError` for *fatal* errors
   and :exc:`ExtractError` for *non-fatal* ones.

   Note that when an exception is raised, the archive may be partially
   extracted. It is the user’s responsibility to clean up.

.. attribute:: TarFile.extraction_filter

   .. versionadded:: 3.12

   The :ref:`extraction filter <tarfile-extraction-filter>` used
   as a default for the *filter* argument of :meth:`~TarFile.extract`
   and :meth:`~TarFile.extractall`.

   The attribute may be ``None`` or a callable.
   String names are not allowed for this attribute, unlike the *filter*
   argument to :meth:`~TarFile.extract`.

   If ``extraction_filter`` is ``None`` (the default), extraction methods
   will use the :func:`data <data_filter>` filter by default.

   The attribute may be set on instances or overridden in subclasses.
   It also is possible to set it on the ``TarFile`` class itself to set a
   global default, although, since it affects all uses of *tarfile*,
   it is best practice to only do so in top-level applications or
   :mod:`site configuration <site>`.
   To set a global default this way, a filter function needs to be wrapped in
   :func:`staticmethod` to prevent injection of a ``self`` argument.

   .. versionchanged:: 3.14

      The default filter is set to :func:`data <data_filter>`,
      which disallows some dangerous features such as links to absolute paths
      or paths outside of the destination.
      Previously, the default was equivalent to
      :func:`fully_trusted <fully_trusted_filter>`.

.. method:: TarFile.add(name, arcname=None, recursive=True, *, filter=None)

   Add the file *name* to the archive. *name* may be any type of file
   (directory, fifo, symbolic link, etc.). If given, *arcname* specifies an
   alternative name for the file in the archive. Directories are added
   recursively by default. This can be avoided by setting *recursive* to
   :const:`False`. Recursion adds entries in sorted order.
   If *filter* is given, it
   should be a function that takes a :class:`TarInfo` object argument and
   returns the changed :class:`TarInfo` object. If it instead returns
   :const:`None` the :class:`TarInfo` object will be excluded from the
   archive. See :ref:`tar-examples` for an example.

   .. versionchanged:: 3.2
      Added the *filter* parameter.

   .. versionchanged:: 3.7
      Recursion adds entries in sorted order.


.. method:: TarFile.addfile(tarinfo, fileobj=None)

   Add the :class:`TarInfo` object *tarinfo* to the archive. If *tarinfo* represents
   a non zero-size regular file, the *fileobj* argument should be a :term:`binary file`,
   and ``tarinfo.size`` bytes are read from it and added to the archive.  You can
   create :class:`TarInfo` objects directly, or by using :meth:`gettarinfo`.

   .. versionchanged:: 3.13

      *fileobj* must be given for non-zero-sized regular files.


.. method:: TarFile.gettarinfo(name=None, arcname=None, fileobj=None)

   Create a :class:`TarInfo` object from the result of :func:`os.stat` or
   equivalent on an existing file.  The file is either named by *name*, or
   specified as a :term:`file object` *fileobj* with a file descriptor.
   *name* may be a :term:`path-like object`.  If
   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.

   .. versionchanged:: 3.6
      The *name* parameter accepts a :term:`path-like object`.


.. method:: TarFile.close()

   Close the :class:`TarFile`. In write mode, two finishing zero blocks are
   appended to the archive.


.. attribute:: TarFile.pax_headers
   :type: dict

   A dictionary containing key-value pairs of pax global headers.



.. _tarinfo-objects:

TarInfo Objects
---------------

A :class:`TarInfo` object represents one member in a :class:`TarFile`. Aside
from storing all required attributes of a file (like file type, size, time,
permissions, owner etc.), it provides some useful methods to determine its type.
It does *not* contain the file's data itself.

:class:`TarInfo` objects are returned by :class:`TarFile`'s methods
:meth:`~TarFile.getmember`, :meth:`~TarFile.getmembers` and
:meth:`~TarFile.gettarinfo`.

Modifying the objects returned by :meth:`~TarFile.getmember` or
:meth:`~TarFile.getmembers` will affect all subsequent
operations on the archive.
For cases where this is unwanted, you can use :mod:`copy.copy() <copy>` or
call the :meth:`~TarInfo.replace` method to create a modified copy in one step.

Several attributes can be set to ``None`` to indicate that a piece of metadata
is unused or unknown.
Different :class:`TarInfo` methods handle ``None`` differently:

- The :meth:`~TarFile.extract` or :meth:`~TarFile.extractall` methods will
  ignore the corresponding metadata, leaving it set to a default.
- :meth:`~TarFile.addfile` will fail.
- :meth:`~TarFile.list` will print a placeholder string.

.. class:: TarInfo(name="")

   Create a :class:`TarInfo` object.


.. classmethod:: TarInfo.frombuf(buf, encoding, errors)

   Create and return a :class:`TarInfo` object from string buffer *buf*.

   Raises :exc:`HeaderError` if the buffer is invalid.


.. classmethod:: TarInfo.fromtarfile(tarfile)

   Read the next member from the :class:`TarFile` object *tarfile* and return it as
   a :class:`TarInfo` object.


.. method:: TarInfo.tobuf(format=DEFAULT_FORMAT, encoding=ENCODING, errors='surrogateescape')

   Create a string buffer from a :class:`TarInfo` object. For information on the
   arguments see the constructor of the :class:`TarFile` class.

   .. versionchanged:: 3.2
      Use ``'surrogateescape'`` as the default for the *errors* argument.


A ``TarInfo`` object has the following public data attributes:


.. attribute:: TarInfo.name
   :type: str

   Name of the archive member.


.. attribute:: TarInfo.size
   :type: int

   Size in bytes.


.. attribute:: TarInfo.mtime
   :type: int | float

   Time of last modification in seconds since the :ref:`epoch <epoch>`,
   as in :attr:`os.stat_result.st_mtime`.

   .. versionchanged:: 3.12

      Can be set to ``None`` for :meth:`~TarFile.extract` and
      :meth:`~TarFile.extractall`, causing extraction to skip applying this
      attribute.

.. attribute:: TarInfo.mode
   :type: int

   Permission bits, as for :func:`os.chmod`.

   .. versionchanged:: 3.12

      Can be set to ``None`` for :meth:`~TarFile.extract` and
      :meth:`~TarFile.extractall`, causing extraction to skip applying this
      attribute.

.. attribute:: TarInfo.type

   File type.  *type* is usually one of these constants: :const:`REGTYPE`,
   :const:`AREGTYPE`, :const:`LNKTYPE`, :const:`SYMTYPE`, :const:`DIRTYPE`,
   :const:`FIFOTYPE`, :const:`CONTTYPE`, :const:`CHRTYPE`, :const:`BLKTYPE`,
   :const:`GNUTYPE_SPARSE`.  To determine the type of a :class:`TarInfo` object
   more conveniently, use the ``is*()`` methods below.


.. attribute:: TarInfo.linkname
   :type: str

   Name of the target file name, which is only present in :class:`TarInfo` objects
   of type :const:`LNKTYPE` and :const:`SYMTYPE`.

   For symbolic links (``SYMTYPE``), the *linkname* is relative to the directory
   that contains the link.
   For hard links (``LNKTYPE``), the *linkname* is relative to the root of
   the archive.


.. attribute:: TarInfo.uid
   :type: int

   User ID of the user who originally stored this member.

   .. versionchanged:: 3.12

      Can be set to ``None`` for :meth:`~TarFile.extract` and
      :meth:`~TarFile.extractall`, causing extraction to skip applying this
      attribute.

.. attribute:: TarInfo.gid
   :type: int

   Group ID of the user who originally stored this member.

   .. versionchanged:: 3.12

      Can be set to ``None`` for :meth:`~TarFile.extract` and
      :meth:`~TarFile.extractall`, causing extraction to skip applying this
      attribute.

.. attribute:: TarInfo.uname
   :type: str

   User name.

   .. versionchanged:: 3.12

      Can be set to ``None`` for :meth:`~TarFile.extract` and
      :meth:`~TarFile.extractall`, causing extraction to skip applying this
      attribute.

.. attribute:: TarInfo.gname
   :type: str

   Group name.

   .. versionchanged:: 3.12

      Can be set to ``None`` for :meth:`~TarFile.extract` and
      :meth:`~TarFile.extractall`, causing extraction to skip applying this
      attribute.

.. attribute:: TarInfo.chksum
   :type: int

   Header checksum.


.. attribute:: TarInfo.devmajor
   :type: int

   Device major number.


.. attribute:: TarInfo.devminor
   :type: int

   Device minor number.


.. attribute:: TarInfo.offset
   :type: int

   The tar header starts here.


.. attribute:: TarInfo.offset_data
   :type: int

   The file's data starts here.


.. attribute:: TarInfo.sparse

   Sparse member information.


.. attribute:: TarInfo.pax_headers
   :type: dict

   A dictionary containing key-value pairs of an associated pax extended header.

.. method:: TarInfo.replace(name=..., mtime=..., mode=..., linkname=..., \
                            uid=..., gid=..., uname=..., gname=..., \
                            deep=True)

   .. versionadded:: 3.12

   Return a *new* copy of the :class:`!TarInfo` object with the given attributes
   changed. For example, to return a ``TarInfo`` with the group name set to
   ``'staff'``, use::

       new_tarinfo = old_tarinfo.replace(gname='staff')

   By default, a deep copy is made.
   If *deep* is false, the copy is shallow, i.e. ``pax_headers``
   and any custom attributes are shared with the original ``TarInfo`` object.

A :class:`TarInfo` object also provides some convenient query methods:


.. method:: TarInfo.isfile()

   Return :const:`True` if the :class:`TarInfo` object is a regular file.


.. method:: TarInfo.isreg()

   Same as :meth:`isfile`.


.. method:: TarInfo.isdir()

   Return :const:`True` if it is a directory.


.. method:: TarInfo.issym()

   Return :const:`True` if it is a symbolic link.


.. method:: TarInfo.islnk()

   Return :const:`True` if it is a hard link.


.. method:: TarInfo.ischr()

   Return :const:`True` if it is a character device.


.. method:: TarInfo.isblk()

   Return :const:`True` if it is a block device.


.. method:: TarInfo.isfifo()

   Return :const:`True` if it is a FIFO.


.. method:: TarInfo.isdev()

   Return :const:`True` if it is one of character device, block device or FIFO.


.. _tarfile-extraction-filter:

Extraction filters
------------------

.. versionadded:: 3.12

The *tar* format is designed to capture all details of a UNIX-like filesystem,
which makes it very powerful.
Unfortunately, the features make it easy to create tar files that have
unintended -- and possibly malicious -- effects when extracted.
For example, extracting a tar file can overwrite arbitrary files in various
ways (e.g.  by using absolute paths, ``..`` path components, or symlinks that
affect later members).

In most cases, the full functionality is not needed.
Therefore, *tarfile* supports extraction filters: a mechanism to limit
functionality, and thus mitigate some of the security issues.

.. warning::

   None of the available filters blocks *all* dangerous archive features.
   Never extract archives from untrusted sources without prior inspection.
   See also :ref:`tarfile-further-verification`.

.. seealso::

   :pep:`706`
      Contains further motivation and rationale behind the design.

The *filter* argument to :meth:`TarFile.extract` or :meth:`~TarFile.extractall`
can be:

* the string ``'fully_trusted'``: Honor all metadata as specified in the
  archive.
  Should be used if the user trusts the archive completely, or implements
  their own complex verification.

* the string ``'tar'``: Honor most *tar*-specific features (i.e. features of
  UNIX-like filesystems), but block features that are very likely to be
  surprising or malicious. See :func:`tar_filter` for details.

* the string ``'data'``: Ignore or block most features specific to UNIX-like
  filesystems. Intended for extracting cross-platform data archives.
  See :func:`data_filter` for details.

* ``None`` (default): Use :attr:`TarFile.extraction_filter`.

  If that is also ``None`` (the default), the ``'data'`` filter will be used.

   .. versionchanged:: 3.14

      The default filter is set to :func:`data <data_filter>`.
      Previously, the default was equivalent to
      :func:`fully_trusted <fully_trusted_filter>`.

* A callable which will be called for each extracted member with a
  :ref:`TarInfo <tarinfo-objects>` describing the member and the destination
  path to where the archive is extracted (i.e. the same path is used for all
  members)::

      filter(member: TarInfo, path: str, /) -> TarInfo | None

  The callable is called just before each member is extracted, so it can
  take the current state of the disk into account.
  It can:

  - return a :class:`TarInfo` object which will be used instead of the metadata
    in the archive, or
  - return ``None``, in which case the member will be skipped, or
  - raise an exception to abort the operation or skip the member,
    depending on :attr:`~TarFile.errorlevel`.
    Note that when extraction is aborted, :meth:`~TarFile.extractall` may leave
    the archive partially extracted. It does not attempt to clean up.

Default named filters
~~~~~~~~~~~~~~~~~~~~~

The pre-defined, named filters are available as functions, so they can be
reused in custom filters:

.. function:: fully_trusted_filter(member, path)

   Return *member* unchanged.

   This implements the ``'fully_trusted'`` filter.

.. function:: tar_filter(member, path)

  Implements the ``'tar'`` filter.

  - Strip leading slashes (``/`` and :data:`os.sep`) from filenames.
  - :ref:`Refuse <tarfile-extraction-refuse>` to extract files with absolute
    paths (in case the name is absolute
    even after stripping slashes, e.g. ``C:/foo`` on Windows).
    This raises :class:`~tarfile.AbsolutePathError`.
  - :ref:`Refuse <tarfile-extraction-refuse>` to extract files whose absolute
    path (after following symlinks) would end up outside the destination.
    This raises :class:`~tarfile.OutsideDestinationError`.
  - Clear high mode bits (setuid, setgid, sticky) and group/other write bits
    (:const:`~stat.S_IWGRP` | :const:`~stat.S_IWOTH`).

  Return the modified ``TarInfo`` member.

.. function:: data_filter(member, path)

  Implements the ``'data'`` filter.
  In addition to what ``tar_filter`` does:

  - Normalize link targets (:attr:`TarInfo.linkname`) using
    :func:`os.path.normpath`.
    Note that this removes internal ``..`` components, which may change the
    meaning of the link if the path in :attr:`!TarInfo.linkname` traverses
    symbolic links.

  - :ref:`Refuse <tarfile-extraction-refuse>` to extract links (hard or soft)
    that link to absolute paths, or ones that link outside the destination.

    This raises :class:`~tarfile.AbsoluteLinkError` or
    :class:`~tarfile.LinkOutsideDestinationError`.

    Note that such files are refused even on platforms that do not support
    symbolic links.

  - :ref:`Refuse <tarfile-extraction-refuse>` to extract device files
    (including pipes).
    This raises :class:`~tarfile.SpecialFileError`.

  - For regular files, including hard links:

    - Set the owner read and write permissions
      (:const:`~stat.S_IRUSR` | :const:`~stat.S_IWUSR`).
    - Remove the group & other executable permission
      (:const:`~stat.S_IXGRP` | :const:`~stat.S_IXOTH`)
      if the owner doesn’t have it (:const:`~stat.S_IXUSR`).

  - For other files (directories), set ``mode`` to ``None``, so
    that extraction methods skip applying permission bits.
  - Set user and group info (``uid``, ``gid``, ``uname``, ``gname``)
    to ``None``, so that extraction methods skip setting it.

  Return the modified ``TarInfo`` member.

  Note that this filter does not block *all* dangerous archive features.
  See :ref:`tarfile-further-verification`  for details.

  .. versionchanged:: 3.15

     Link targets are now normalized.


.. _tarfile-extraction-refuse:

Filter errors
~~~~~~~~~~~~~

When a filter refuses to extract a file, it will raise an appropriate exception,
a subclass of :class:`~tarfile.FilterError`.
This will abort the extraction if :attr:`TarFile.errorlevel` is 1 or more.
With ``errorlevel=0`` the error will be logged and the member will be skipped,
but extraction will continue.


.. _tarfile-further-verification:

Hints for further verification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Even with ``filter='data'``, *tarfile* is not suited for extracting untrusted
files without prior inspection.
Among other issues, the pre-defined filters do not prevent denial-of-service
attacks. Users should do additional checks.

Here is an incomplete list of things to consider:

* Extract to a :func:`new temporary directory <tempfile.mkdtemp>`
  to prevent e.g. exploiting pre-existing links, and to make it easier to
  clean up after a failed extraction.
* Disallow symbolic links if you do not need the functionality.
* When working with untrusted data, use external (e.g. OS-level) limits on
  disk, memory and CPU usage.
* Check filenames against an allow-list of characters
  (to filter out control characters, confusables, foreign path separators,
  and so on).
* Check that filenames have expected extensions (discouraging files that
  execute when you “click on them”, or extension-less files like Windows
  special device names).
* Limit the number of extracted files, total size of extracted data,
  filename length (including symlink length), and size of individual files.
* Check for files that would be shadowed on case-insensitive filesystems.

Also note that:

* Tar files may contain multiple versions of the same file.
  Later ones are expected to overwrite any earlier ones.
  This feature is crucial to allow updating tape archives, but can be abused
  maliciously.
* *tarfile* does not protect against issues with “live” data,
  e.g. an attacker tinkering with the destination (or source) directory while
  extraction (or archiving) is in progress.


Supporting older Python versions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Extraction filters were added to Python 3.12, but may be backported to older
versions as security updates.
To check whether the feature is available, use e.g.
``hasattr(tarfile, 'data_filter')`` rather than checking the Python version.

The following examples show how to support Python versions with and without
the feature.
Note that setting ``extraction_filter`` will affect any subsequent operations.

* Fully trusted archive::

    my_tarfile.extraction_filter = (lambda member, path: member)
    my_tarfile.extractall()

* Use the ``'data'`` filter if available, but revert to Python 3.11 behavior
  (``'fully_trusted'``) if this feature is not available::

    my_tarfile.extraction_filter = getattr(tarfile, 'data_filter',
                                           (lambda member, path: member))
    my_tarfile.extractall()

* Use the ``'data'`` filter; *fail* if it is not available::

    my_tarfile.extractall(filter=tarfile.data_filter)

  or::

    my_tarfile.extraction_filter = tarfile.data_filter
    my_tarfile.extractall()

* Use the ``'data'`` filter; *warn* if it is not available::

   if hasattr(tarfile, 'data_filter'):
       my_tarfile.extractall(filter='data')
   else:
       # remove this when no longer needed
       warn_the_user('Extracting may be unsafe; consider updating Python')
       my_tarfile.extractall()


Stateful extraction filter example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

While *tarfile*'s extraction methods take a simple *filter* callable,
custom filters may be more complex objects with an internal state.
It may be useful to write these as context managers, to be used like this::

    with StatefulFilter() as filter_func:
        tar.extractall(path, filter=filter_func)

Such a filter can be written as, for example::

    class StatefulFilter:
        def __init__(self):
            self.file_count = 0

        def __enter__(self):
            return self

        def __call__(self, member, path):
            self.file_count += 1
            return member

        def __exit__(self, *exc_info):
            print(f'{self.file_count} files extracted')


.. _tarfile-commandline:
.. program:: tarfile


Command-Line Interface
----------------------

.. versionadded:: 3.4

The :mod:`tarfile` module provides a simple command-line interface to interact
with tar archives.

If you want to create a new tar archive, specify its name after the :option:`-c`
option and then list the filename(s) that should be included:

.. code-block:: shell-session

    $ python -m tarfile -c monty.tar  spam.txt eggs.txt

Passing a directory is also acceptable:

.. code-block:: shell-session

    $ python -m tarfile -c monty.tar life-of-brian_1979/

If you want to extract a tar archive into the current directory, use
the :option:`-e` option:

.. code-block:: shell-session

    $ python -m tarfile -e monty.tar

You can also extract a tar archive into a different directory by passing the
directory's name:

.. code-block:: shell-session

    $ python -m tarfile -e monty.tar  other-dir/

For a list of the files in a tar archive, use the :option:`-l` option:

.. code-block:: shell-session

    $ python -m tarfile -l monty.tar


Command-line options
~~~~~~~~~~~~~~~~~~~~

.. option:: -l <tarfile>
            --list <tarfile>

   List files in a tarfile.

.. option:: -c <tarfile> <source1> ... <sourceN>
            --create <tarfile> <source1> ... <sourceN>

   Create tarfile from source files.

.. option:: -e <tarfile> [<output_dir>]
            --extract <tarfile> [<output_dir>]

   Extract tarfile into the current directory if *output_dir* is not specified.

.. option:: -t <tarfile>
            --test <tarfile>

   Test whether the tarfile is valid or not.

.. option:: -v, --verbose

   Verbose output.

.. option:: --filter <filtername>

   Specifies the *filter* for ``--extract``.
   See :ref:`tarfile-extraction-filter` for details.
   Only string names are accepted (that is, ``fully_trusted``, ``tar``,
   and ``data``).

.. _tar-examples:

Examples
--------

Reading examples
~~~~~~~~~~~~~~~~~~~

How to extract an entire tar archive to the current working directory::

   import tarfile
   tar = tarfile.open("sample.tar.gz")
   tar.extractall(filter='data')
   tar.close()

How to extract a subset of a tar archive with :meth:`TarFile.extractall` using
a generator function instead of a list::

   import os
   import tarfile

   def py_files(members):
       for tarinfo in members:
           if os.path.splitext(tarinfo.name)[1] == ".py":
               yield tarinfo

   tar = tarfile.open("sample.tar.gz")
   tar.extractall(members=py_files(tar))
   tar.close()

How to read a gzip compressed tar archive and display some member information::

   import tarfile
   tar = tarfile.open("sample.tar.gz", "r:gz")
   for tarinfo in tar:
       print(tarinfo.name, "is", tarinfo.size, "bytes in size and is ", end="")
       if tarinfo.isreg():
           print("a regular file.")
       elif tarinfo.isdir():
           print("a directory.")
       else:
           print("something else.")
   tar.close()

Writing examples
~~~~~~~~~~~~~~~~

How to create an uncompressed tar archive from a list of filenames::

   import tarfile
   tar = tarfile.open("sample.tar", "w")
   for name in ["foo", "bar", "quux"]:
       tar.add(name)
   tar.close()

The same example using the :keyword:`with` statement::

    import tarfile
    with tarfile.open("sample.tar", "w") as tar:
        for name in ["foo", "bar", "quux"]:
            tar.add(name)

How to create and write an archive to stdout using
:data:`sys.stdout.buffer <sys.stdout>` in the *fileobj* parameter
in :meth:`TarFile.add`::

    import sys
    import tarfile
    with tarfile.open("sample.tar.gz", "w|gz", fileobj=sys.stdout.buffer) as tar:
        for name in ["foo", "bar", "quux"]:
            tar.add(name)

How to create an archive and reset the user information using the *filter*
parameter in :meth:`TarFile.add`::

    import tarfile
    def reset(tarinfo):
        tarinfo.uid = tarinfo.gid = 0
        tarinfo.uname = tarinfo.gname = "root"
        return tarinfo
    tar = tarfile.open("sample.tar.gz", "w:gz")
    tar.add("foo", filter=reset)
    tar.close()


.. _tar-formats:

Supported tar formats
---------------------

There are three tar formats that can be created with the :mod:`tarfile` module:

* The POSIX.1-1988 ustar format (:const:`USTAR_FORMAT`). It supports filenames
  up to a length of at best 256 characters and linknames up to 100 characters.
  The maximum file size is 8 GiB. This is an old and limited but widely
  supported format.

* The GNU tar format (:const:`GNU_FORMAT`). It supports long filenames and
  linknames, files bigger than 8 GiB and sparse files. It is the de facto
  standard on GNU/Linux systems. :mod:`tarfile` fully supports the GNU tar
  extensions for long names, sparse file support is read-only.

* The POSIX.1-2001 pax format (:const:`PAX_FORMAT`). It is the most flexible
  format with virtually no limits. It supports long filenames and linknames, large
  files and stores pathnames in a portable way. Modern tar implementations,
  including GNU tar, bsdtar/libarchive and star, fully support extended *pax*
  features; some old or unmaintained libraries may not, but should treat
  *pax* archives as if they were in the universally supported *ustar* format.
  It is the current default format for new archives.

  It extends the existing *ustar* format with extra headers for information
  that cannot be stored otherwise. There are two flavours of pax headers:
  Extended headers only affect the subsequent file header, global
  headers are valid for the complete archive and affect all following files.
  All the data in a pax header is encoded in *UTF-8* for portability reasons.

There are some more variants of the tar format which can be read, but not
created:

* The ancient V7 format. This is the first tar format from Unix Seventh Edition,
  storing only regular files and directories. Names must not be longer than 100
  characters, there is no user/group name information. Some archives have
  miscalculated header checksums in case of fields with non-ASCII characters.

* The SunOS tar extended format. This format is a variant of the POSIX.1-2001
  pax format, but is not compatible.

.. _tar-unicode:

Unicode issues
--------------

The tar format was originally conceived to make backups on tape drives with the
main focus on preserving file system information. Nowadays tar archives are
commonly used for file distribution and exchanging archives over networks. One
problem of the original format (which is the basis of all other formats) is
that there is no concept of supporting different character encodings. For
example, an ordinary tar archive created on a *UTF-8* system cannot be read
correctly on a *Latin-1* system if it contains non-*ASCII* characters. Textual
metadata (like filenames, linknames, user/group names) will appear damaged.
Unfortunately, there is no way to autodetect the encoding of an archive. The
pax format was designed to solve this problem. It stores non-ASCII metadata
using the universal character encoding *UTF-8*.

The details of character conversion in :mod:`tarfile` are controlled by the
*encoding* and *errors* keyword arguments of the :class:`TarFile` class.

*encoding* defines the character encoding to use for the metadata in the
archive. The default value is :func:`sys.getfilesystemencoding` or ``'ascii'``
as a fallback. Depending on whether the archive is read or written, the
metadata must be either decoded or encoded. If *encoding* is not set
appropriately, this conversion may fail.

The *errors* argument defines how characters are treated that cannot be
converted. Possible values are listed in section :ref:`error-handlers`.
The default scheme is ``'surrogateescape'`` which Python also uses for its
file system calls, see :ref:`os-filenames`.

For :const:`PAX_FORMAT` archives (the default), *encoding* is generally not needed
because all the metadata is stored using *UTF-8*. *encoding* is only used in
the rare cases when binary pax headers are decoded or when strings with
surrogate characters are stored.
