Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,22 @@ jobs:
- name: Test
run: python -m unittest discover tests -v

lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup Python
uses: actions/setup-python@v6
with:
python-version: 3.14
- name: Install dependencies
run: python -m pip install -r requirements-lint.txt
- name: ruff check
run: ruff check
- name: ruff format
run: ruff format --check

publish:
name: Publish to PyPI
if: startsWith(github.ref, 'refs/tags')
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
- Changes in build dependency: remove `setuptools` and C build toolchain, add `hatchling` and `hatch-vcs`
- Remove git submodule usage
- Drop support for Python 3.9 and below
- Use `ruff` as formatter and linter

## 0.18.0 (October 5, 2025)

Expand Down
16 changes: 8 additions & 8 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
project = 'pyzstd module'
author = 'Ma Lin and contributors'
copyright = '2020-present, Ma Lin and contributors'
language = 'en'
project = "pyzstd module"
author = "Ma Lin and contributors"
copyright = "2020-present, Ma Lin and contributors"
language = "en"

master_doc = 'index'
pygments_style = 'sphinx'
extensions = ['myst_parser', 'sphinx_rtd_theme']
html_theme = 'sphinx_rtd_theme'
master_doc = "index"
pygments_style = "sphinx"
extensions = ["myst_parser", "sphinx_rtd_theme"]
html_theme = "sphinx_rtd_theme"
42 changes: 42 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,45 @@ version-file = "src/pyzstd/_version.py"

[tool.hatch.version]
source = "vcs"


#
# ruff
#

[tool.ruff]
src = ["src"]
target-version = "py310"
extend-exclude = [
"tests",
'*.pyi', # FIXME
]

[tool.ruff.lint]
select = ["ALL"]
ignore = [
"ANN", # FIXME
"C901",
"COM812",
"D",
"E501",
"EM",
"ERA001",
"FA100",
"ISC001",
"PLR0912",
"PLR0913",
"PLR0915",
"PLR2004",
"PTH",
"TRY003",
"TRY301",
]

[tool.ruff.lint.per-file-ignores]
"src/pyzstd/__main__.py" = ["PLC0415", "T201"]
"docs/conf.py" = ["A001", "INP001"]

[tool.ruff.lint.isort]
force-sort-within-sections = true
known-first-party = ["pyzstd"]
3 changes: 3 additions & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-e .

-r requirements-lint.txt
1 change: 1 addition & 0 deletions requirements-lint.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ruff==0.14.8
106 changes: 55 additions & 51 deletions src/pyzstd/__init__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from enum import IntEnum
import sys
from typing import NamedTuple
import warnings

from collections import namedtuple
from enum import IntEnum

if sys.version_info < (3, 14):
from backports import zstd
else:
Expand All @@ -14,8 +13,7 @@
except ImportError:
from typing_extensions import deprecated

from pyzstd._version import __version__

from pyzstd._version import __version__ # noqa: F401

__doc__ = """\
Python bindings to Zstandard (zstd) compression library, the API style is
Expand All @@ -28,32 +26,32 @@
PyPI: https://pypi.org/project/pyzstd"""

__all__ = (
"ZstdCompressor",
"RichMemZstdCompressor",
"ZstdDecompressor",
"EndlessZstdDecompressor",
"CParameter",
"DParameter",
"EndlessZstdDecompressor",
"RichMemZstdCompressor",
"SeekableFormatError",
"SeekableZstdFile",
"Strategy",
"ZstdCompressor",
"ZstdDecompressor",
"ZstdDict",
"ZstdError",
"ZstdFile",
"compress",
"richmem_compress",
"decompress",
"compress_stream",
"compressionLevel_values",
"decompress",
"decompress_stream",
"ZstdDict",
"train_dict",
"finalize_dict",
"get_frame_info",
"get_frame_size",
"ZstdFile",
"open",
"richmem_compress",
"train_dict",
"zstd_support_multithread",
"zstd_version",
"zstd_version_info",
"zstd_support_multithread",
"compressionLevel_values",
"SeekableZstdFile",
"SeekableFormatError",
)


Expand All @@ -68,29 +66,29 @@ def __repr__(self):
class CParameter(IntEnum):
"""Compression parameters"""

compressionLevel = zstd.CompressionParameter.compression_level
windowLog = zstd.CompressionParameter.window_log
hashLog = zstd.CompressionParameter.hash_log
chainLog = zstd.CompressionParameter.chain_log
searchLog = zstd.CompressionParameter.search_log
minMatch = zstd.CompressionParameter.min_match
targetLength = zstd.CompressionParameter.target_length
compressionLevel = zstd.CompressionParameter.compression_level # noqa: N815
windowLog = zstd.CompressionParameter.window_log # noqa: N815
hashLog = zstd.CompressionParameter.hash_log # noqa: N815
chainLog = zstd.CompressionParameter.chain_log # noqa: N815
searchLog = zstd.CompressionParameter.search_log # noqa: N815
minMatch = zstd.CompressionParameter.min_match # noqa: N815
targetLength = zstd.CompressionParameter.target_length # noqa: N815
strategy = zstd.CompressionParameter.strategy
targetCBlockSize = 130 # not part of PEP-784
targetCBlockSize = 130 # not part of PEP-784 # noqa: N815

enableLongDistanceMatching = zstd.CompressionParameter.enable_long_distance_matching
ldmHashLog = zstd.CompressionParameter.ldm_hash_log
ldmMinMatch = zstd.CompressionParameter.ldm_min_match
ldmBucketSizeLog = zstd.CompressionParameter.ldm_bucket_size_log
ldmHashRateLog = zstd.CompressionParameter.ldm_hash_rate_log
enableLongDistanceMatching = zstd.CompressionParameter.enable_long_distance_matching # noqa: N815
ldmHashLog = zstd.CompressionParameter.ldm_hash_log # noqa: N815
ldmMinMatch = zstd.CompressionParameter.ldm_min_match # noqa: N815
ldmBucketSizeLog = zstd.CompressionParameter.ldm_bucket_size_log # noqa: N815
ldmHashRateLog = zstd.CompressionParameter.ldm_hash_rate_log # noqa: N815

contentSizeFlag = zstd.CompressionParameter.content_size_flag
checksumFlag = zstd.CompressionParameter.checksum_flag
dictIDFlag = zstd.CompressionParameter.dict_id_flag
contentSizeFlag = zstd.CompressionParameter.content_size_flag # noqa: N815
checksumFlag = zstd.CompressionParameter.checksum_flag # noqa: N815
dictIDFlag = zstd.CompressionParameter.dict_id_flag # noqa: N815

nbWorkers = zstd.CompressionParameter.nb_workers
jobSize = zstd.CompressionParameter.job_size
overlapLog = zstd.CompressionParameter.overlap_log
nbWorkers = zstd.CompressionParameter.nb_workers # noqa: N815
jobSize = zstd.CompressionParameter.job_size # noqa: N815
overlapLog = zstd.CompressionParameter.overlap_log # noqa: N815

def bounds(self):
"""Return lower and upper bounds of a compression parameter, both inclusive."""
Expand All @@ -100,7 +98,7 @@ def bounds(self):
class DParameter(IntEnum):
"""Decompression parameters"""

windowLogMax = zstd.DecompressionParameter.window_log_max
windowLogMax = zstd.DecompressionParameter.window_log_max # noqa: N815

def bounds(self):
"""Return lower and upper bounds of a decompression parameter, both inclusive."""
Expand All @@ -110,17 +108,15 @@ def bounds(self):
def _convert_level_or_option(level_or_option, mode):
"""Transform pyzstd params into PEP-784 `options` param"""
if not isinstance(mode, str):
raise ValueError(f"Invalid mode type: {mode}")
raise TypeError(f"Invalid mode type: {mode}")
read_mode = mode.startswith("r")
if isinstance(level_or_option, int):
if read_mode:
raise TypeError(
(
"In read mode (decompression), level_or_option argument "
"should be a dict object, that represents decompression "
"option. It doesn't support int type compression level "
"in this case."
)
"In read mode (decompression), level_or_option argument "
"should be a dict object, that represents decompression "
"option. It doesn't support int type compression level "
"in this case."
)
return {
CParameter.compressionLevel: level_or_option,
Expand Down Expand Up @@ -477,7 +473,7 @@ def __init__(
)


def open(
def open( # noqa: A001
filename,
mode="rb",
*,
Expand Down Expand Up @@ -536,7 +532,7 @@ def cb(total_input, total_output, data_in, data_out):

elif callback is None:

def cb(total_input, total_output, data_in, data_out):
def cb(total_input, total_output, data_in, data_out): # noqa: ARG001
output_stream.write(data_out)

else:
Expand All @@ -561,7 +557,7 @@ def compress_stream(
zstd_dict=None,
pledged_input_size=None,
read_size=131_072,
write_size=_DEPRECATED_PLACEHOLDER,
write_size=_DEPRECATED_PLACEHOLDER, # noqa: ARG001
callback=None,
):
"""Compresses input_stream and writes the compressed data to output_stream, it
Expand Down Expand Up @@ -604,7 +600,7 @@ def compress_stream(
total_output = 0
compressor = ZstdCompressor(level_or_option, zstd_dict)
if pledged_input_size is not None and pledged_input_size != 2**64 - 1:
compressor._set_pledged_input_size(pledged_input_size)
compressor._set_pledged_input_size(pledged_input_size) # noqa: SLF001
while data_in := input_stream.read(read_size):
total_input += len(data_in)
data_out = compressor.compress(data_in)
Expand Down Expand Up @@ -701,9 +697,17 @@ def decompress_stream(
zstd_version = zstd.zstd_version
zstd_version_info = zstd.zstd_version_info
zstd_support_multithread = CParameter.nbWorkers.bounds() != (0, 0)
compressionLevel_values = namedtuple("values", ["default", "min", "max"])(


class CompressionValues(NamedTuple):
default: int
min: int
max: int


compressionLevel_values = CompressionValues( # noqa: N816
zstd.COMPRESSION_LEVEL_DEFAULT, *CParameter.compressionLevel.bounds()
)

# import here to avoid circular dependency issues
from ._seekable_zstdfile import SeekableFormatError, SeekableZstdFile
from ._seekable_zstdfile import SeekableFormatError, SeekableZstdFile # noqa: E402
Loading