Skip to content

Update lock files plus test fixes - #7270

Merged
ESadek-MO merged 7 commits into
SciTools:mainfrom
trexfeathers:replace-7243
Sep 7, 2026
Merged

ESadek-MO merged 7 commits into
SciTools:mainfrom
trexfeathers:replace-7243

Conversation

@trexfeathers

@trexfeathers trexfeathers commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Description

Closes #7243

Have tested and proven that the remaining failures result from the incompatible combination of PROJ>=9.8 and Cartopy <0.26. Have therefore skipped the relevant tests.

Checklist

Important

The Iris core developers are here to help! If anything below is unclear, just post a comment asking for help 😊


Tip

Things you can trigger on this PR:

  • Add this label to trigger benchmarks: benchmark_this Request that this pull request be benchmarked to check if it introduces performance shifts
  • Visit this URL - swapping 9999 for this PR's number - to re-trigger the CLA check:
    https://cla-assistant.io/check/SciTools/iris?pullRequest=9999

@trexfeathers
trexfeathers marked this pull request as draft September 7, 2026 14:31
@github-actions github-actions Bot added the benchmark_this Request that this pull request be benchmarked to check if it introduces performance shifts label Sep 7, 2026
@codecov

codecov Bot commented Sep 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.35%. Comparing base (d9ebbaf) to head (4c51d43).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7270      +/-   ##
==========================================
- Coverage   90.42%   90.35%   -0.07%     
==========================================
  Files          93       93              
  Lines       25816    25816              
  Branches     4796     4796              
==========================================
- Hits        23344    23327      -17     
- Misses       1693     1709      +16     
- Partials      779      780       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@trexfeathers

Copy link
Copy Markdown
Contributor Author

Closes #7243

@trexfeathers
trexfeathers marked this pull request as ready for review September 7, 2026 15:50

@ESadek-MO ESadek-MO left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @trexfeathers, all looks good!

@ESadek-MO
ESadek-MO merged commit 253510b into SciTools:main Sep 7, 2026
22 checks passed
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

⏱️ Performance Benchmark Report: 31016d7

Performance shifts
| Change   | Before [d9ebbaf5]    | After [31016d78]    |   Ratio | Benchmark (Parameter)   |
|----------|----------------------|---------------------|---------|-------------------------|
| -        | 88.7±0.4μs           | 63.1±0.7μs          |    0.71 | iterate.IZip.time_izip  |
| Change   | Before [d9ebbaf5]    | After [31016d78]    |    Ratio | Benchmark (Parameter)                                                          |
|----------|----------------------|---------------------|----------|--------------------------------------------------------------------------------|
| +        | 388±2μs              | 470±10μs            |     1.21 | cube.CubeCreation.time_create(False, 'instantiate')                            |
| +        | 16.8±0.2μs           | 63.9±4μs            |     3.8  | cube.CubeEquality.time_equality(False, False, 'metadata_inequality')           |
| +        | 16.9±0.2μs           | 67.1±2μs            |     3.97 | cube.CubeEquality.time_equality(False, True, 'metadata_inequality')            |
| +        | 53.7±0.2μs           | 90.4±2μs            |     1.68 | cube.CubeEquality.time_equality(True, False, 'metadata_inequality')            |
| +        | 362±2ns              | 5.74±0.1ms          | 15840.9  | mesh.utils.regions_combine.CombineRegionsComputeRealData.time_compute_data(50) |
| +        | 92.8±6ns             | 1.15±0.3μs          |    12.41 | save.NetcdfSave.time_netcdf_save_mesh(50, False)                               |
| +        | 91.6±0.5ns           | 2.43±0.2μs          |    26.56 | save.NetcdfSave.time_netcdf_save_mesh(600, False)                              |
Full benchmark results

Benchmarks that have improved:

| Change   | Before [d9ebbaf5]    | After [31016d78]    |   Ratio | Benchmark (Parameter)   |
|----------|----------------------|---------------------|---------|-------------------------|
| -        | 88.7±0.4μs           | 63.1±0.7μs          |    0.71 | iterate.IZip.time_izip  |

Benchmarks that have stayed the same:

| Change   | Before [d9ebbaf5]    | After [31016d78]    |   Ratio | Benchmark (Parameter)                                                                       |
|----------|----------------------|---------------------|---------|---------------------------------------------------------------------------------------------|
|          | 21.4±1ms             | 21.8±1ms            |    1.02 | aggregate_collapse.Aggregation.time_aggregated_by_COUNT(False)                              |
|          | 53.4±2ms             | 53.7±1ms            |    1.01 | aggregate_collapse.Aggregation.time_aggregated_by_COUNT(True)                               |
|          | 36.7±2ms             | 36.0±2ms            |    0.98 | aggregate_collapse.Aggregation.time_aggregated_by_FAST_PERCENTILE(False)                    |
|          | 168±10ms             | 172±4ms             |    1.02 | aggregate_collapse.Aggregation.time_aggregated_by_FAST_PERCENTILE(True)                     |
|          | 24.0±2ms             | 23.3±2ms            |    0.97 | aggregate_collapse.Aggregation.time_aggregated_by_GMEAN(False)                              |
|          | 31.7±0.3ms           | 32.4±0.5ms          |    1.02 | aggregate_collapse.Aggregation.time_aggregated_by_GMEAN(True)                               |
|          | 23.9±1ms             | 24.1±2ms            |    1.01 | aggregate_collapse.Aggregation.time_aggregated_by_HMEAN(False)                              |
|          | 32.3±1ms             | 32.5±0.7ms          |    1.01 | aggregate_collapse.Aggregation.time_aggregated_by_HMEAN(True)                               |
|          | 21.7±2ms             | 21.3±2ms            |    0.98 | aggregate_collapse.Aggregation.time_aggregated_by_MAX(False)                                |
|          | 45.8±2ms             | 45.2±0.9ms          |    0.99 | aggregate_collapse.Aggregation.time_aggregated_by_MAX(True)                                 |
|          | 140±2ms              | 140±3ms             |    1    | aggregate_collapse.Aggregation.time_aggregated_by_MAX_RUN(False)                            |
|          | 136±4ms              | 135±0.7ms           |    1    | aggregate_collapse.Aggregation.time_aggregated_by_MAX_RUN(True)                             |
|          | 23.9±2ms             | 22.7±2ms            |    0.95 | aggregate_collapse.Aggregation.time_aggregated_by_MEAN(False)                               |
|          | 49.6±3ms             | 48.5±1ms            |    0.98 | aggregate_collapse.Aggregation.time_aggregated_by_MEAN(True)                                |
|          | 23.5±1ms             | 24.0±2ms            |    1.02 | aggregate_collapse.Aggregation.time_aggregated_by_MEDIAN(False)                             |
|          | 59.7±1ms             | 58.7±0.9ms          |    0.98 | aggregate_collapse.Aggregation.time_aggregated_by_MEDIAN(True)                              |
|          | 21.2±2ms             | 21.2±2ms            |    1    | aggregate_collapse.Aggregation.time_aggregated_by_MIN(False)                                |
|          | 45.3±0.6ms           | 44.3±2ms            |    0.98 | aggregate_collapse.Aggregation.time_aggregated_by_MIN(True)                                 |
|          | 1.09±0.01s           | 1.10±0.01s          |    1.01 | aggregate_collapse.Aggregation.time_aggregated_by_PEAK(False)                               |
|          | 1.08±0s              | 1.08±0.01s          |    1    | aggregate_collapse.Aggregation.time_aggregated_by_PEAK(True)                                |
|          | 225±4ms              | 219±2ms             |    0.98 | aggregate_collapse.Aggregation.time_aggregated_by_PERCENTILE(False)                         |
|          | 369±10ms             | 367±10ms            |    0.99 | aggregate_collapse.Aggregation.time_aggregated_by_PERCENTILE(True)                          |
|          | 22.6±2ms             | 22.5±2ms            |    0.99 | aggregate_collapse.Aggregation.time_aggregated_by_PROPORTION(False)                         |
|          | 29.8±1ms             | 30.7±0.3ms          |    1.03 | aggregate_collapse.Aggregation.time_aggregated_by_PROPORTION(True)                          |
|          | 23.7±2ms             | 23.1±2ms            |    0.98 | aggregate_collapse.Aggregation.time_aggregated_by_RMS(False)                                |
|          | 60.4±2ms             | 59.2±1ms            |    0.98 | aggregate_collapse.Aggregation.time_aggregated_by_RMS(True)                                 |
|          | 24.7±2ms             | 23.8±2ms            |    0.96 | aggregate_collapse.Aggregation.time_aggregated_by_STD_DEV(False)                            |
|          | 63.7±3ms             | 61.8±0.9ms          |    0.97 | aggregate_collapse.Aggregation.time_aggregated_by_STD_DEV(True)                             |
|          | 23.7±2ms             | 23.2±2ms            |    0.98 | aggregate_collapse.Aggregation.time_aggregated_by_VARIANCE(False)                           |
|          | 59.6±2ms             | 58.4±2ms            |    0.98 | aggregate_collapse.Aggregation.time_aggregated_by_VARIANCE(True)                            |
|          | 7.71±0.1ms           | 7.80±0.05ms         |    1.01 | aggregate_collapse.Aggregation.time_collapsed_by_COUNT(False)                               |
|          | 22.4±0.5ms           | 22.6±0.7ms          |    1.01 | aggregate_collapse.Aggregation.time_collapsed_by_COUNT(True)                                |
|          | 19.7±0.5ms           | 19.7±0.3ms          |    1    | aggregate_collapse.Aggregation.time_collapsed_by_FAST_PERCENTILE(False)                     |
|          | 132±10ms             | 138±4ms             |    1.04 | aggregate_collapse.Aggregation.time_collapsed_by_FAST_PERCENTILE(True)                      |
|          | 8.11±0.04ms          | 8.45±0.09ms         |    1.04 | aggregate_collapse.Aggregation.time_collapsed_by_GMEAN(False)                               |
|          | 20.3±0.8ms           | 20.8±0.2ms          |    1.02 | aggregate_collapse.Aggregation.time_collapsed_by_GMEAN(True)                                |
|          | 8.16±0.07ms          | 8.52±0.2ms          |    1.05 | aggregate_collapse.Aggregation.time_collapsed_by_HMEAN(False)                               |
|          | 20.3±0.5ms           | 20.6±0.2ms          |    1.02 | aggregate_collapse.Aggregation.time_collapsed_by_HMEAN(True)                                |
|          | 7.60±0.04ms          | 7.86±0.1ms          |    1.03 | aggregate_collapse.Aggregation.time_collapsed_by_MAX(False)                                 |
|          | 21.2±0.8ms           | 20.9±0.4ms          |    0.99 | aggregate_collapse.Aggregation.time_collapsed_by_MAX(True)                                  |
|          | 26.7±2ms             | 26.1±2ms            |    0.98 | aggregate_collapse.Aggregation.time_collapsed_by_MAX_RUN(False)                             |
|          | 35.4±0.8ms           | 37.9±1ms            |    1.07 | aggregate_collapse.Aggregation.time_collapsed_by_MAX_RUN(True)                              |
|          | 7.95±0.1ms           | 8.03±0.07ms         |    1.01 | aggregate_collapse.Aggregation.time_collapsed_by_MEAN(False)                                |
|          | 21.3±0.8ms           | 21.3±0.4ms          |    1    | aggregate_collapse.Aggregation.time_collapsed_by_MEAN(True)                                 |
|          | 8.99±0.1ms           | 9.04±0.1ms          |    1.01 | aggregate_collapse.Aggregation.time_collapsed_by_MEDIAN(False)                              |
|          | 23.3±0.4ms           | 23.7±0.5ms          |    1.02 | aggregate_collapse.Aggregation.time_collapsed_by_MEDIAN(True)                               |
|          | 7.54±0.05ms          | 7.71±0.09ms         |    1.02 | aggregate_collapse.Aggregation.time_collapsed_by_MIN(False)                                 |
|          | 21.1±0.6ms           | 21.3±0.5ms          |    1.01 | aggregate_collapse.Aggregation.time_collapsed_by_MIN(True)                                  |
|          | 572±2ms              | 575±1ms             |    1    | aggregate_collapse.Aggregation.time_collapsed_by_PEAK(False)                                |
|          | 578±2ms              | 581±1ms             |    1.01 | aggregate_collapse.Aggregation.time_collapsed_by_PEAK(True)                                 |
|          | 46.9±0.7ms           | 45.9±0.4ms          |    0.98 | aggregate_collapse.Aggregation.time_collapsed_by_PERCENTILE(False)                          |
|          | 146±10ms             | 145±4ms             |    0.99 | aggregate_collapse.Aggregation.time_collapsed_by_PERCENTILE(True)                           |
|          | 7.88±0.1ms           | 7.93±0.1ms          |    1.01 | aggregate_collapse.Aggregation.time_collapsed_by_PROPORTION(False)                          |
|          | 20.1±0.6ms           | 20.3±0.2ms          |    1.01 | aggregate_collapse.Aggregation.time_collapsed_by_PROPORTION(True)                           |
|          | 7.95±0.06ms          | 8.10±0.1ms          |    1.02 | aggregate_collapse.Aggregation.time_collapsed_by_RMS(False)                                 |
|          | 23.3±0.7ms           | 23.3±0.3ms          |    1    | aggregate_collapse.Aggregation.time_collapsed_by_RMS(True)                                  |
|          | 8.24±0.1ms           | 8.22±0.09ms         |    1    | aggregate_collapse.Aggregation.time_collapsed_by_STD_DEV(False)                             |
|          | 22.5±0.8ms           | 22.8±0.4ms          |    1.01 | aggregate_collapse.Aggregation.time_collapsed_by_STD_DEV(True)                              |
|          | 8.21±0.06ms          | 8.28±0.05ms         |    1.01 | aggregate_collapse.Aggregation.time_collapsed_by_VARIANCE(False)                            |
|          | 22.0±0.4ms           | 22.0±0.3ms          |    1    | aggregate_collapse.Aggregation.time_collapsed_by_VARIANCE(True)                             |
|          | 23.0±2ms             | 22.7±2ms            |    0.98 | aggregate_collapse.WeightedAggregation.time_w_aggregated_by_MEAN(False)                     |
|          | 83.9±1ms             | 84.0±0.8ms          |    1    | aggregate_collapse.WeightedAggregation.time_w_aggregated_by_MEAN(True)                      |
|          | 23.5±2ms             | 22.5±2ms            |    0.95 | aggregate_collapse.WeightedAggregation.time_w_aggregated_by_RMS(False)                      |
|          | 95.6±1ms             | 94.6±0.5ms          |    0.99 | aggregate_collapse.WeightedAggregation.time_w_aggregated_by_RMS(True)                       |
|          | 22.2±2ms             | 23.0±2ms            |    1.04 | aggregate_collapse.WeightedAggregation.time_w_aggregated_by_SUM(False)                      |
|          | 55.8±3ms             | 54.8±1ms            |    0.98 | aggregate_collapse.WeightedAggregation.time_w_aggregated_by_SUM(True)                       |
|          | 8.14±0.05ms          | 8.49±0.1ms          |    1.04 | aggregate_collapse.WeightedAggregation.time_w_collapsed_by_MEAN(False)                      |
|          | 27.7±0.6ms           | 27.7±0.3ms          |    1    | aggregate_collapse.WeightedAggregation.time_w_collapsed_by_MEAN(True)                       |
|          | 8.02±0.09ms          | 8.17±0.05ms         |    1.02 | aggregate_collapse.WeightedAggregation.time_w_collapsed_by_RMS(False)                       |
|          | 29.7±0.6ms           | 28.8±0.6ms          |    0.97 | aggregate_collapse.WeightedAggregation.time_w_collapsed_by_RMS(True)                        |
|          | 7.88±0.09ms          | 7.96±0.07ms         |    1.01 | aggregate_collapse.WeightedAggregation.time_w_collapsed_by_SUM(False)                       |
|          | 22.8±0.5ms           | 22.6±0.4ms          |    0.99 | aggregate_collapse.WeightedAggregation.time_w_collapsed_by_SUM(True)                        |
|          | 210±2ms              | 208±0.8ms           |    0.99 | aggregate_collapse.WeightedAggregation.time_w_collapsed_by_WPERCENTILE(False)               |
|          | 286±8ms              | 278±2ms             |    0.97 | aggregate_collapse.WeightedAggregation.time_w_collapsed_by_WPERCENTILE(True)                |
|          | 1.14±0.01ms          | 1.24±0.03ms         |    1.08 | cube.CubeCreation.time_create(False, 'construct')                                           |
|          | 1.87±0.02ms          | 1.95±0.02ms         |    1.04 | cube.CubeCreation.time_create(True, 'construct')                                            |
|          | 1.33±0.02ms          | 1.41±0.02ms         |    1.05 | cube.CubeCreation.time_create(True, 'instantiate')                                          |
|          | 86.6±4ms             | 87.9±4ms            |    1.01 | cube.CubeEquality.time_equality(False, False, 'all_equal')                                  |
|          | 25.9±1ms             | 26.4±0.8ms          |    1.02 | cube.CubeEquality.time_equality(False, False, 'coord_inequality')                           |
|          | 95.5±4ms             | 101±6ms             |    1.06 | cube.CubeEquality.time_equality(False, False, 'data_inequality')                            |
|          | 83.6±2ms             | 88.1±3ms            |    1.05 | cube.CubeEquality.time_equality(False, True, 'all_equal')                                   |
|          | 29.0±0.9ms           | 29.6±0.5ms          |    1.02 | cube.CubeEquality.time_equality(False, True, 'coord_inequality')                            |
|          | 101±3ms              | 107±3ms             |    1.06 | cube.CubeEquality.time_equality(False, True, 'data_inequality')                             |
|          | 168±3ms              | 172±6ms             |    1.03 | cube.CubeEquality.time_equality(True, False, 'all_equal')                                   |
|          | 69.1±3ms             | 71.3±2ms            |    1.03 | cube.CubeEquality.time_equality(True, False, 'coord_inequality')                            |
|          | 191±7ms              | 208±9ms             |    1.09 | cube.CubeEquality.time_equality(True, False, 'data_inequality')                             |
|          | 243±10ms             | 255±9ms             |    1.05 | cube.CubeEquality.time_equality(True, True, 'all_equal')                                    |
|          | 145±6ms              | 146±6ms             |    1.01 | cube.CubeEquality.time_equality(True, True, 'coord_inequality')                             |
|          | 270±10ms             | 283±9ms             |    1.05 | cube.CubeEquality.time_equality(True, True, 'data_inequality')                              |
|          | 335±5μs              | 397±8μs             |    1.18 | cube.CubeEquality.time_equality(True, True, 'metadata_inequality')                          |
|          | 892±30μs             | 872±20μs            |    0.98 | import_iris.Iris.time__concatenate                                                          |
|          | 194±6μs              | 190±10μs            |    0.98 | import_iris.Iris.time__constraints                                                          |
|          | 121±1μs              | 118±2μs             |    0.98 | import_iris.Iris.time__data_manager                                                         |
|          | 101±0.9μs            | 103±0.8μs           |    1.02 | import_iris.Iris.time__deprecation                                                          |
|          | 172±3μs              | 168±2μs             |    0.98 | import_iris.Iris.time__lazy_data                                                            |
|          | 998±9μs              | 994±9μs             |    1    | import_iris.Iris.time__merge                                                                |
|          | 74.3±0.4μs           | 75.2±0.8μs          |    1.01 | import_iris.Iris.time__representation                                                       |
|          | 641±10μs             | 629±10μs            |    0.98 | import_iris.Iris.time_analysis                                                              |
|          | 145±4μs              | 143±2μs             |    0.99 | import_iris.Iris.time_analysis__area_weighted                                               |
|          | 126±7μs              | 125±3μs             |    1    | import_iris.Iris.time_analysis__grid_angles                                                 |
|          | 262±6μs              | 257±4μs             |    0.98 | import_iris.Iris.time_analysis__interpolation                                               |
|          | 192±4μs              | 190±4μs             |    0.99 | import_iris.Iris.time_analysis__regrid                                                      |
|          | 111±2μs              | 112±0.6μs           |    1.01 | import_iris.Iris.time_analysis__scipy_interpolate                                           |
|          | 141±2μs              | 143±0.8μs           |    1.01 | import_iris.Iris.time_analysis_calculus                                                     |
|          | 339±5μs              | 336±3μs             |    0.99 | import_iris.Iris.time_analysis_cartography                                                  |
|          | 91.6±1μs             | 91.0±0.4μs          |    0.99 | import_iris.Iris.time_analysis_geomerty                                                     |
|          | 214±2μs              | 211±2μs             |    0.99 | import_iris.Iris.time_analysis_maths                                                        |
|          | 94.9±0.8μs           | 96.7±1μs            |    1.02 | import_iris.Iris.time_analysis_stats                                                        |
|          | 175±3μs              | 173±2μs             |    0.99 | import_iris.Iris.time_analysis_trajectory                                                   |
|          | 321±4μs              | 337±20μs            |    1.05 | import_iris.Iris.time_aux_factory                                                           |
|          | 80.9±0.5μs           | 81.5±0.5μs          |    1.01 | import_iris.Iris.time_common                                                                |
|          | 164±2μs              | 162±1μs             |    0.98 | import_iris.Iris.time_common_lenient                                                        |
|          | 1.58±0.03ms          | 1.58±0.06ms         |    1    | import_iris.Iris.time_common_metadata                                                       |
|          | 179±1μs              | 180±3μs             |    1.01 | import_iris.Iris.time_common_mixin                                                          |
|          | 1.20±0.02ms          | 1.19±0.02ms         |    0.99 | import_iris.Iris.time_common_resolve                                                        |
|          | 256±1μs              | 267±20μs            |    1.04 | import_iris.Iris.time_config                                                                |
|          | 136±0.7μs            | 135±2μs             |    0.99 | import_iris.Iris.time_coord_categorisation                                                  |
|          | 387±10μs             | 392±20μs            |    1.01 | import_iris.Iris.time_coord_systems                                                         |
|          | 879±20μs             | 824±10μs            |    0.94 | import_iris.Iris.time_coords                                                                |
|          | 785±30μs             | 770±40μs            |    0.98 | import_iris.Iris.time_cube                                                                  |
|          | 267±4μs              | 270±8μs             |    1.01 | import_iris.Iris.time_exceptions                                                            |
|          | 74.7±0.6μs           | 75.4±0.9μs          |    1.01 | import_iris.Iris.time_experimental                                                          |
|          | 193±4μs              | 191±1μs             |    0.99 | import_iris.Iris.time_fileformats                                                           |
|          | 262±2μs              | 258±4μs             |    0.99 | import_iris.Iris.time_fileformats__ff                                                       |
|          | 2.62±0.01ms          | 2.56±0.1ms          |    0.98 | import_iris.Iris.time_fileformats__ff_cross_references                                      |
|          | 76.3±0.5μs           | 77.8±1μs            |    1.02 | import_iris.Iris.time_fileformats__pp_lbproc_pairs                                          |
|          | 117±2μs              | 118±0.6μs           |    1.01 | import_iris.Iris.time_fileformats_abf                                                       |
|          | 451±9μs              | 450±10μs            |    1    | import_iris.Iris.time_fileformats_cf                                                        |
|          | 4.79±0.08ms          | 4.87±0.3ms          |    1.02 | import_iris.Iris.time_fileformats_dot                                                       |
|          | 70.5±0.3μs           | 72.9±1μs            |    1.03 | import_iris.Iris.time_fileformats_name                                                      |
|          | 259±10μs             | 261±2μs             |    1.01 | import_iris.Iris.time_fileformats_name_loaders                                              |
|          | 116±2μs              | 117±0.9μs           |    1.01 | import_iris.Iris.time_fileformats_netcdf                                                    |
|          | 159±5μs              | 165±3μs             |    1.04 | import_iris.Iris.time_fileformats_nimrod                                                    |
|          | 320±7μs              | 322±2μs             |    1.01 | import_iris.Iris.time_fileformats_nimrod_load_rules                                         |
|          | 807±10μs             | 814±10μs            |    1.01 | import_iris.Iris.time_fileformats_pp                                                        |
|          | 178±4μs              | 172±4μs             |    0.97 | import_iris.Iris.time_fileformats_pp_load_rules                                             |
|          | 135±2μs              | 134±1μs             |    0.99 | import_iris.Iris.time_fileformats_pp_save_rules                                             |
|          | 576±4μs              | 582±9μs             |    1.01 | import_iris.Iris.time_fileformats_rules                                                     |
|          | 230±3μs              | 229±1μs             |    1    | import_iris.Iris.time_fileformats_structured_array_identification                           |
|          | 80.3±0.4μs           | 82.0±0.8μs          |    1.02 | import_iris.Iris.time_fileformats_um                                                        |
|          | 160±3μs              | 161±1μs             |    1.01 | import_iris.Iris.time_fileformats_um__fast_load                                             |
|          | 139±2μs              | 144±7μs             |    1.04 | import_iris.Iris.time_fileformats_um__fast_load_structured_fields                           |
|          | 73.8±1μs             | 73.0±0.7μs          |    0.99 | import_iris.Iris.time_fileformats_um__ff_replacement                                        |
|          | 79.2±0.5μs           | 80.8±1μs            |    1.02 | import_iris.Iris.time_fileformats_um__optimal_array_structuring                             |
|          | 968±8μs              | 945±7μs             |    0.98 | import_iris.Iris.time_fileformats_um_cf_map                                                 |
|          | 145±3μs              | 145±2μs             |    1    | import_iris.Iris.time_io                                                                    |
|          | 183±2μs              | 184±4μs             |    1    | import_iris.Iris.time_io_format_picker                                                      |
|          | 206±2μs              | 206±2μs             |    1    | import_iris.Iris.time_iris                                                                  |
|          | 129±3μs              | 130±2μs             |    1.01 | import_iris.Iris.time_iterate                                                               |
|          | 34.2±0.3ms           | 34.6±0.2ms          |    1.01 | import_iris.Iris.time_palette                                                               |
|          | 1.87±0.02ms          | 1.91±0.06ms         |    1.02 | import_iris.Iris.time_plot                                                                  |
|          | 258±30μs             | 266±20μs            |    1.03 | import_iris.Iris.time_quickplot                                                             |
|          | 2.20±0.02ms          | 2.14±0.04ms         |    0.97 | import_iris.Iris.time_std_names                                                             |
|          | 1.89±0.01ms          | 1.85±0.01ms         |    0.98 | import_iris.Iris.time_symbols                                                               |
|          | 94.4±20ms            | 96.8±3ms            |    1.03 | import_iris.Iris.time_tests                                                                 |
|          | 238±7μs              | 257±2μs             |    1.08 | import_iris.Iris.time_third_party_cartopy                                                   |
|          | 5.13±0.1ms           | 5.12±0.07ms         |    1    | import_iris.Iris.time_third_party_cf_units                                                  |
|          | 122±0.8μs            | 123±0.5μs           |    1.01 | import_iris.Iris.time_third_party_cftime                                                    |
|          | 2.57±0.02ms          | 2.58±0.02ms         |    1    | import_iris.Iris.time_third_party_matplotlib                                                |
|          | 532±7μs              | 526±6μs             |    0.99 | import_iris.Iris.time_third_party_numpy                                                     |
|          | 175±3μs              | 177±0.6μs           |    1.01 | import_iris.Iris.time_third_party_scipy                                                     |
|          | 99.8±1μs             | 103±2μs             |    1.03 | import_iris.Iris.time_time                                                                  |
|          | 867±10μs             | 852±5μs             |    0.98 | import_iris.Iris.time_util                                                                  |
|          | 10.1±0.08ms          | 10.1±0.1ms          |    1.01 | load.LoadAndRealise.time_load((1280, 960, 5), False, 'FF')                                  |
|          | 17.3±0.5ms           | 17.8±0.5ms          |    1.03 | load.LoadAndRealise.time_load((1280, 960, 5), False, 'NetCDF')                              |
|          | 9.91±0.2ms           | 9.99±0.1ms          |    1.01 | load.LoadAndRealise.time_load((1280, 960, 5), False, 'PP')                                  |
|          | 10.1±0.09ms          | 10.1±0.1ms          |    1    | load.LoadAndRealise.time_load((1280, 960, 5), True, 'FF')                                   |
|          | 14.4±0.3ms           | 14.4±0.3ms          |    1    | load.LoadAndRealise.time_load((1280, 960, 5), True, 'NetCDF')                               |
|          | 9.95±0.08ms          | 9.82±0.3ms          |    0.99 | load.LoadAndRealise.time_load((1280, 960, 5), True, 'PP')                                   |
|          | 1.53±0.02s           | 1.53±0.03s          |    1    | load.LoadAndRealise.time_load((2, 2, 1000), False, 'FF')                                    |
|          | 13.2±0.2ms           | 14.0±0.5ms          |    1.06 | load.LoadAndRealise.time_load((2, 2, 1000), False, 'NetCDF')                                |
|          | 1.52±0.01s           | 1.52±0.01s          |    1    | load.LoadAndRealise.time_load((2, 2, 1000), False, 'PP')                                    |
|          | 1.52±0.02s           | 1.55±0.02s          |    1.02 | load.LoadAndRealise.time_load((2, 2, 1000), True, 'FF')                                     |
|          | 13.2±0.3ms           | 13.6±0.3ms          |    1.03 | load.LoadAndRealise.time_load((2, 2, 1000), True, 'NetCDF')                                 |
|          | 1.52±0.01s           | 1.52±0.02s          |    1    | load.LoadAndRealise.time_load((2, 2, 1000), True, 'PP')                                     |
|          | 5.28±0.03ms          | 5.41±0.2ms          |    1.02 | load.LoadAndRealise.time_load((50, 50, 2), False, 'FF')                                     |
|          | 12.9±0.3ms           | 13.3±0.6ms          |    1.03 | load.LoadAndRealise.time_load((50, 50, 2), False, 'NetCDF')                                 |
|          | 5.12±0.05ms          | 5.19±0.04ms         |    1.01 | load.LoadAndRealise.time_load((50, 50, 2), False, 'PP')                                     |
|          | 5.28±0.04ms          | 5.35±0.2ms          |    1.01 | load.LoadAndRealise.time_load((50, 50, 2), True, 'FF')                                      |
|          | 13.4±0.3ms           | 13.3±0.2ms          |    1    | load.LoadAndRealise.time_load((50, 50, 2), True, 'NetCDF')                                  |
|          | 5.22±0.05ms          | 5.11±0.04ms         |    0.98 | load.LoadAndRealise.time_load((50, 50, 2), True, 'PP')                                      |
|          | 22.4±1ms             | 23.8±2ms            |    1.06 | load.LoadAndRealise.time_realise((1280, 960, 5), False, 'FF')                               |
|          | 22.0±1ms             | 23.3±1ms            |    1.06 | load.LoadAndRealise.time_realise((1280, 960, 5), False, 'NetCDF')                           |
|          | 12.7±1ms             | 14.2±2ms            |    1.12 | load.LoadAndRealise.time_realise((1280, 960, 5), False, 'PP')                               |
|          | 28.6±1ms             | 30.0±1ms            |    1.05 | load.LoadAndRealise.time_realise((1280, 960, 5), True, 'FF')                                |
|          | 82.2±2ms             | 72.4±2ms            |    0.88 | load.LoadAndRealise.time_realise((1280, 960, 5), True, 'NetCDF')                            |
|          | 28.4±0.9ms           | 29.1±1ms            |    1.03 | load.LoadAndRealise.time_realise((1280, 960, 5), True, 'PP')                                |
|          | 642±8ms              | 645±8ms             |    1.01 | load.LoadAndRealise.time_realise((2, 2, 1000), False, 'FF')                                 |
|          | 3.64±0.4ms           | 3.58±0.2ms          |    0.98 | load.LoadAndRealise.time_realise((2, 2, 1000), False, 'NetCDF')                             |
|          | 647±20ms             | 647±10ms            |    1    | load.LoadAndRealise.time_realise((2, 2, 1000), False, 'PP')                                 |
|          | 648±20ms             | 643±10ms            |    0.99 | load.LoadAndRealise.time_realise((2, 2, 1000), True, 'FF')                                  |
|          | 4.00±0.4ms           | 3.92±0.2ms          |    0.98 | load.LoadAndRealise.time_realise((2, 2, 1000), True, 'NetCDF')                              |
|          | 649±10ms             | 646±6ms             |    0.99 | load.LoadAndRealise.time_realise((2, 2, 1000), True, 'PP')                                  |
|          | 2.21±0.03ms          | 2.30±0.05ms         |    1.04 | load.LoadAndRealise.time_realise((50, 50, 2), False, 'FF')                                  |
|          | 3.47±0.2ms           | 3.77±0.2ms          |    1.09 | load.LoadAndRealise.time_realise((50, 50, 2), False, 'NetCDF')                              |
|          | 2.23±0.04ms          | 2.26±0.09ms         |    1.01 | load.LoadAndRealise.time_realise((50, 50, 2), False, 'PP')                                  |
|          | 2.23±0.06ms          | 2.32±0.08ms         |    1.04 | load.LoadAndRealise.time_realise((50, 50, 2), True, 'FF')                                   |
|          | 3.65±0.2ms           | 4.02±0.1ms          |    1.1  | load.LoadAndRealise.time_realise((50, 50, 2), True, 'NetCDF')                               |
|          | 2.38±0.1ms           | 2.39±0.09ms         |    1    | load.LoadAndRealise.time_realise((50, 50, 2), True, 'PP')                                   |
|          | 381±10ms             | 379±3ms             |    0.99 | load.ManyCubes.time_many_cube_load                                                          |
|          | 97.9±2ms             | 96.2±1ms            |    0.98 | load.ManyVars.time_many_var_load                                                            |
|          | 10.5±0.7ms           | 10.2±0.2ms          |    0.97 | load.STASHConstraint.time_stash_constraint((1280, 960, 5), 'FF')                            |
|          | 10.4±0.3ms           | 10.1±0.09ms         |    0.98 | load.STASHConstraint.time_stash_constraint((1280, 960, 5), 'PP')                            |
|          | 1.54±0.03s           | 1.56±0.04s          |    1.01 | load.STASHConstraint.time_stash_constraint((2, 2, 1000), 'FF')                              |
|          | 1.52±0.01s           | 1.54±0.02s          |    1.01 | load.STASHConstraint.time_stash_constraint((2, 2, 1000), 'PP')                              |
|          | 5.42±0.2ms           | 5.27±0.06ms         |    0.97 | load.STASHConstraint.time_stash_constraint((2, 2, 2), 'FF')                                 |
|          | 5.24±0.08ms          | 5.23±0.06ms         |    1    | load.STASHConstraint.time_stash_constraint((2, 2, 2), 'PP')                                 |
|          | 9.14±0.2ms           | 9.11±0.2ms          |    1    | load.StructuredFF.time_structured_load((1280, 960, 5), False)                               |
|          | 5.71±0.04ms          | 5.64±0.07ms         |    0.99 | load.StructuredFF.time_structured_load((1280, 960, 5), True)                                |
|          | 1.51±0.01s           | 1.52±0.02s          |    1    | load.StructuredFF.time_structured_load((2, 2, 1000), False)                                 |
|          | 428±7ms              | 434±8ms             |    1.01 | load.StructuredFF.time_structured_load((2, 2, 1000), True)                                  |
|          | 4.48±0.05ms          | 4.46±0.06ms         |    1    | load.StructuredFF.time_structured_load((2, 2, 2), False)                                    |
|          | 4.28±0.03ms          | 4.21±0.04ms         |    0.98 | load.StructuredFF.time_structured_load((2, 2, 2), True)                                     |
|          | 156±2ms              | 158±2ms             |    1.01 | load.TimeConstraint.time_time_constraint(20, 'FF')                                          |
|          | 16.1±0.5ms           | 16.3±0.6ms          |    1.01 | load.TimeConstraint.time_time_constraint(20, 'NetCDF')                                      |
|          | 154±2ms              | 159±0.6ms           |    1.03 | load.TimeConstraint.time_time_constraint(20, 'PP')                                          |
|          | 31.1±0.1ms           | 31.7±0.7ms          |    1.02 | load.TimeConstraint.time_time_constraint(3, 'FF')                                           |
|          | 15.3±0.6ms           | 16.5±0.1ms          |    1.08 | load.TimeConstraint.time_time_constraint(3, 'NetCDF')                                       |
|          | 30.7±1ms             | 31.4±0.7ms          |    1.02 | load.TimeConstraint.time_time_constraint(3, 'PP')                                           |
|          | 20.0±0.5ms           | 20.9±0.5ms          |    1.05 | load.ugrid.BasicLoading.time_load_file(1)                                                   |
|          | 49.9±0.9ms           | 52.1±1ms            |    1.04 | load.ugrid.BasicLoading.time_load_file(200000)                                              |
|          | 10.5±2ms             | 10.7±0.4ms          |    1.02 | load.ugrid.BasicLoading.time_load_mesh(1)                                                   |
|          | 18.6±0.8ms           | 18.8±0.7ms          |    1.01 | load.ugrid.BasicLoading.time_load_mesh(200000)                                              |
|          | 20.3±0.5ms           | 20.9±0.7ms          |    1.03 | load.ugrid.BasicLoadingTime.time_load_file(1)                                               |
|          | 21.4±1ms             | 21.3±0.7ms          |    0.99 | load.ugrid.BasicLoadingTime.time_load_file(200000)                                          |
|          | 10.2±0.5ms           | 10.5±0.5ms          |    1.03 | load.ugrid.BasicLoadingTime.time_load_mesh(1)                                               |
|          | 12.8±0.4ms           | 14.4±0.3ms          |    1.12 | load.ugrid.BasicLoadingTime.time_load_mesh(200000)                                          |
|          | 22.2±1ms             | 23.0±0.5ms          |    1.04 | load.ugrid.Callback.time_load_file_callback(1)                                              |
|          | 63.9±2ms             | 67.4±3ms            |    1.05 | load.ugrid.Callback.time_load_file_callback(200000)                                         |
|          | 23.1±1ms             | 22.8±0.8ms          |    0.98 | load.ugrid.CallbackTime.time_load_file_callback(1)                                          |
|          | 23.6±0.4ms           | 24.3±1ms            |    1.03 | load.ugrid.CallbackTime.time_load_file_callback(200000)                                     |
|          | 3.89±0.2ms           | 4.01±0.3ms          |    1.03 | load.ugrid.DataRealisation.time_realise_data(10000)                                         |
|          | 4.83±0.3ms           | 5.29±0.2ms          |    1.1  | load.ugrid.DataRealisation.time_realise_data(200000)                                        |
|          | 50.2±4ms             | 54.2±6ms            |    1.08 | load.ugrid.DataRealisationTime.time_realise_data(10000)                                     |
|          | 1.07±0.06s           | 1.15±0.05s          |    1.08 | load.ugrid.DataRealisationTime.time_realise_data(200000)                                    |
|          | 1.11±0.03s           | 1.15±0.04s          |    1.04 | merge_concat.Concatenate.time_concatenate(False)                                            |
|          | 449±5ms              | 457±5ms             |    1.02 | merge_concat.Concatenate.time_concatenate(True)                                             |
|          | 2.21±0G              | 2.21±0G             |    1    | merge_concat.Concatenate.tracemalloc_concatenate(False)                                     |
|          | 71.7±4M              | 71.7±4M             |    1    | merge_concat.Concatenate.tracemalloc_concatenate(True)                                      |
|          | 35.1±2ms             | 40.1±4ms            |    1.14 | merge_concat.Merge.time_merge                                                               |
|          | 126±0.03M            | 126±0.03M           |    1    | merge_concat.Merge.tracemalloc_merge                                                        |
|          | 158±2ms              | 148±2ms             |    0.94 | mesh.utils.regions_combine.CombineRegionsComputeRealData.time_compute_data(500)             |
|          | 769±3k               | 769±3k              |    1    | mesh.utils.regions_combine.CombineRegionsComputeRealData.tracemalloc_compute_data(50)       |
|          | 60.2±0M              | 60.2±0M             |    1    | mesh.utils.regions_combine.CombineRegionsComputeRealData.tracemalloc_compute_data(500)      |
|          | 19.0±0.7ms           | 19.7±0.4ms          |    1.03 | mesh.utils.regions_combine.CombineRegionsCreateCube.time_create_combined_cube(50)           |
|          | 22.3±0.2ms           | 22.9±0.3ms          |    1.03 | mesh.utils.regions_combine.CombineRegionsCreateCube.time_create_combined_cube(500)          |
|          | 821±2k               | 821±2k              |    1    | mesh.utils.regions_combine.CombineRegionsCreateCube.tracemalloc_create_combined_cube(50)    |
|          | 24.6±0M              | 24.6±0M             |    1    | mesh.utils.regions_combine.CombineRegionsCreateCube.tracemalloc_create_combined_cube(500)   |
|          | 111±1ms              | 123±5ms             |    1.11 | mesh.utils.regions_combine.CombineRegionsFileStreamedCalc.time_stream_file2file(50)         |
|          | 428±5ms              | 430±20ms            |    1    | mesh.utils.regions_combine.CombineRegionsFileStreamedCalc.time_stream_file2file(500)        |
|          | 1.48±0.07M           | 1.46±0.05M          |    0.99 | mesh.utils.regions_combine.CombineRegionsFileStreamedCalc.tracemalloc_stream_file2file(50)  |
|          | 96.5±0.06M           | 96.5±0.07M          |    1    | mesh.utils.regions_combine.CombineRegionsFileStreamedCalc.tracemalloc_stream_file2file(500) |
|          | 75.1±1ms             | 80.7±6ms            |    1.07 | mesh.utils.regions_combine.CombineRegionsSaveData.time_save(50)                             |
|          | 381±5ms              | 383±20ms            |    1.01 | mesh.utils.regions_combine.CombineRegionsSaveData.time_save(500)                            |
|          | 1.34±0.05M           | 1.38±0.01M          |    1.02 | mesh.utils.regions_combine.CombineRegionsSaveData.tracemalloc_save(50)                      |
|          | 96.4±0.04M           | 96.4±0.05M          |    1    | mesh.utils.regions_combine.CombineRegionsSaveData.tracemalloc_save(500)                     |
|          | 2.175361             | 2.175361            |    1    | mesh.utils.regions_combine.CombineRegionsSaveData.track_filesize_saved(50)                  |
|          | 216.01536099999998   | 216.01536099999998  |    1    | mesh.utils.regions_combine.CombineRegionsSaveData.track_filesize_saved(500)                 |
|          | 6.60±0.1ms           | 6.65±0.2ms          |    1.01 | plot.AuxSort.time_aux_sort                                                                  |
|          | 57.4±5ms             | 58.9±3ms            |    1.03 | regridding.CurvilinearRegridding.time_regrid_pic                                            |
|          | 136±3M               | 136±3M              |    1    | regridding.CurvilinearRegridding.tracemalloc_regrid_pic                                     |
|          | 106±6ms              | 106±6ms             |    1    | regridding.HorizontalChunkedRegridding.time_regrid_area_w                                   |
|          | 55.5±2ms             | 62.8±4ms            |    1.13 | regridding.HorizontalChunkedRegridding.time_regrid_area_w_new_grid                          |
|          | 107±0.09M            | 107±0.09M           |    1    | regridding.HorizontalChunkedRegridding.tracemalloc_regrid_area_w                            |
|          | 147±0.03M            | 147±0.03M           |    1    | regridding.HorizontalChunkedRegridding.tracemalloc_regrid_area_w_new_grid                   |
|          | 4.73±0.06ms          | 5.02±0.3ms          |    1.06 | save.NetcdfSave.time_netcdf_save_cube(50, False)                                            |
|          | 82.0±3ms             | 87.3±2ms            |    1.06 | save.NetcdfSave.time_netcdf_save_cube(50, True)                                             |
|          | 26.3±20ms            | 23.1±1ms            |    0.88 | save.NetcdfSave.time_netcdf_save_cube(600, False)                                           |
|          | 295±8ms              | 326±20ms            |    1.1  | save.NetcdfSave.time_netcdf_save_cube(600, True)                                            |
|          | 63.2±0.7ms           | 65.9±3ms            |    1.04 | save.NetcdfSave.time_netcdf_save_mesh(50, True)                                             |
|          | 260±7ms              | 270±10ms            |    1.04 | save.NetcdfSave.time_netcdf_save_mesh(600, True)                                            |
|          | 31.4±1k              | 31.5±1k             |    1    | save.NetcdfSave.tracemalloc_netcdf_save(50, False)                                          |
|          | 1.8±0.2M             | 1.78±0.2M           |    0.99 | save.NetcdfSave.tracemalloc_netcdf_save(50, True)                                           |
|          | 31.6±1k              | 31.4±1k             |    0.99 | save.NetcdfSave.tracemalloc_netcdf_save(600, False)                                         |
|          | 208±20M              | 225±20M             |    1.08 | save.NetcdfSave.tracemalloc_netcdf_save(600, True)                                          |
|          | 41.0±0.7ms           | 42.3±0.7ms          |    1.03 | stats.PearsonR.time_lazy                                                                    |
|          | 9.52±0.3ms           | 10.5±0.3ms          |    1.11 | stats.PearsonR.time_real                                                                    |
|          | 29.4±0.5M            | 29.1±0.6M           |    0.99 | stats.PearsonR.tracemalloc_lazy                                                             |
|          | 18.3±0M              | 18.3±0M             |    1    | stats.PearsonR.tracemalloc_real                                                             |
|          | 23.6±0.8ms           | 25.3±0.7ms          |    1.07 | trajectory.TrajectoryInterpolation.time_trajectory_linear                                   |
|          | 80.7±0.6ms           | 82.6±0.6ms          |    1.02 | trajectory.TrajectoryInterpolation.time_trajectory_nearest                                  |
|          | 17.6±0.01M           | 17.6±0.01M          |    1    | trajectory.TrajectoryInterpolation.tracemalloc_trajectory_linear                            |
|          | 7.74±0.01M           | 7.74±0.01M          |    1    | trajectory.TrajectoryInterpolation.tracemalloc_trajectory_nearest                           |

Benchmarks that have got worse:

| Change   | Before [d9ebbaf5]    | After [31016d78]    |    Ratio | Benchmark (Parameter)                                                          |
|----------|----------------------|---------------------|----------|--------------------------------------------------------------------------------|
| +        | 388±2μs              | 470±10μs            |     1.21 | cube.CubeCreation.time_create(False, 'instantiate')                            |
| +        | 16.8±0.2μs           | 63.9±4μs            |     3.8  | cube.CubeEquality.time_equality(False, False, 'metadata_inequality')           |
| +        | 16.9±0.2μs           | 67.1±2μs            |     3.97 | cube.CubeEquality.time_equality(False, True, 'metadata_inequality')            |
| +        | 53.7±0.2μs           | 90.4±2μs            |     1.68 | cube.CubeEquality.time_equality(True, False, 'metadata_inequality')            |
| +        | 362±2ns              | 5.74±0.1ms          | 15840.9  | mesh.utils.regions_combine.CombineRegionsComputeRealData.time_compute_data(50) |
| +        | 92.8±6ns             | 1.15±0.3μs          |    12.41 | save.NetcdfSave.time_netcdf_save_mesh(50, False)                               |
| +        | 91.6±0.5ns           | 2.43±0.2μs          |    26.56 | save.NetcdfSave.time_netcdf_save_mesh(600, False)                              |

Generated by GHA run 34140207752

bjlittle added a commit to bjlittle/iris that referenced this pull request Sep 10, 2026
The branch was cut from main at c508ac8; greenfield carries SciTools#7270 on top
of that, which re-solved all three lock files. The lock additions here are
re-derived against those fresh locks, and remain minimal - the myst-parser
dependency closure and the input_hash, nothing else.

The cube.py line references the spec cites are unaffected: SciTools#7270's changes
are confined to rolling_window, some 4500 lines below the merge and
concatenate methods.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
bjlittle added a commit that referenced this pull request Sep 10, 2026
… and configurable (#7274)

* Add design spec for merge/concatenate improvement programme

Specifies a twelve-PR programme to make cube merge and concatenate more
robust, efficient, configurable, extensible, lazy and lenient, without a
rewrite. Each PR is either a behaviour-preserving refactor or a standalone
user-visible improvement; together they grow a shared substrate beneath
both engines.

Includes a confirmed diagnosis and fix for the separability bug open since
2017 (#2761), verified end-to-end against the reporter's case.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Record design-spec location in AGENTS.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs: publish design specs as MyST Markdown

Adopt the spec/plan convention used in bjlittle/tephpy.

Agreed design specs now live in `docs/src/developers_guide/specs/` and are
published as part of the documentation.  They are written in MyST Markdown,
are living documents revised as a design evolves, and each declares a
citation prefix so its sections can be cited from issues and pull requests.

Implementation plans live in the sibling `docs/src/developers_guide/plans/`.
A plan is point-in-time and frozen once its pull request merges, so plans are
tracked in the repository but excluded from the Sphinx build.

This requires `myst-parser`, added to `requirements/py*.yml` and inserted into
the three lock files following the precedent of #7095 and #7100.  Markdown is
used only for specs; all other documentation remains reStructuredText.

The merge/concatenate design spec moves here from `docs/superpowers/specs/`
and is reworked to the new conventions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs: add a plan roadmap and decision register to the merge spec

The spec described a twelve-PR programme but had nowhere to record how far
it had got, which assumptions it rested on, or what it had left open.

Restructure §6 from a static table of work into the programme's live
progress record: dependencies as a partial order rather than a chain, a
status vocabulary, an "Outside the roadmap" list, and a numbered register
of assumptions and open decisions - each item owned by the pull request
that must resolve it. Add §10 for the questions the programme raises but
does not answer, renumbering References to §11.

Also exclude "_build" and "_static" from the Sphinx build. myst-parser
makes ".md" a source suffix, so the README of each was being read as a
document.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs: record how agentic contributions are pushed and labelled

This work is long-running partly because it is also an exercise in earning
core-developer buy-in for agentic contributions, so the mechanics of how it
reaches them are worth writing down rather than re-deciding each session.

Add a "Contribution Workflow" section to AGENTS.md carrying the general
rule: branches to the fork, pull requests to a feature branch rather than
main, honest "Agentic" labelling, clear attribution, and ask before doing
anything outward-facing when unsure. Drop the "Getting Help" link list to
stay inside the file's 200-line budget - the links it held are all reachable
from CONTRIBUTING.md.

The programme-specific parts - base branch "greenfield" and the
"Feature: Merge/Concatenate" label - go in the spec's cross-cutting rules
instead, where a reviewer can see why these pull requests do not target main.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs: add changelog fragments for the design spec

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* docs: rebase the spec baseline onto greenfield

The branch was cut from main at c508ac8; greenfield carries #7270 on top
of that, which re-solved all three lock files. The lock additions here are
re-derived against those fresh locks, and remain minimal - the myst-parser
dependency closure and the input_hash, nothing else.

The cube.py line references the spec cites are unaffected: #7270's changes
are confined to rolling_window, some 4500 lines below the merge and
concatenate methods.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Spell out spec section citation runs

Give every cited section its own section sign, and separate a run of them
with a comma or a solidus rather than a dash.  A dashed range such as
"5.6-5.7" reads as a single citation carrying a stray suffix, so only its
first section is unambiguously identified -- by a reader now, and by any
cross-reference tooling later.

Records the rule on the Design Specs index page, next to the citation
prefix table it belongs with, and applies it to the one occurrence in the
merge/concatenate spec.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
stephenworsley added a commit that referenced this pull request Sep 18, 2026
* undo the whatsnew changes

* fix for doctest warnings

* Add unit tests for Cube.coord_dims (#7198)

* Add unit tests for Cube.coord_dims

* Add What's New changelog fragment for #4552

* Refactor Test_coord_dims._setup for readability

Address review feedback from @ESadek-MO:
- Move hybrid-height set-up into the single test that uses it
- Group _setup into clear blocks: cube → DimCoords → AuxCoords → assigns

* Move hybrid-height set-up into a dedicated fixture

Address review feedback from @ESadek-MO on #7198: move the hybrid-height
construction (delta/sigma/orography, HybridHeightFactory, add_aux_factory)
out of the test body and into its own pytest fixture, so that set-up
failures can be isolated by PyTest.

---------

Co-authored-by: 01luyicheng <01luyicheng@users.noreply.github.com>

* Bump the gha group across 1 directory with 9 updates (#7215)

Bumps the gha group with 9 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `7.0.0` | `7.0.1` |
| [actions/setup-python](https://github.com/actions/setup-python) | `6.3.0` | `7.0.0` |
| [lycheeverse/lychee-action](https://github.com/lycheeverse/lychee-action) | `2.8.0` | `2.9.0` |
| [scitools/workflows/.github/workflows/ci-manifest.yml](https://github.com/scitools/workflows) | `2026.06.0` | `2026.07.1` |
| [scitools/workflows/.github/workflows/ci-template-check.yml](https://github.com/scitools/workflows) | `2026.06.0` | `2026.07.1` |
| [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) | `1.14.0` | `1.14.2` |
| [actions/labeler](https://github.com/actions/labeler) | `6.1.0` | `7.0.0` |
| [scitools/workflows/.github/workflows/refresh-lockfiles.yml](https://github.com/scitools/workflows) | `2026.06.0` | `2026.07.1` |
| [actions/stale](https://github.com/actions/stale) | `10.3.0` | `11.0.0` |



Updates `actions/checkout` from 7.0.0 to 7.0.1
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@9c091bb...3d3c42e)

Updates `actions/setup-python` from 6.3.0 to 7.0.0
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@ece7cb0...5fda3b9)

Updates `lycheeverse/lychee-action` from 2.8.0 to 2.9.0
- [Release notes](https://github.com/lycheeverse/lychee-action/releases)
- [Commits](lycheeverse/lychee-action@8646ba3...e747777)

Updates `scitools/workflows/.github/workflows/ci-manifest.yml` from 2026.06.0 to 2026.07.1
- [Release notes](https://github.com/scitools/workflows/releases)
- [Commits](SciTools/workflows@1f21414...7c41342)

Updates `scitools/workflows/.github/workflows/ci-template-check.yml` from 2026.06.0 to 2026.07.1
- [Release notes](https://github.com/scitools/workflows/releases)
- [Commits](SciTools/workflows@1f21414...7c41342)

Updates `pypa/gh-action-pypi-publish` from 1.14.0 to 1.14.2
- [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases)
- [Commits](pypa/gh-action-pypi-publish@cef2210...dc37677)

Updates `actions/labeler` from 6.1.0 to 7.0.0
- [Release notes](https://github.com/actions/labeler/releases)
- [Commits](actions/labeler@f27b608...bf12e9b)

Updates `scitools/workflows/.github/workflows/refresh-lockfiles.yml` from 2026.06.0 to 2026.07.1
- [Release notes](https://github.com/scitools/workflows/releases)
- [Commits](SciTools/workflows@1f21414...7c41342)

Updates `actions/stale` from 10.3.0 to 11.0.0
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](actions/stale@eb5cf3a...4391f3d)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gha
- dependency-name: actions/labeler
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: gha
- dependency-name: actions/setup-python
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: gha
- dependency-name: actions/stale
  dependency-version: 10.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: gha
- dependency-name: lycheeverse/lychee-action
  dependency-version: 2.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: gha
- dependency-name: pypa/gh-action-pypi-publish
  dependency-version: 1.14.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: gha
- dependency-name: scitools/workflows/.github/workflows/ci-manifest.yml
  dependency-version: 2026.07.1
  dependency-type: direct:production
  dependency-group: gha
- dependency-name: scitools/workflows/.github/workflows/ci-template-check.yml
  dependency-version: 2026.07.1
  dependency-type: direct:production
  dependency-group: gha
- dependency-name: scitools/workflows/.github/workflows/refresh-lockfiles.yml
  dependency-version: 2026.07.1
  dependency-type: direct:production
  dependency-group: gha
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Bump the gha group across 1 directory with 3 updates (#7256)

Bumps the gha group with 3 updates in the / directory: [scitools/workflows/.github/workflows/ci-manifest.yml](https://github.com/scitools/workflows), [scitools/workflows/.github/workflows/ci-template-check.yml](https://github.com/scitools/workflows) and [scitools/workflows/.github/workflows/refresh-lockfiles.yml](https://github.com/scitools/workflows).


Updates `scitools/workflows/.github/workflows/ci-manifest.yml` from 2026.07.1 to 2026.08.1
- [Release notes](https://github.com/scitools/workflows/releases)
- [Commits](SciTools/workflows@7c41342...28aea7a)

Updates `scitools/workflows/.github/workflows/ci-template-check.yml` from 2026.07.1 to 2026.08.1
- [Release notes](https://github.com/scitools/workflows/releases)
- [Commits](SciTools/workflows@7c41342...28aea7a)

Updates `scitools/workflows/.github/workflows/refresh-lockfiles.yml` from 2026.07.1 to 2026.08.1
- [Release notes](https://github.com/scitools/workflows/releases)
- [Commits](SciTools/workflows@7c41342...28aea7a)

---
updated-dependencies:
- dependency-name: scitools/workflows/.github/workflows/ci-manifest.yml
  dependency-version: 2026.08.1
  dependency-type: direct:production
  dependency-group: gha
- dependency-name: scitools/workflows/.github/workflows/ci-template-check.yml
  dependency-version: 2026.08.1
  dependency-type: direct:production
  dependency-group: gha
- dependency-name: scitools/workflows/.github/workflows/refresh-lockfiles.yml
  dependency-version: 2026.08.1
  dependency-type: direct:production
  dependency-group: gha
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* Fix TEST_DATA_DIR default behaviour (#7257)

* fix TEST_DATA_DIR default behaviour

* add whatsnew

* Add option for steps in Cube rolling windows (#7236)

* Add option for steps in Cube rolling windows

* Add changelog entry

* Fix bug with mesh indexing for start_index=1 (#7253)

* fix bug with mesh indexing for start_index=1

* add test

* add whatsnew

* add unit tests

* CI compatibility with PROJ 9.8 (#7254)

* CI compatibility with PROJ 9.8.

* review comments (#97)

---------

Co-authored-by: Elias <110238618+ESadek-MO@users.noreply.github.com>

* Update lock files plus test fixes (#7270)

* Updated environment lockfiles

* Temporary gallery test fix.

* Revert "Temporary gallery test fix."

This reverts commit 6403701.

* Skip Proj 9.8 incompatible gallery tests. Proven by 6403701.

* Modernise graphics tests.

* What's New entry.

---------

Co-authored-by: Lockfile bot <noreply@github.com>
Co-authored-by: Elias <110238618+ESadek-MO@users.noreply.github.com>

* DOC BLD: get scipy objects inventory from their static site (#7269)

* Move developers' conda yml to environment.yml (#7267)

* Move developers' conda yml to environment.yml

* Fix readthedocs.yml

* Add environment.yml to manifest

* Add code trial for encode/decode of lazy data.

* Some extra debug.

* Apply encode/decode to load/save shortcutting, and support lazy data.

* Small changes to support scalar character variables.

* Replace complex VariableEncoder constructor with a .from_var classmethod.

* Apply scalar adjustment whether lazy or real.

* Remove debug print.

* Extend get_cf_var to test dataset-shortcutting of strings and real/lazy data.

* Fix typo in tests.

* Remove temporary tests.

* With CoPilot: tests for handling of ncdata-style direct data transfers in '_lazy_stream_data'.

* Added changelog fragment.

* Review changes.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Henry Wright <henrywright@sky.com>
Co-authored-by: Martin Yeo <40734014+trexfeathers@users.noreply.github.com>
Co-authored-by: 陆奕丞 <01luyicheng@gmail.com>
Co-authored-by: 01luyicheng <01luyicheng@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: stephenworsley <49274989+stephenworsley@users.noreply.github.com>
Co-authored-by: Andrew Creswick <89418171+mo-AndrewCreswick@users.noreply.github.com>
Co-authored-by: Elias <110238618+ESadek-MO@users.noreply.github.com>
Co-authored-by: Lockfile bot <noreply@github.com>
Co-authored-by: Ruth Comer <10599679+rcomer@users.noreply.github.com>
pp-mo pushed a commit to pp-mo/iris that referenced this pull request Sep 22, 2026
* Updated environment lockfiles

* Temporary gallery test fix.

* Revert "Temporary gallery test fix."

This reverts commit 6403701.

* Skip Proj 9.8 incompatible gallery tests. Proven by SciTools/iris@6403701.

* Modernise graphics tests.

* What's New entry.

---------

Co-authored-by: Lockfile bot <noreply@github.com>
Co-authored-by: Elias <110238618+ESadek-MO@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

benchmark_this Request that this pull request be benchmarked to check if it introduces performance shifts

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants