Package: xopen
xopenThis Python module provides anxopenfunction that works like Python’s
built-inopenfunction but also transparently deals with compressed files.xopenselects the most efficient method for reading or writing a compressed file.Supported compression formats are:gzip (.gz)bzip2 (.bz2)xz (.xz)Zstandard (.zst) (optional)xopenis compatible with Python versions 3.8 and later.Example usageOpen a file for reading:from xopen import xopen

with xopen("file.txt.gz") as f:
    content = f.read()Write to a file in binary mode,
set the compression level
and avoid using an external process:from xopen import xopen

with xopen("file.txt.xz", mode="wb", threads=0, compresslevel=3) as f:
    f.write(b"Hello")ThexopenfunctionThexopenmodule offers a single function namedxopenwith the following
signature:xopen(
  filename: str | bytes | os.PathLike,
  mode: Literal["r", "w", "a", "rt", "rb", "wt", "wb", "at", "ab"] = "r",
  compresslevel: Optional[int] = None,
  threads: Optional[int] = None,
  *,
  encoding: str = "utf-8",
  errors: Optional[str] = None,
  newline: Optional[str] = None,
  format: Optional[str] = None,
) -> IOThe function opens the file using a function suitable for the detected
file format and returns an open file-like object.When writing, the file format is chosen based on the file name extension:.gz,.bz2,.xz,.zst. This can be overriden withformat.
If the extension is not recognized, no compression is used.When reading and a file name extension is available, the format is detected
from the extension.
When reading and no file name extension is available,
the format is detected from thefile signature <https://en.wikipedia.org/wiki/File_format#Magic_number>.Parametersfilename(str, bytes, oros.PathLike):
Name of the file to open.If set to"-", standard output (in mode"w") or
standard input (in mode"r") is returned.mode,encoding,errors,newline:
These parameters have the same meaning as in Python’s built-inopen functionexcept that the default encoding is always UTF-8 instead of the
preferred locale encoding.encoding,errorsandnewlineare only used when opening a file in text mode.compresslevel:
The compression level for writing to gzip, xz and Zstandard files.
If set to None, a default depending on the format is used:
gzip: 1, xz: 6, Zstandard: 3.This parameter is ignored for other compression formats.format:
Override the autodetection of the input or output format.
Possible values are:"gz","xz","bz2","zst".threads:
Set the number of additional threads spawned for compression or decompression.
May be ignored if the backend does not support threads.Ifthreadsis None (the default), as many threads as available CPU cores are
used, but not more than four.xopen tries to offload the (de)compression to other threads
to free up the main Python thread for the application.
This can either be done by using a subprocess to an external application or
using a library that supports threads.Set threads to 0 to force xopen to use only the main Python thread.BackendsOpening of gzip files is delegated to one of these programs or libraries:python-isal.
Supports multiple threads and compression levels up to 3.python-zlib-ngpigz(a parallel version ofgzip)gzipFor xz files, a pipe to thexzprogram is used because it has
built-in support for multithreaded compression.For bz2 files,pbzip2 (parallel bzip2)is used.xopenfalls back to Python’s built-in functions
(gzip.open,lzma.open,bz2.open)
if none of the other methods can be used.Reproducibilityxopen writes gzip files in a reproducible manner.Normally, gzip files contain a timestamp in the file header,
which means that compressing the same data at different times results in different output files.
xopen disables this for all of the supported gzip compression backends.
For example, when using an external process, it sets the command-line option--no-name(same as-n).Note that different gzip compression backends typically do not produce
identical output, so reproducibility may no longer be given when the execution environment changes
from onexopen()invocation to the next.
This includes the CPU architecture asigzip adjusts its algorithm
depending on it.bzip2 and xz compression methods do not store timestamps in the file headers,
so output from them is also reproducible.Optional Zstandard supportFor reading and writing Zstandard (.zst) files, either thezstdcommand-line
program or the Pythonzstandardpackage needs to be installed.If thethreadsparameter toxopen()isNone(the default) or any value greater than 0,xopenuses an externalzstdprocess.If the above fails (because nozstdprogram is available) or ifthreadsis 0,
thezstandardpackage is used.To ensure that you get the correctzstandardversion, you can specify thezstdextra forxopen, that is, install it usingpip install xopen[zstd].Changelogv1.9.0 (2024-01-31)#142: The python-isal compression backend is now only used for compression
levels 1 and 2. Contrary to other backends, python-isal level 0 gave
compressed rather than uncompressed data in gzip format. Level 3 on
python-isal did not provide better compression than level 2.#140: PipedCompressionReader/Writer now derive from theio.IOBaseabstract class.#138: The gzip default compression level is now 1 when no value is provided
by the calling function. The default used to be determined by the backend.#135: xopen now uses zlib-ng when available and applicable.#133: Pipedigzipis no longer used as a (de)compression backend as
python-isal’s threaded mode is a better choice in all use cases.v1.8.0 (2023-11-03)#131: xopen now defers to theisal.igzip_threadedmodule rather than
piping to external programs in applicable cases. This makes reading and
writing to gzip files using threads more efficient.Support for Python 3.7 is dropped and support for Python 3.12 is added.v1.7.0 (2022-11-03)#91: Added optional support for Zstandard (.zst) files.
This requires that the Pythonzstandardpackage is installed
or that thezstdcommand-line program is available.v1.6.0 (2022-08-10)#94: When writing gzip files, the timestamp and name of the original
file is omitted (equivalent to usinggzip--no-name(or-n) on the
command line). This allows files to be written in a reproducible manner.v1.5.0 (2022-03-23)#100: Dropped Python 3.6 support#101: Added support for piping into and from an externalxzprocess. Contributed by @fanninpm.#102: Support setting the xz compression level. Contributed by @tsibley.v1.4.0 (2022-01-14)Addseek()andtell()to thePipedCompressionReaderclasses
(for Windows compatibility)v1.3.0 (2022-01-10)xopen is now available on Windows (in addition to Linux and macOS).For greater compatibility withthe built-in open()
function,xopen()has gained the parametersencoding,errorsandnewlineswith the same meaning as inopen(). Unlike built-inopen(), though,
encoding is UTF-8 by default.A parameterformathas been added that allows to force the compression
file format.v1.2.0 (2021-09-21)pbzip2is now used to open.bz2files ifthreadsis greater than zero (contributed by @DriesSchaumont).v1.1.0 (2021-01-20)Python 3.5 support is dropped.On Linux systems,python-isalis now added as a requirement. This will speed up the reading of gzip files
significantly when no external processes are used.v1.0.0 (2020-11-05)If installed, theigzipprogram (part ofIntel ISA-L) is now used for reading
and writing gzip-compressed files at compression levels 1-3, which results
in a significant speedup.v0.9.0 (2020-04-02)#80: When the file name extension of a file to be opened for reading is not
available, the content is inspected (if possible) and used to determine
which compression format applies (contributed by @bvaisvil).This release drops Python 2.7 and 3.4 support. Python 3.5 or later is
now required.v0.8.4 (2019-10-24)When reading gzipped files, forcepigzto use only a single process.pigzcannot use multiple cores anyway when decompressing. By default,
it would use extra I/O processes, which slightly reduces wall-clock time,
but increases CPU time. Single-core decompression withpigzis still
about twice as fast as regulargzip.Allowthreads=0for specifying that no externalpigz/gzipprocess should be used (then regulargzip.open()is used instead).v0.8.3 (2019-10-18)#20: When reading gzipped files, letpigzuse at most four threads by default.
This limit previously only applied when writing to a file. Contributed by @bernt-matthias.Support Python 3.8v0.8.0 (2019-08-14)#14: Speed improvements when iterating over gzipped files.v0.6.0 (2019-05-23)For reading from gzipped files, xopen will now use apigzsubprocess.
This is faster than usinggzip.open.Python 2 support will be dropped in one of the next releases.v0.5.0 (2019-01-30)By default, pigz is now only allowed to use at most four threads. This hopefully reduces
problems some users had with too many threads when opening many files at the same time.xopen now accepts pathlib.Path objects.v0.4.0 (2019-01-07)Drop Python 3.3 supportAdd athreadsparameter (passed on topigz)v0.3.2 (2017-11-22)#6: Make multi-block bz2 work on Python 2 by using external bz2file library.v0.3.1 (2017-11-22)Drop Python 2.6 support#5: Fix PipedGzipReader.read() not returning anythingv0.3.0 (2017-11-15)Add gzip compression parameterv0.2.1 (2017-05-31)#3: Allow appending to bz2 and lzma files where possiblev0.1.1 (2016-12-02)Fix a deadlockv0.1.0 (2016-09-09)Initial releaseCreditsThe namexopenwas taken from the C function of the same name in theutils.h file that is part of
BWA.Some ideas were taken from thecanopener project.
If you also want to open S3 files, you may want to use that module instead.@kyleabeauchamp contributed support for appending to files before this repository was created.MaintainersMarcel MartinRuben VordermanSee also thefull list of contributors.LinksSource codeReport an issueProject page on PyPI (Python package index)