Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 11 additions & 1 deletion .github/workflows/python_package.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,22 @@ on: [push]

jobs:
pytest:
name: pytest for py${{ matrix.python-version }} on ${{ matrix.os }}
name: pytest for py${{ matrix.python-version }} on ${{ matrix.os }}${{ matrix.unpinned && ', unpinned' || '' }}

runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
python-version: [3.9, '3.10', '3.11', '3.12']
os: ['ubuntu-latest', 'macos-latest', 'windows-latest']
unpinned: [false]
include:
# One job installs the package without the pins of
# requirements.txt, as pip install microstructpy does, so that the
# tests see the dependency versions that users get.
- python-version: '3.12'
os: 'ubuntu-latest'
unpinned: true

steps:
- uses: actions/checkout@main
Expand All @@ -33,6 +41,7 @@ jobs:
pip install setuptools wheel
pip install flake8 pytest pytest-cov coveralls
- name: Install package requirements
if: ${{ !matrix.unpinned }}
run: pip install -r requirements.txt
- name: Install package
run: pip install -e .
Expand All @@ -47,6 +56,7 @@ jobs:
run: pytest --cov=src tests/

- name: Coveralls
if: ${{ !matrix.unpinned }}
env:
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
COVERALLS_FLAG_NAME: py${{ matrix.python-version }} on ${{ matrix.os }}
Expand Down
21 changes: 20 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,24 @@ All notable changes to this project will be documented in this file.
The format is based on `Keep a Changelog`_,
and this project adheres to `Semantic Versioning`_.

`1.6.1`_ - 2026-10-19
--------------------------
Fixed
'''''
- ``pip install microstructpy`` installs versions of numpy and MeshPy that
the package works with: numpy below 2 and MeshPy below 2026. With numpy 2,
the text files of the meshes cannot be read back, since numpy writes
integers as ``np.int64(4)``, and ``tangent_sphere`` fails. With MeshPy
2026, TetGen no longer keeps the elements of 3D meshes under
``max_volume``. numpy below 2 has no wheels for Python 3.13 and later, so
pip builds it from source there, which needs a compiler.

Changed
'''''''
- The continuous integration also runs the tests on an installation without
the pins of ``requirements.txt``, as ``pip install microstructpy`` does, so
that it sees the dependency versions that users get.

`1.6.0`_ - 2026-10-18
--------------------------
Added
Expand Down Expand Up @@ -508,7 +526,8 @@ Added

.. LINKS

.. _`Unreleased`: https://github.com/kip-hart/MicroStructPy/compare/v1.6.0...HEAD
.. _`Unreleased`: https://github.com/kip-hart/MicroStructPy/compare/v1.6.1...HEAD
.. _`1.6.1`: https://github.com/kip-hart/MicroStructPy/compare/v1.6.0...v1.6.1
.. _`1.6.0`: https://github.com/kip-hart/MicroStructPy/compare/v1.5.9...v1.6.0
.. _`1.5.9`: https://github.com/kip-hart/MicroStructPy/compare/v1.5.8...v1.5.9
.. _`1.5.8`: https://github.com/kip-hart/MicroStructPy/compare/v1.5.7...v1.5.8
Expand Down
2 changes: 1 addition & 1 deletion docs/source/sphinx_gallery/plot_demos.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
# them is edited, and the build would serve stale figures.
#
# Managed by docs/example_digest.py. Do not edit by hand.
EXAMPLES_DIGEST = 'e16a7babf54a2cfe'
EXAMPLES_DIGEST = '1cc876c00916b073'

example_dir = '../../../src/microstructpy/examples'

Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ def find_version(*fname):
'pybind11', # must come before meshpy for successful install
'lsq-ellipse',
'matplotlib>=3.4.0',
'meshpy>=2018.2.1',
'numpy>=1.22.2',
'meshpy>=2018.2.1,<2026', # TetGen of 2026 exceeds max_volume

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On the unpinned CI job you suggest doing after this release: I would land
it with this PR instead.

The argument is this release itself. 1.6.0 went to PyPI with 224 tests
passing and was broken for every user who installed it the normal way.
Nothing in the pipeline was capable of noticing, because every job installs
requirements.txt first and the pins there hide what install_requires
resolves to. The ceilings in this PR fix the versions we know about today.
They do not give CI the ability to see the next pair.

The gap is narrow and so is the job. One matrix entry that skips
requirements.txt:

    - name: Install package requirements
      if: matrix.unpinned != true
      run: pip install -r requirements.txt
    - name: Install package
      run: pip install -e .

with an unpinned: true entry added to the matrix, and continue-on-error
if you would rather it warns than blocks at first. Even as a warning it
would have caught this one, since the failure is 13 tests and not a
subtlety.

The reason I would not defer it is that the cost of the miss is already
known. A broken release is public, it needs a second release to undo, and
the people who hit it are the ones who installed the package for the first
time.

'numpy>=1.22.2,<2', # numpy 2 breaks the mesh text files

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ceilings are right and I confirmed the problem they fix. A clean
pip install microstructpy==1.6.0 on Python 3.12 resolves numpy 2.5.4 and
MeshPy 2026.1.1, and the 1.6.0 tests against that install give 13 failed,
211 passed. The four causes in your table account for all thirteen, test
for test.

Worth saying out loud how visible the first group is. Three of the seven
are test_periodic_cli, so the command line itself breaks. Anyone who
installs from PyPI and runs microstructpy --demo=periodic_2D.xml writes
mesh files that cannot be read back. That is the main path, not a corner.

I also checked that both ceilings are needed. With numpy held below 2,
MeshPy 2026.1.1 still fails the three max_volume tests, so capping numpy
alone would have left a quieter version of the same release.

One thing to add while you are here. This package has no
python_requires, and the classifiers stop at 3.12:

$ grep python_requires setup.py
(no output)

numpy below 2 has no releases for Python 3.13 or later, as you note. With
the new ceiling and no python_requires, a user on 3.13 gets a resolution
failure with a wall of candidate versions instead of being told the package
does not support their Python. Adding

    python_requires='>=3.9,<3.13',

turns that into one readable line, and it matches the classifiers. It also
stops pip from installing 1.6.1 on a Python where it cannot work.

'pygmsh>=7.0.2',
'pyquaternion',
'pyvoro-rimoli>=1.4.0', # pyvoro with the current Voro++
Expand Down
2 changes: 1 addition & 1 deletion src/microstructpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
import microstructpy.seeding
import microstructpy.verification

__version__ = '1.6.0'
__version__ = '1.6.1'
Loading