|
| 1 | +# ks-xlsx-parser v0.2.1 — Packaging hotfix 📦 |
| 2 | + |
| 3 | +**Headline:** v0.2.0 shipped a broken wheel. `from ks_xlsx_parser.pipeline import parse_workbook` (and every public entry point that depends on it) raised `ModuleNotFoundError` for everyone who installed from PyPI. **v0.2.1 fixes it.** |
| 4 | + |
| 5 | +If you're on 0.2.0: |
| 6 | + |
| 7 | +```bash |
| 8 | +pip install --upgrade ks-xlsx-parser # or: uv pip install --upgrade ks-xlsx-parser |
| 9 | +python -c "from ks_xlsx_parser.pipeline import parse_workbook; print('ok')" |
| 10 | +``` |
| 11 | + |
| 12 | +## What was broken |
| 13 | + |
| 14 | +The source tree was laid out flat under `src/` — `pipeline.py` and `api.py` as top-level *modules*, with 13 sibling *packages* (`models`, `utils`, `parsers`, `analysis`, …) next to them. The setuptools build picked up the packages but **silently dropped the top-level modules**, because `[tool.setuptools.packages.find]` only finds packages, never modules. The published wheel's `top_level.txt`: |
| 15 | + |
| 16 | +``` |
| 17 | +analysis annotation charts chunking comparison export formula |
| 18 | +ks_xlsx_parser models parsers rendering storage utils verification |
| 19 | +``` |
| 20 | + |
| 21 | +— 14 top-level entries, 13 of them generic. Two consequences: |
| 22 | + |
| 23 | +1. `from ks_xlsx_parser.pipeline import ...` failed because `pipeline.py` was never copied into the wheel. |
| 24 | +2. Anyone with an unrelated `models` / `utils` / `parsers` package in `site-packages` had it shadowed by ks-xlsx-parser's internal ones. |
| 25 | + |
| 26 | +CI couldn't catch this because the test matrix used an editable install — `src/` lives on `sys.path` and the wheel-packaging defect is invisible. |
| 27 | + |
| 28 | +## What changed in 0.2.1 |
| 29 | + |
| 30 | +* **Proper nested package.** Everything now lives under `src/ks_xlsx_parser/`. The wheel's `top_level.txt` contains only `ks_xlsx_parser`. Imports inside the package switched from `from pipeline import …` to relative / fully-qualified `ks_xlsx_parser.pipeline`. |
| 31 | +* **`scripts/verify_wheel.py`** — builds the wheel, installs it in a clean venv, asserts the public import surface resolves and there's no namespace pollution. Wired into both `ci.yml` (new `wheel-check` job — required) and `release.yml` (a `Verify wheel` step that runs before PyPI publish). The class of bug that produced 0.2.0 cannot recur. |
| 32 | +* **CI overhaul** — separate `test` / `wheel-check` / `lint` / `typecheck` jobs; `uv`-backed installs (faster); `make install-dev` alias. |
| 33 | +* **Docker benchmark + accuracy tracking** — `Dockerfile.bench` reproduces the SpreadsheetBench retrieval benchmark; a new `.github/workflows/benchmark.yml` runs a 60-instance sample on every PR touching the parser and the full 912-corpus weekly. `scripts/append_bench_history.py` keeps a commit-over-commit history file. (Goal: text recall@5 > 0.90.) |
| 34 | +* **Recall failure triage** — `eval_retrieval.py --emit-failures` + `scripts/triage_recall.py` turn "recall@5 = X" into a bucket histogram with exemplar failures. `docs/recall-investigation.md` documents the diagnosis framework. |
| 35 | + |
| 36 | +## ⚠️ Breaking — if you depended on the leaked top-level packages |
| 37 | + |
| 38 | +Anyone whose downstream code did: |
| 39 | + |
| 40 | +```python |
| 41 | +from models import WorkbookDTO # ← used to "work" because of the leak |
| 42 | +from parsers.workbook_parser import … |
| 43 | +``` |
| 44 | + |
| 45 | +must update to: |
| 46 | + |
| 47 | +```python |
| 48 | +from ks_xlsx_parser.models import WorkbookDTO |
| 49 | +from ks_xlsx_parser.parsers.workbook_parser import … |
| 50 | +``` |
| 51 | + |
| 52 | +If you only used the documented public surface (`from ks_xlsx_parser import parse_workbook` and `ks_xlsx_parser.pipeline.parse_workbook`), nothing changes — those names still resolve, and now they actually *load*. |
| 53 | + |
| 54 | +## Upgrade |
| 55 | + |
| 56 | +```bash |
| 57 | +pip install --upgrade ks-xlsx-parser |
| 58 | +# or |
| 59 | +uv pip install --upgrade ks-xlsx-parser |
| 60 | +``` |
| 61 | + |
| 62 | +Then: |
| 63 | + |
| 64 | +```python |
| 65 | +from ks_xlsx_parser import parse_workbook |
| 66 | +result = parse_workbook(path="report.xlsx") |
| 67 | +print(result.workbook.total_cells) |
| 68 | +for chunk in result.chunks: |
| 69 | + print(chunk.source_uri, chunk.render_text[:120]) |
| 70 | +``` |
| 71 | + |
| 72 | +## Verification used to ship this release |
| 73 | + |
| 74 | +``` |
| 75 | +1041 passed, 11 deselected # full test suite |
| 76 | +verifying ks_xlsx_parser-0.2.1-py3-none-any.whl |
| 77 | +wheel contents OK (61 entries, top-level: ks_xlsx_parser) |
| 78 | +clean-venv import OK |
| 79 | +wheel verification PASSED |
| 80 | +``` |
| 81 | + |
| 82 | +`scripts/verify_wheel.py` ran as a release-workflow step before the PyPI publish, with the wheel that's now on PyPI. |
| 83 | + |
| 84 | +## Thanks |
| 85 | + |
| 86 | +Frank for the bug report — the channel screenshot was the right level of detail to reproduce in five minutes. |
| 87 | + |
| 88 | +## See also |
| 89 | + |
| 90 | +* [CHANGELOG.md](https://github.com/knowledgestack/ks-xlsx-parser/blob/main/CHANGELOG.md) — full diff log. |
| 91 | +* [`docs/recall-investigation.md`](https://github.com/knowledgestack/ks-xlsx-parser/blob/main/docs/recall-investigation.md) — diagnosis framework for the recall→0.90 roadmap. |
| 92 | +* [`docs/benchmark-local-setup.md`](https://github.com/knowledgestack/ks-xlsx-parser/blob/main/docs/benchmark-local-setup.md) — reproduce the benchmark on your laptop. |
0 commit comments