Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
f3ac050
test: add FileManager fixtures and parameterized backend tests; add T…
trissim Nov 3, 2025
ec6b418
test(disk,registry): add targeted disk backend and backend_registry t…
trissim Nov 3, 2025
8dda079
test(disk): more focused DiskBackend tests (numpy, registry, symlink,…
trissim Nov 3, 2025
161cc29
deps: make zarr import required; restore streaming optional import
trissim Nov 3, 2025
ff10345
Remove local auto_register_meta shim
trissim Nov 3, 2025
788c133
Refactor: remove openhcs imports, make streaming lazy, extract constants
trissim Nov 3, 2025
435ae6e
feat: enhance testing infrastructure and fix configuration issues
trissim Nov 3, 2025
165e788
feat: add GPU acceleration dependencies and Kaggle CI integration
trissim Nov 3, 2025
d8e53ac
fix: add missing zarr dependencies to GPU requirements
trissim Nov 3, 2025
e756d9f
feat: add Zarr metadata file for testing
trissim Nov 3, 2025
41aaa9d
fix: correct TOML syntax error in pyproject.toml
trissim Nov 3, 2025
0190a5a
fix: add zarr dependencies to core requirements
trissim Nov 3, 2025
fe3eba8
fix: remove duplicate dependencies section in pyproject.toml
trissim Nov 3, 2025
47c9e37
fix: import copy module in memory backend for deepcopy operations
trissim Nov 3, 2025
5b18ebb
fix: handle optional StreamingBackend import gracefully
trissim Nov 3, 2025
8e9fae2
fix: isolate memory backend tests with unique paths
trissim Nov 3, 2025
d1a6c86
fix: isolate memory backend test paths to prevent interference
trissim Nov 3, 2025
a1d0c16
Fix: remove duplicate/malformed test methods in TestFileManagerMemory…
trissim Nov 3, 2025
3310edb
Expand CI testing matrix: add Python 3.13 and multi-OS support
trissim Nov 3, 2025
efca10c
Remove hacky metaclass-registry patch from CI
trissim Nov 3, 2025
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
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,14 @@ jobs:
continue-on-error: true
run: |
mypy src/ --ignore-missing-imports

# Kaggle integration test
kaggle:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: kaggle Action
uses: Frederisk/kaggle-action@v1.0.0
19 changes: 4 additions & 15 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ on:

jobs:
test:
runs-on: ubuntu-latest
runs-on: ${{ matrix.os }}
strategy:
matrix:
python-version: ["3.11", "3.12"]
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.11", "3.12", "3.13"]

steps:
- name: Checkout code
Expand All @@ -29,18 +30,6 @@ jobs:
# Install the package with dev dependencies
pip install -e ".[dev]"

- name: Patch metaclass-registry (temporary fix for import issues)
run: |
# Fix metaclass-registry __init__.py to avoid import errors
REGISTRY_INIT=$(python -c "import metaclass_registry, os; print(os.path.dirname(metaclass_registry.__file__))")/__init__.py
cat > "$REGISTRY_INIT" << 'EOF'
"""metaclass-registry: Zero-boilerplate metaclass-driven plugin registry system."""
__version__ = "0.1.0"
from .core import AutoRegisterMeta, RegistryConfig, PRIMARY_KEY
from .exceptions import RegistryError
__all__ = ["AutoRegisterMeta", "RegistryConfig", "PRIMARY_KEY", "RegistryError"]
EOF

- name: Verify installation
run: |
python -c "import polystore; print(f'polystore {polystore.__version__} installed successfully')"
Expand All @@ -59,7 +48,7 @@ jobs:
python -m pytest --cov=polystore --cov-report=term-missing --cov-report=xml -v

- name: Upload coverage to Codecov
if: matrix.python-version == '3.12'
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
continue-on-error: true
uses: codecov/codecov-action@v3
with:
Expand Down
3 changes: 3 additions & 0 deletions .zgroup
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"zarr_format": 2
}
34 changes: 34 additions & 0 deletions TEST_PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Test coverage improvement plan

Goal: raise coverage from ~24% to 85%+ by adding small, high-leverage, parameterized tests that exercise the FileManager router and backend implementations.

Scope and strategy
- Focus first on the low-friction, high-return surface:
- `FileManager` (router) — exercises many backend code paths with little test code.
- `DiskBackend` and `MemoryBackend` — implement core IO, listing, formats.
- Add `Zarr` tests later when `zarr`/ome-zarr deps are available.

Approach
- Keep tests small and DRY using pytest fixtures and parameterization.
- Use `registry` fixture that supplies a minimal backend mapping (`disk`, `memory`).
- Provide a `FileManager` fixture that uses that registry so tests exercise the router.
- For each backend run the same set of assertions: save/load, batch ops, exists/ensure_directory, list_files, natural sorting for images, and error propagation for unknown backends.

Files to add (first wave)
- `tests/conftest.py` — fixtures: `registry`, `file_manager`, `sample_payloads`.
- `tests/test_filemanager_backends.py` — parameterized tests for `disk` and `memory`.

Next steps (after this wave)
- Expand disk-specific tests for CSV/JSON/Text handlers and symlink behavior.
- Add gated `zarr` tests using `pytest.importorskip('zarr')` and small synthetic stores.
- Add registry and cleanup tests to exercise lazy instantiation and cleanup paths.

How I'll validate
- Run the new tests and iteratively fix test issues.
- Run `pytest --cov=polystore --cov-report=term-missing` to monitor coverage improvements.

Notes
- Tests intentionally avoid heavy external deps (ome-zarr, tifffile) in the initial wave. These will be added behind `importorskip` so CI remains lightweight.

Author: automated scaffolding
Date: 2025-11-02
40 changes: 37 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ classifiers = [
dependencies = [
"numpy>=1.26.0",
"portalocker>=2.8.0", # Cross-platform file locking
"metaclass-registry>=0.1.0",
"metaclass-registry",
"zarr>=2.18.0,<3.0", # Required for ZarrStorageBackend
"ome-zarr>=0.11.0", # Required for OME-ZARR HCS compliance
]

[project.optional-dependencies]
Expand Down Expand Up @@ -94,6 +96,39 @@ docs = [
"sphinx-design>=0.5.0",
]

gpu = [
# Zarr
"zarr>=2.18.0,<3.0",
"ome-zarr>=0.11.0",

# PyTorch
"torch>=2.6.0,<2.8.0",
"torchvision>=0.21.0,<0.23.0",

# JAX
"jax>=0.5.3,<0.6.0",
"jaxlib>=0.5.3,<0.6.0",

# JAX CUDA plugins
"jax-cuda12-pjrt>=0.5.3,<0.6.0",
"jax-cuda12-plugin>=0.5.3,<0.6.0",

# CuPy
"cupy-cuda12x>=13.3.0,<14.0.0",

# CuCIM
"cucim-cu12>=25.6.0,<26.0.0",

# TensorFlow
"tensorflow>=2.19.0,<2.20.0",

# TensorFlow Probability
"tensorflow-probability[tf]>=0.25.0,<0.26.0",

# pyclesperanto
"pyclesperanto>=0.17.1",
]

[project.urls]
Homepage = "https://github.com/trissim/polystore"
Documentation = "https://polystore.readthedocs.io"
Expand Down Expand Up @@ -163,5 +198,4 @@ ignore = [
]

[tool.ruff.per-file-ignores]
"__init__.py" = ["F401"] # unused imports

"__init__.py" = ["F401"] # unused imports
17 changes: 11 additions & 6 deletions src/polystore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,9 @@
from .disk import DiskBackend

# Optional backends
try:
from .zarr import ZarrBackend
except ImportError:
ZarrBackend = None
# Zarr is a required backend for this project. Import it directly so
# missing dependency errors surface loudly during test/setup.
from .zarr import ZarrBackend

# File manager
from .filemanager import FileManager
Expand All @@ -43,11 +42,17 @@
UnsupportedFormatError,
)

# Streaming (optional)
# Streaming (optional and lazy)
# Don't import at module level - streaming is heavy and optional
# Users can import manually if needed: from polystore.streaming import StreamingBackend
try:
from .streaming import StreamingBackend
except ImportError:
StreamingBackend = None
# Streaming (optional and lazy)
# Don't import at module level - streaming is heavy and optional
# Users can import manually if needed: from polystore.streaming import StreamingBackend
StreamingBackend = None

__all__ = [
# Version
Expand All @@ -74,7 +79,7 @@
"StorageResolutionError",
"BackendNotFoundError",
"UnsupportedFormatError",
# Streaming
# Streaming (optional)
"StreamingBackend",
]

Loading