Skip to content

Commit cdefcef

Browse files
committed
Merge branch 'main' of github.com:NCAS-CMS/cf-python into field-combination
2 parents f2da52f + 2d183c8 commit cdefcef

File tree

10 files changed

+78
-14
lines changed

10 files changed

+78
-14
lines changed

Changelog.rst

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
version NEXTVERSION
2+
-------------------
3+
4+
**2024-??-??**
5+
6+
* Include the UM version as a field property when reading UM files
7+
(https://github.com/NCAS-CMS/cf-python/issues/777)
8+
* Fix bug where `cf.example_fields` returned a `list`
9+
of Fields rather than a `Fieldlist`
10+
(https://github.com/NCAS-CMS/cf-python/issues/725)
11+
* Fix bug where `cf.normalize_slice` doesn't correctly
12+
handle certain cyclic slices
13+
(https://github.com/NCAS-CMS/cf-python/issues/774)
14+
15+
----
16+
117
version 3.16.2
218
--------------
319

cf/examplefield.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import cfdm
22

33
from .cfimplementation import implementation
4+
from .fieldlist import FieldList
45

56
_implementation = implementation()
67

@@ -13,7 +14,7 @@ def example_field(n, _implementation=_implementation):
1314

1415

1516
def example_fields(*n, _func=example_field):
16-
return cfdm.example_fields(*n, _func=_func)
17+
return FieldList(cfdm.example_fields(*n, _func=_func))
1718

1819

1920
example_fields.__doc__ = cfdm.example_fields.__doc__.replace("cfdm.", "cf.")

cf/field.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10513,9 +10513,9 @@ def convolution_filter(
1051310513
new_bounds[0 : length - lower_offset, 1:] = old_bounds[
1051410514
lower_offset:length, 1:
1051510515
]
10516-
new_bounds[length - lower_offset : length, 1:] = (
10517-
old_bounds[length - 1, 1:]
10518-
)
10516+
new_bounds[
10517+
length - lower_offset : length, 1:
10518+
] = old_bounds[length - 1, 1:]
1051910519

1052010520
coord.set_bounds(self._Bounds(data=new_bounds))
1052110521

cf/functions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2132,8 +2132,8 @@ def normalize_slice(index, size, cyclic=False):
21322132
return slice(start, stop, step)
21332133

21342134
if not (
2135-
(step > 0 and start < 0 and stop > 0)
2136-
or (step < 0 and start > 0 and stop < 0)
2135+
(step > 0 and start < 0 and stop >= 0)
2136+
or (step < 0 and start >= 0 and stop < 0)
21372137
):
21382138
raise IndexError(
21392139
f"{index!r} is not a {'cyclic ' if cyclic else ''}slice"

cf/read_write/um/umread.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1040,6 +1040,22 @@ def __init__(
10401040
cf_properties["stash_code"] = str(stash)
10411041
cf_properties["submodel"] = str(submodel)
10421042

1043+
# Convert the UM version to a string and provide it as a
1044+
# CF property. E.g. 405 -> '4.5', 606.3 -> '6.6.3', 1002
1045+
# -> '10.2'
1046+
#
1047+
# Note: We don't just do `divmod(self.um_version, 100)`
1048+
# because if self.um_version has a fractional part
1049+
# then it would likely get altered in the divmod
1050+
# calculation.
1051+
a, b = divmod(int(self.um_version), 100)
1052+
fraction = str(self.um_version).split(".")[-1]
1053+
um = f"{a}.{b}"
1054+
if fraction != "0" and fraction != str(self.um_version):
1055+
um += f".{fraction}"
1056+
1057+
cf_properties["um_version"] = um
1058+
10431059
# --------------------------------------------------------
10441060
# Set the data and extra data
10451061
# --------------------------------------------------------

cf/test/test_Data.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2389,7 +2389,9 @@ def test_Data_BINARY_AND_UNARY_OPERATORS(self):
23892389
except Exception:
23902390
pass
23912391
else:
2392-
self.assertTrue((x**d).all(), "{}**{}".format(x, repr(d)))
2392+
self.assertTrue(
2393+
(x**d).all(), "{}**{}".format(x, repr(d))
2394+
)
23932395

23942396
self.assertTrue(
23952397
d.__truediv__(x).equals(

cf/test/test_functions.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,12 @@ class functionTest(unittest.TestCase):
1717
def setUp(self):
1818
self.test_only = ()
1919

20-
def test_example_field(self):
21-
for f in cf.example_fields():
20+
def test_example_field_example_fields(self):
21+
e = cf.example_fields()
22+
self.assertIsInstance(e, cf.FieldList)
23+
24+
for f in e:
25+
self.assertIsInstance(f, cf.Field)
2226
f.dump(display=False)
2327

2428
with self.assertRaises(ValueError):
@@ -385,7 +389,24 @@ def test_normalize_slice(self):
385389
cf.normalize_slice(slice(2, 5, -2), 8, cyclic=True),
386390
slice(2, -3, -2),
387391
)
388-
392+
393+
self.assertEqual(
394+
cf.normalize_slice(slice(-8, 0, 1), 8, cyclic=True),
395+
slice(-8, 0, 1)
396+
)
397+
self.assertEqual(
398+
cf.normalize_slice(slice(0, 7, -1), 8, cyclic=True),
399+
slice(0, -1, -1)
400+
)
401+
self.assertEqual(
402+
cf.normalize_slice(slice(-1, -8, 1), 8, cyclic=True),
403+
slice(-1, 0, 1)
404+
)
405+
self.assertEqual(
406+
cf.normalize_slice(slice(-8, -1, -1), 8, cyclic=True),
407+
slice(0, -1, -1)
408+
)
409+
389410
with self.assertRaises(IndexError):
390411
cf.normalize_slice([1, 2], 8)
391412

cf/test/test_pp.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def test_PP_read_um(self):
5757
g = cf.read(self.ppextradata, um={"fmt": "pp"})[0]
5858
self.assertTrue(f.equals(g))
5959

60-
for vn in (4.5, 405, "4.5", None):
60+
for vn in (4.5, 405, "4.5"):
6161
g = cf.read(self.ppextradata, um={"fmt": "pp", "version": vn})[0]
6262
self.assertTrue(f.equals(g))
6363

@@ -138,6 +138,13 @@ def test_PP_extra_data(self):
138138
self.assertTrue(f.dimension_coordinate("time", default=False))
139139
self.assertTrue(f.auxiliary_coordinate("longitude", default=False))
140140

141+
def test_PP_um_version(self):
142+
f = cf.read(self.ppfile)[0]
143+
self.assertEqual(f.get_property("um_version"), "11.0")
144+
145+
f = cf.read(self.ppfile, um={"version": "6.6.3"})[0]
146+
self.assertEqual(f.get_property("um_version"), "6.6.3")
147+
141148

142149
if __name__ == "__main__":
143150
print("Run date:", datetime.datetime.now())

cf/weights.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,9 +1461,9 @@ def linear(
14611461
else:
14621462
# Bounds exist
14631463
if methods:
1464-
weights[(da_key,)] = (
1465-
f"linear {f.constructs.domain_axis_identity(da_key)}"
1466-
)
1464+
weights[
1465+
(da_key,)
1466+
] = f"linear {f.constructs.domain_axis_identity(da_key)}"
14671467
else:
14681468
weights[(da_key,)] = dim.cellsize
14691469

docs/source/contributing.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,4 @@ ideas, code, and documentation to the cf library:
126126
* Sadie Bartholomew
127127
* Thibault Hallouin
128128
* Tim Bradshaw
129+
* Matt Brown

0 commit comments

Comments
 (0)