fix: audit-driven cleanup of packaging, CI, and silent failures#4
Conversation
Sync 0.4.6 version across _version.py / README / changelog and stop the README features table from advertising a non-existent pyXenium.spatho namespace (the entry point is build_spatho_manifest + external spatho). Stop shipping _vendor/Gmi/.github workflow files inside the wheel and narrow requires-python / classifiers to >=3.10 (scientific stack already excludes 3.8-3.9). Expand CI matrix to 3.10-3.13 and drop the duplicate test.yml workflow. Pin aiohttp>=3.9 so it stops being the only unpinned runtime dependency. Replace the only bare except: in src (multimodal/analysis/differential.py) with a precise AttributeError so non-toarray failures surface. Plug fsspec handle leaks in io.xenium_artifacts.open_text (release on TextIOWrapper/GzipFile construction error) and in read_cell_feature_matrix_h5 (close the fsspec fileobj when h5py.File(fileobj, ...) fails before falling back to a local re-open). Seed np.random in the SCILD CCI adapter via SCILD_SEED env var so benchmark runs are reproducible. Add logger.warning / logger.debug to 13 silent except Exception sites in multimodal/histoseg_lazyslide.py, 1 in multimodal/immune_resistance.py, and 1 in _topology_core.safe_to_parquet so whole-slide / contour pipeline failures are diagnosable.
Reviewer's Guide基于审计的维护型发行版:收紧 Python/支持元数据与 CI,改善打包卫生,修复 fsspec/h5py 句柄泄漏和差异分析中的裸 except,用可配置随机种子保证 SCILD 基准测试可复现,并为此前静默的宽泛异常处理增加日志记录,同时更新文档和版本信息。 File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your Experience打开你的 dashboard 以:
Getting HelpOriginal review guide in EnglishReviewer's GuideAudit-driven maintenance release that tightens Python/support metadata and CI, improves packaging hygiene, fixes fsspec/h5py handle leaks and a bare except in differential analysis, seeds SCILD benchmarking for reproducibility, and adds logging around previously silent broad exception handlers plus documentation/version updates. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
zarr 3.0+ has never shipped a wheel for Python 3.10 (its requires_python is >=3.11), so the new CI matrix on 3.10 failed at pip install: "No matching distribution found for zarr>=3.1". The package never actually ran on 3.10 — the previous (3.11-only) CI just never exercised that claim. Align requires-python, classifiers, and CI matrix to >=3.11.
There was a problem hiding this comment.
Hey - 我已经审核了你的更改,一切看起来都很棒!
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈来改进后续的代码审查。
Original comment in English
Hey - I've reviewed your changes and they look great!
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Pull request overview
This PR addresses an audit backlog by tightening packaging metadata, CI coverage, and runtime robustness—primarily by eliminating silent exception swallowing, fixing a couple of fsspec/h5py handle-leak paths, and aligning docs/metadata around what the project actually supports/ships.
Changes:
- Replace/augment broad exception handlers with targeted exceptions or debug/warning logs to avoid silent failures in multimodal workflows.
- Fix resource-management edge cases for fsspec-backed readers (
open_text,read_cell_feature_matrix_h5) and add reproducible seeding for the SCILD adapter viaSCILD_SEED. - Clean up packaging/CI/docs: exclude vendored workflow files from wheels, pin
aiohttp>=3.9, remove duplicate workflow, and update README/changelog.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/pyXenium/multimodal/immune_resistance.py | Add logger + debug logging for resolve_protein_column fallback instead of silent broad exception. |
| src/pyXenium/multimodal/histoseg_lazyslide.py | Add logger and debug/warning logs to previously silent broad exception fallbacks. |
| src/pyXenium/multimodal/analysis/differential.py | Replace bare except: with except AttributeError when calling toarray(). |
| src/pyXenium/io/xenium_artifacts.py | Close fsspec handles on wrapper-construction failures and close fileobj on h5py.File(fileobj, ...) failure path. |
| src/pyXenium/benchmarking/cci_adapters.py | Make SCILD seeding reproducible via SCILD_SEED and use a seeded Generator for initialization. |
| src/pyXenium/_topology_core.py | Add logger + warning on parquet write failure instead of silent failure. |
| README.md | Update version/install snippet and clarify spatho integration entry point (but Python support line is now stale). |
| pyproject.toml | Restrict Python support to >=3.11, pin aiohttp>=3.9, and narrow vendored Gmi package-data globs. |
| docs/changelog.md | Add 0.4.6 notes (but one bullet mismatches the actual SCILD seeding mechanism). |
| .github/workflows/test.yml | Remove duplicate workflow. |
| .github/workflows/ci.yml | Add Python matrix + docs job (but packaging build step is no longer run in PR CI). |
Comments suppressed due to low confidence (1)
README.md:65
- README still lists “Supported Python:
>=3.8”, butpyproject.tomlnow requires Python>=3.11and CI only tests 3.11–3.13. Please update this README line so users don’t attempt unsupported installs.
- Current repository version: `0.4.6`
- Package index: [PyPI](https://pypi.org/project/pyXenium/)
- Documentation site: [pyxenium.readthedocs.io](https://pyxenium.readthedocs.io/en/latest/)
- Canonical build status: [GitHub Actions CI](https://github.com/hutaobo/pyXenium/actions/workflows/ci.yml)
- Supported Python: `>=3.8`
- License: [GNU AGPL v3.0 only](https://github.com/hutaobo/pyXenium/blob/main/LICENSE)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - Expand CI Python matrix to `3.11`–`3.13` and remove the duplicate `test.yml` workflow. | ||
| - Fix bare `except:` in `multimodal.analysis.differential.get_rna_expr_df` so non-`AttributeError` failures surface. | ||
| - Plug fsspec handle leaks in `io.xenium_artifacts.open_text` (release on TextIOWrapper/GzipFile construction error) and in `read_cell_feature_matrix_h5` (close the fsspec fileobj when `h5py.File(fileobj, ...)` fails before falling back to a local re-open). | ||
| - Seed `np.random.random` in the SCILD CCI adapter; benchmark runs are now reproducible via a `seed` kwarg. |
| description = "Xenium I/O, multimodal analysis, topology workflows, contour-native spatial profiling, GMI inference, mechanostress analysis, and optional external workflow bridges." | ||
| readme = "README.md" | ||
| requires-python = ">=3.8" | ||
| requires-python = ">=3.11" | ||
| license = "AGPL-3.0-only" | ||
| license-files = ["LICENSE"] |
|
|
||
| - run: python -m pip install --upgrade pip | ||
| - run: python -m pip install -e ".[dev,docs]" | ||
| - run: pytest -q |
Summary
Audit of pyXenium on the 0.4.6 branch surfaced 9 high/medium-severity defects plus
15 silent
except Exception:sites. All of them are fixed in this PR.High-severity
_version.py(0.4.6),README.md,docs/changelog.md_vendor/Gmi/.github/**workflow files inside the wheeltest.ymlworkflow; narrowrequires-python/classifiers to>=3.10so claim and reality agree (scientific stack already excludes 3.8/3.9 in practice)pyXenium.spathorow in the README features table (spatho is external; the in-repo helper isbuild_spatho_manifest)except:in src (multimodal/analysis/differential.py) withexcept AttributeErrorso non-toarray failures surfaceio.xenium_artifacts.open_text(release onTextIOWrapper/GzipFileconstruction error) and inread_cell_feature_matrix_h5(close the fsspec fileobj whenh5py.File(fileobj, ...)fails before falling back to a local re-open)np.random.randomin the SCILD CCI adapter viaSCILD_SEEDenv var so benchmark runs are reproducibleMedium / hygiene
aiohttp>=3.9(previously the only unpinned runtime dependency)logger.warning(...)/logger.debug(...)to 15 silentexcept Exception:sites inmultimodal/histoseg_lazyslide.py(×13),multimodal/immune_resistance.py, and_topology_core.safe_to_parquet— whole-slide / contour pipeline failures are now diagnosableDefects NOT fixed (excluded by design)
tests/test_dataset_catalog.py:5was flagged by audit as a "network call" — verified to be only astartswithstring assertion, not actually a network call. No change needed.XeniumOmeTiffSource.open_zarr_sourcewas a candidate for context-manager conversion, but all 5 existing call sites incontour/loading.py,io/slide_store.py,io/backfill.py, andio/xenium_slide_builder.pyalready wrap usage intry/finallywithstore.close(). Changing the signature would touch 4 files for no real leak — skipped. The h5py interaction bug (D12) atxenium_artifacts.py:614-618was a real leak and is fixed._vendor/Gmi/R metadata (DESCRIPTION,NAMESPACE,LICENSE.md, etc.) remains inpackage-databecauseassert_vendored_gmi_complete()checks for them at runtime.Test plan
pytest -q— 293 passed, 2 skipped, 0 failed locallypython -c "import pyXenium; assert pyXenium.__version__ == '0.4.6'"python -c "from pyXenium.gmi import assert_vendored_gmi_complete; assert_vendored_gmi_complete()"— vendor completeness check still passespython -m build— wheel builds cleanly;unzip -l dist/pyxenium-0.4.6-*.whl | grep _vendor/Gmi/.githubreturns no hitspython -c "import pyXenium; pyXenium.spatho"raisesAttributeErroras expected (README no longer misleads)grep -rn 'except:\s*$' src/pyXenium→ no hitsgrep -rn 'np\.random\.random(' src/pyXenium→ no hitssphinx-builddocs job green on this PRGenerated by Claude Code
Summary by Sourcery
围绕 pyXenium 0.4.6 收紧打包、CI 和运行时行为,以提升可靠性、可诊断性和可复现性。
Bug 修复:
AttributeError,从而不再静默吞掉其他类型的失败。增强:
构建:
aiohttp固定为>=3.9,并停止在 wheel 中包含自带的 Gmi GitHub workflow 文件。CI:
文档:
Original summary in English
Summary by Sourcery
Tighten packaging, CI, and runtime behavior around pyXenium 0.4.6 to improve reliability, diagnostics, and reproducibility.
Bug Fixes:
Enhancements:
Build:
CI:
Documentation:
Bug 修复:
fsspec的文件句柄在出错时能够被正确关闭,以防止资源泄漏。AttributeError,以便其他类型的失败能够暴露出来,而不是被静默吞掉。增强改进:
构建(Build):
pyproject元数据和运行时 classifiers 中,将支持的 Python 版本限制为 3.10+,并将aiohttp固定为>=3.9,以获得更可预期的依赖解析行为。CI:
Original summary in English
Summary by Sourcery
围绕 pyXenium 0.4.6 收紧打包、CI 和运行时行为,以提升可靠性、可诊断性和可复现性。
Bug 修复:
AttributeError,从而不再静默吞掉其他类型的失败。增强:
构建:
aiohttp固定为>=3.9,并停止在 wheel 中包含自带的 Gmi GitHub workflow 文件。CI:
文档:
Original summary in English
Summary by Sourcery
Tighten packaging, CI, and runtime behavior around pyXenium 0.4.6 to improve reliability, diagnostics, and reproducibility.
Bug Fixes:
Enhancements:
Build:
CI:
Documentation: