tarfile
| Language | Python |
|---|---|
| License | PSF License (Python standard library) |
| Repository | github.com/python/cpython |
| Documentation | tarfile on docs.python.org |
| Depends on | nothing; zlib, bz2, lzma and compression.zstd (3.14+) modules for compression |
| Read / write | yes / yes; ustar, GNU and pax formats; gzip, bzip2, xz, zstd (3.14+) |
tarfile is the standard library module for TAR archives. tarfile.open() opens a file in a mode such as "r:gz" or "w:xz"; "r" detects the compression by itself. A TarFile gives you TarInfo objects with the name, size, mode, owner, times and link target of each entry, and methods to extract entries or add files.
It writes pax by default (since Python 3.8), so long names and large files work. Since 3.12 extraction takes a filter argument that blocks dangerous entries; since 3.14 the default filter is "data", which refuses absolute paths, .., links pointing outside the destination, and device files.
Installation#
Nothing to install: import tarfile.
Basic usage: list and extract a .tar.gz#
import tarfile
with tarfile.open("archive.tar.gz") as tar: # "r:*": compression detected automatically
for member in tar.getmembers():
kind = "d" if member.isdir() else "-"
print(f"{kind} {member.size:10d} {member.name}")
tar.extractall("out", filter="data") # safe extraction
Pass filter="data" explicitly in Python 3.12 and 3.13; older versions extract whatever the archive says, including ../ paths.
How to create a .tar.gz, .tar.xz or .tar.zst#
import tarfile
with tarfile.open("docs.tar.gz", "w:gz") as tar:
tar.add("docs") # recursive; stored as "docs/..."
with tarfile.open("docs.tar.xz", "w:xz", preset=9) as tar:
tar.add("docs", arcname="documentation") # rename inside the archive
# Python 3.14+
with tarfile.open("docs.tar.zst", "w:zst") as tar:
tar.add("docs")
Other modes: "w" (no compression), "w:bz2", "x:gz" (fail if the file exists). Gzip and bzip2 take compresslevel=, xz takes preset=.
How to read one file without extracting#
extractfile returns a file object for a regular file:
import tarfile
with tarfile.open("archive.tar.gz") as tar:
f = tar.extractfile("project/README.md") # KeyError if missing
if f is not None:
text = f.read().decode("utf-8")
print(text)
How to add a file from memory#
import io
import tarfile
import time
data = "hello\n".encode("utf-8")
info = tarfile.TarInfo(name="notes/hello.txt")
info.size = len(data)
info.mtime = int(time.time())
info.mode = 0o644
with tarfile.open("out.tar", "w") as tar:
tar.addfile(info, io.BytesIO(data))
How to exclude files and reset owners when creating#
The filter argument of add gets each TarInfo; return None to skip it or change fields:
import tarfile
def clean(info: tarfile.TarInfo):
if info.name.endswith((".pyc", ".log")) or "/.git" in info.name:
return None
info.uid = info.gid = 0
info.uname = info.gname = "root"
return info
with tarfile.open("release.tar.gz", "w:gz") as tar:
tar.add("project", filter=clean)
How to stream a tar from a pipe or socket#
Modes with | read or write sequentially without seeking, for stdin, sockets or HTTP responses:
import sys
import tarfile
with tarfile.open(fileobj=sys.stdin.buffer, mode="r|gz") as tar:
for member in tar: # iterate; random access isn't possible in stream mode
if member.isfile():
data = tar.extractfile(member).read()
print(member.name, len(data))
Tips#
tarfile.is_tarfile(path)checks whether a file is a tar archive (it also accepts compressed ones).- Write a specific variant with
format=tarfile.USTAR_FORMATortarfile.GNU_FORMAT. - The extraction filters are also available as functions (
tarfile.data_filter,tarfile.tar_filter) to inspect members before extracting them yourself. - Command line:
python -m tarfile -l archive.tar.gzlists,-eextracts,-c out.tar.gz dir/creates.