Skip to content

Commit 41b046c

Browse files
committed
docs: improve tarfile documentation
1 parent b1fdab9 commit 41b046c

File tree

1 file changed

+45
-22
lines changed

1 file changed

+45
-22
lines changed

docs/index.rst

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,42 +1470,65 @@ Use with tarfile module
14701470

14711471
Python's `tarfile <https://docs.python.org/3/library/tarfile.html>`_ module supports arbitrary compression algorithms by providing a file object.
14721472

1473-
This code encapsulates a ``ZstdTarFile`` class using :py:class:`ZstdFile`, it can be used like `tarfile.TarFile <https://docs.python.org/3/library/tarfile.html#tarfile.TarFile>`_ class:
1474-
14751473
.. sourcecode:: python
14761474

14771475
import tarfile
14781476

1479-
# when using read mode (decompression), the level_or_option parameter
1480-
# can only be a dict object, that represents decompression option. It
1481-
# doesn't support int type compression level in this case.
1477+
# compression
1478+
with ZstdFile('archive.tar.zst', mode='w') as _fileobj, tarfile.open(fileobj=_fileobj, mode='w') as tar:
1479+
# do something
1480+
1481+
# decompression
1482+
with ZstdFile('archive.tar.zst', mode='r') as _fileobj, tarfile.open(fileobj=_fileobj) as tar:
1483+
# do something
1484+
1485+
Alternatively, it is possible to extend the ``Tarfile`` class, so that it supports decompressing ``.tar.zst`` file automatically, as well as adding the following modes: ``r:zst``, ``w:zst`` and ``x:zst``.
1486+
1487+
.. sourcecode:: python
1488+
1489+
from tarfile import TarFile, CompressionError, ReadError
1490+
from pyzstd import ZstdFile, ZstdError
1491+
1492+
class CustomTarFile(TarFile):
1493+
1494+
OPEN_METH = {
1495+
**TarFile.OPEN_METH,
1496+
'zst': 'zstopen'
1497+
}
1498+
1499+
@classmethod
1500+
def zstopen(cls, name, mode='r', fileobj=None, level_or_option=None, zstd_dict=None, **kwargs):
1501+
"""Open zstd compressed tar archive name for reading or writing.
1502+
Appending is not allowed.
1503+
"""
1504+
if mode not in ('r', 'w', 'x'):
1505+
raise ValueError("mode must be 'r', 'w' or 'x'")
1506+
1507+
fileobj = ZstdFile(fileobj or name, mode, level_or_option=level_or_option, zstd_dict=zstd_dict)
14821508

1483-
class ZstdTarFile(tarfile.TarFile):
1484-
def __init__(self, name, mode='r', *, level_or_option=None, zstd_dict=None, **kwargs):
1485-
self.zstd_file = ZstdFile(name, mode,
1486-
level_or_option=level_or_option,
1487-
zstd_dict=zstd_dict)
14881509
try:
1489-
super().__init__(fileobj=self.zstd_file, mode=mode, **kwargs)
1510+
tar = cls.taropen(name, mode, fileobj, **kwargs)
1511+
except (ZstdError, EOFError) as exception:
1512+
fileobj.close()
1513+
if mode == 'r':
1514+
raise ReadError('not a zstd file') from exception
1515+
raise
14901516
except:
1491-
self.zstd_file.close()
1517+
fileobj.close()
14921518
raise
14931519
1494-
def close(self):
1495-
try:
1496-
super().close()
1497-
finally:
1498-
self.zstd_file.close()
1520+
tar._extfileobj = False
1521+
return tar
14991522

1500-
# write .tar.zst file (compression)
1501-
with ZstdTarFile('archive.tar.zst', mode='w', level_or_option=5) as tar:
1523+
# compression
1524+
with CustomTarFile.open('archive.tar.zst', mode='w:zst') as tar:
15021525
# do something
15031526

1504-
# read .tar.zst file (decompression)
1505-
with ZstdTarFile('archive.tar.zst', mode='r') as tar:
1527+
# decompression
1528+
with CustomTarFile.open('archive.tar.zst') as tar:
15061529
# do something
15071530

1508-
When the above code is in read mode (decompression), and selectively read files multiple times, it may seek to a position before the current position, then the decompression has to be restarted from zero. If this slows down the operations, you can:
1531+
In both implementations, when selectively reading files multiple times, it may seek to a position before the current position; then the decompression has to be restarted from zero. If this slows down the operations, you can:
15091532

15101533
#. Use :py:class:`SeekableZstdFile` class to create/read .tar.zst file.
15111534
#. Decompress the archive to a temporary file, and read from it. This code encapsulates the process:

0 commit comments

Comments
 (0)