Development#
Installation for development#
PyGlider uses pixi to manage environments. To get started, clone the repo and install in editable mode:
git clone https://github.com/c-proof/pyglider.git
cd pyglider
pixi install
This installs pyglider itself as an editable package (changes to source files take effect immediately without reinstalling). The default environment includes the library and its dependencies. To also get the test dependencies:
pixi install -e test
If you prefer conda/pip without pixi, install the dependencies with conda and then do an editable pip install:
conda create -n pyglider-dev
conda activate pyglider-dev
conda install -c conda-forge dask netcdf4 xarray numpy scipy gsw
pip install -e .
Running the tests#
PyGlider uses pytest. To run the tests with pixi:
pixi run -e test pytest tests/
Or, if your environment already has the dependencies installed:
pytest tests/
Tests run the full processing pipeline on example data and compare the output against stored YAML “golden files” in tests/expected/. A test failure means the output has changed — either a regression or an intentional change that requires updating the golden files (see below).
How the YAML regression tests work#
Rather than committing binary NetCDF golden files to the repo, the tests summarize each output dataset into a compact YAML file and compare that instead. Each YAML file captures:
the list of variables
global attributes (excluding dynamic fields like
date_createdandhistory)per-variable CF attributes
per-variable statistics:
min,max,mean,std,n_valid,n_nanper-variable time-derivative statistics:
diff_mean,diff_std
This makes diffs human-readable: if a processing change shifts the mean salinity by 0.01 PSU, you see exactly that in the YAML diff rather than a binary blob change.
The golden files live under tests/expected/, organized by glider type and pipeline stage:
tests/expected/
example-seaexplorer/
L0-timeseries/
dfo-eva035-20190718.yml
dfo-eva035-20190718_adjusted.yml
L0-gridfiles/
dfo-eva035-20190718_grid_adjusted.yml
example-seaexplorer-raw/
L0-timeseries/
dfo-bb046-20200908.yml
example-slocum/
L0-timeseries/
dfo-rosie713-20190615.yml
dfo-rosie713-20190615_adjusted.yml
L0-gridfiles/
dfo-rosie713-20190615_grid_adjusted.yml
The test files (tests/test_*_yaml.py) each run the pipeline once at module load time, then use parametrized pytest tests to check each variable and attribute.
Updating golden files after an intentional change#
If you make a change to pyglider that intentionally alters the output — new variable, changed attribute, fixed a calculation — the YAML golden files need to be updated to reflect the new expected values.
Step 1: Run the tests to generate up-to-date output NC files:
pixi run -e test pytest tests/
The tests will fail (that’s expected), but the pipeline will have written fresh NC files to tests/example-data/.
Step 2: Regenerate the YAML golden files from those NC files:
python tests/_generate_expected_yaml.py
This reads each NC file, computes the same summary statistics used by the tests, and overwrites the YAML files in tests/expected/.
Step 3: Re-run the tests to confirm they now pass:
pixi run -e test pytest tests/
Step 4: Inspect the diff before committing:
git diff tests/expected/
The diff should show only the changes you intended. If unrelated variables or datasets changed, investigate before committing.
Test file inventory#
Test file |
What it covers |
|---|---|
|
SeaExplorer NRT sub and raw delayed L0 timeseries; interpolation behaviour |
|
Slocum L0 timeseries and profiles; CF/GliderDAC compliance |
|
SeaExplorer |
|
Slocum |
|
SeaExplorer-specific unit tests |
|
Utility function unit tests |
Making a release#
Releases are published to PyPI automatically when a version tag is pushed. The GitHub Actions workflow builds the package, publishes to TestPyPI, then PyPI, and creates a GitHub Release with auto-generated notes.
The version number is derived from git tags via setuptools-scm — there is no
version to manually bump.
Step 1: Tag the commit you want to release:
git tag v1.2.3
git push --tags
That’s it. The workflow triggers on any v* tag.
TestPyPI runs first as a smoke test. If it fails (e.g. the package already exists at that version on TestPyPI), you can re-tag after fixing, but note that TestPyPI does not allow re-uploading the same version — use a new tag.
Trusted Publishing must be configured on both PyPI and TestPyPI for the
pypi and testpypi GitHub Environments respectively. If the workflow’s
publish step fails with a permissions error, check that the environment is
configured in the repo settings and that the PyPI trusted publisher entry
matches the repo and workflow file name.
Numerical tolerances#
Statistics comparisons use relative tolerance rtol=1e-5 and atol=0.0. Integer counts (n_valid, n_nan) are compared exactly. Time monotonicity is checked as a separate test. The date_created, date_issued, and history global attributes are excluded from comparison because they change on every run.