Skip to content

wntr: Add version 1.5.0 - #4277

Draft
luhenry wants to merge 16 commits into
mainfrom
wntr
Draft

luhenry wants to merge 16 commits into
mainfrom
wntr

Conversation

@luhenry

@luhenry luhenry commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Compiles wntr's SWIG C++ extensions (_evaluator, _network_isolation) and the EPANET 2.0/2.2 and EPANET-MSX libraries it loads through ctypes. Upstream publishes no riscv64 wheel.

Mirrors upstream's build_test_wheels.yml.

Differs from upstream

  • Builds EPANET v2.1/v2.2 and EPANET-MSX from source - upstream commits x86_64-only Linux binaries
  • Runs auditwheel repair - upstream skips it and renames linux to manylinux2014

Matrix: cp312, cp313 - upstream builds cp310-cp313 only.

Testing

  • Runs inside cibuildwheel with wntr/tests, examples and pyproject.toml staged via test-sources - upstream sparse-checks them out in a separate job

License: Wheel bundles EPANET and EPANET-MSX (MIT) and the image's libgomp (GPL-3.0 with GCC Runtime Library Exception); upstream ships no licence text for EPANET, so the build adds it.

Patches

  • 0001-epanet-load-EPANET-libraries-from-linux-riscv64-on-riscv64.patch - To upstream [not yet submitted]. Without it the loader always opens libepanet/linux-x64, so EpanetSimulator and MSX fail to load. Reproduces on any non-x86_64 Linux.

First riscv64 CI run pending.

Build wntr's SWIG C++ extensions with cibuildwheel from the 1.5.0 tag,
mirroring upstream's build_test_wheels.yml. Upstream ships x86_64-only
EPANET 2.0/2.2 and EPANET-MSX shared libraries for Linux; compile them
for riscv64 from the sources they were built from (OpenWaterAnalytics
EPANET v2.1 and v2.2, USEPA EPANETMSX with its EPANET2.2 submodule) and
patch the ctypes loader to pick them up from libepanet/linux-riscv64.
luhenry added a commit that referenced this pull request Nov 2, 2026
GCC14 compiles EPANET-2.1's sources under strict -std=c99 and treats the
resulting implicit-declaration of mkstemp() (a POSIX function, not visible
under plain c99 without _DEFAULT_SOURCE/_POSIX_C_SOURCE) as a hard error.
Reproduce the Makefile's own CFLAGS on the command line (it replaces rather
than appends) and add the missing macro. See gotcha 226/525.
EPANET v2.2 declares cmake_minimum_required(VERSION 2.8.8), which the
CMake 4 shipped in manylinux_2_39_riscv64 rejects. Pass
CMAKE_POLICY_VERSION_MINIMUM=3.5 to its configure step.
EPANET-MSX's msxout.c only includes <stdlib.h> on Apple, so on Linux
calloc() and free() are implicitly declared, which GCC 14 rejects.
Force-include the header through CMAKE_C_FLAGS.
wntr/epanet/io.py does an unconditional `import six` but setup.py
never lists six in DEPENDENCIES or any extra, so installing the wheel
does not guarantee it. Reproduces as ModuleNotFoundError: No module
named 'six' on cp312/cp313 riscv64 CI, the first legs to get past
dependency resolution far enough to import wntr.
All four riscv64 build legs of PR #4277 were failing:
- cp310 failed during the build step itself: PIP_ONLY_BINARY=numpy
  blocks pip from falling back to an sdist build, and our registry's
  cp310 numpy riscv64 wheels stop at 2.2.2, below wntr's pyproject.toml
  build requirement numpy>=2.2.6. Drop numpy from PIP_ONLY_BINARY for
  cp310 only so pip builds it from source there; cp311-cp313 keep the
  fast prebuilt wheel since our registry already satisfies them.
- cp311 failed installing the wheel's [optional,test] test extras:
  rasterio/shapely/pyproj have no riscv64 wheel on our registry for
  cp310/cp311 (geopandas pulls them in transitively). The affected
  tests (test_gis.py) already guard those imports with try/except, so
  skip the 'optional' extra there and keep it for cp312/cp313 where
  the registry has every wheel the extra needs.
- cp312/cp313 got past both of the above and failed at pytest
  collection on the missing six dependency fixed in the previous
  commit.
_publish-wheel.yml now requires a matrix input (main's "publish:
Validate effective wheel targets"), but this PR branch forked before
that landed and wntr has never been merged to main, so
build-wntr.yml never picked up the matching one-line update every
already-published package's workflow got. The merge ref combines the
new required-input _publish-wheel.yml with this branch's old
build-wntr.yml, so any run has failed startup with "Input matrix is
required, but not provided".

Pass it the same way the mass-update commit did for every other
package's publish job.
wntr/tests/conftest.py os.chdir()s to a temp dir at import time, and
pyproject.toml's addopts=--doctest-modules then re-resolves the relative
--ignore=wntr/tests/test_demos.py (and test_examples.py) against that new
cwd, so they silently stop matching. pytest ends up importing
test_demos.py twice (as a regular test module and again for doctest
scanning), both failing with ModuleNotFoundError: No module named
'geopandas', since geopandas is deliberately not installed for
cp310/cp311 (CIBW_TEST_EXTRAS only installs the 'test' extra there).
Resolving the ignore paths with $PWD before cibuildwheel's test command
runs keeps them absolute and immune to the later chdir.
…ests

cp310/cp311's Build wheels step kept failing after narrowing
CIBW_TEST_EXTRAS to 'test' (dropping 'optional') to dodge rasterio/shapely/
pyproj/geopandas, which have no riscv64 wheel on our registry below cp312:

  FAILED wntr/tests/test_graphics.py::TestGraphics::test_plot_interactive_network1
  FAILED wntr/tests/test_graphics.py::TestGraphics::test_plot_leaflet_network1
  FAILED wntr/tests/test_graphics.py::TestGraphics::test_plot_leaflet_network_popup
  FAILED wntr/tests/test_graphics.py::TestGraphics::test_plot_valve_layer_gpd
  FAILED wntr/tests/test_graphics.py::TestGraphics::test_plot_valve_layer_with_attribute
  FAILED wntr/tests/test_morph.py::TestMorph::test_UTM_to_longlat_to_UTM
  FAILED wntr/tests/test_morph.py::TestMorph::test_convert_node_coordinates_to_longlat

Five of these seven only need plotly or the utm package (both pure-Python,
with no riscv64-specific wheel problem of their own - they were simply never
installed once the whole 'optional' extra was dropped). Only the last two,
test_plot_valve_layer_gpd and test_plot_valve_layer_with_attribute, actually
exercise the geopandas/shapely-backed gpd plotting backend that the registry
gap blocks.

Install plotly and utm directly via CIBW_TEST_REQUIRES on cp310/cp311 instead
of losing their tests along with the rest of 'optional', and deselect only
the two tests that genuinely need geopandas/shapely.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant