Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

CFFI backend parity gaps: garbled `ZstdError` messages, `__exit__` ordering mismatch with C backend, minor parameter-validation drift

未关闭
#301 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 2 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
52/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
冷清
技术栈
c, python
领域
backend

调研方向

从 zstandard/backend_cffi.py 中报告的位置开始,并将其与相应的 C-backend 实现进行比较。如果可用,请使用仅包含 PyPy 或 CFFI 的环境验证报告的三个兼容性差异。错误呈现已修正、exit 顺序一致,并且参数验证行为已与 C-backend 对齐,即表示完成。

由索引模型根据 Issue 内容生成。

描述

Summary

The pure-Python CFFI backend has several small-but-real parity gaps with the C extension backend. The most visible is that several ZstdError constructors are called with positional args as if %-formatting were going to happen, but it doesn't — so user-facing error messages look like garbled tuples. Two additional gaps affect resource-lifecycle invariants and parameter validation.

Impact

  • Severity: User-visible garbled error messages (main issue); resource-lifecycle invariant violation in __exit__ (secondary); small parameter-validation drift.
  • Reachability: Any user running the CFFI backend — typically PyPy, or environments where the C extension can't be built.
  • Version: 0.25.0 (commit 7a77a75).
  • Note: Report was produced without a live CFFI environment available; the below is based on static review of zstandard/backend_cffi.py. Happy to verify with a concrete reproducer if you set up a PyPy / CFFI-only test environment.

Gap 1: Tuple-args to ZstdError — garbled error messages

Pattern: raise ZstdError("... %s", error) passes two positional args to the exception constructor, making .args == ("... %s", error). No %-formatting happens. The rendered message looks like ('..., %s', <something>) instead of the intended interpolated string.

Sites: zstandard/backend_cffi.py:1531, 1575, 1682.

Fix: raise ZstdError("... %s" % error) or an f-string.

Gap 2: __exit__ ordering mismatch with the C backend

C backend's __exit__ calls close() first, then clears the compressor/decompressor field. CFFI backend sets _compressor = None first, then calls close() — which runs with the invariants already broken. Any reference to self._compressor inside close() observes None.

Sites: zstandard/backend_cffi.py:1413, 3161.

Fix: Reorder to match the C backend:

def __exit__(self, exc_type, exc_value, tb):
    self.close()                    # first
    self._compressor = None         # then clear
    return False

Gap 3: Minor parameter-validation drift

  • Off-by-one in level-validation error message. CFFI says "less than 22"; C says "less than 23". One of them has the boundary wrong (if the C backend's boundary is correct — ZSTD_maxCLevel() returns 22 — then both messages should say "less than 23" in the "strictly-less-than" formulation or "more than 22" in the symmetric one).
  • compressobj(size=-1) is accepted by CFFI but raises OverflowError in C — signed/unsigned mismatch somewhere in the CFFI argument handling.
  • CFFI backend does not declare Py_MOD_GIL_NOT_USED (doesn't apply — it's pure Python), but has no FT-story either; worth either documenting or gating free-threaded wheels to C-backend-only.

Suggested PR shape

All three gaps are one small PR (pure-Python fixes, likely ~20 lines of diff). If you'd prefer to keep C-side and CFFI-side PRs separate I can do that — otherwise one combined parity PR seems cleanest.

Methodology

Found via cext-review-toolkit — the parity-checker agent identifies places where two implementations of the same interface diverge. Gaps 1 and 2 were flagged via structural pattern matching against the C backend; Gap 3 via argument-validation diffing. The CFFI environment wasn't available during the analysis, so none of the above was live-reproduced; verification is recommended but the diffs are small and the patterns are unambiguous on inspection.

Discovery, root-cause analysis, and issue drafting were performed by Claude Code and reviewed by a human before filing.

Full report

Complete multi-agent analysis (48 FIX findings across 13 categories, plus a reproducer appendix): https://gist.github.com/devdanzin/b86039ac097141579590c1a0f3a43605

主要语言
C
星标
641
派生
117
平均合并
1 天 14 小时
30 天内合并 PR
5

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

indygreg/python-zstandard 的其他 Issue

查看 indygreg/python-zstandard 的全部 Issue

相似的 Issue

更多 C Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。