Skip to content

Commit

Permalink
Supporting Python 3.12 (#1813)
Browse files Browse the repository at this point in the history
  • Loading branch information
john-science authored Aug 15, 2024
1 parent 290715b commit 9ad6e6c
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 55 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unittests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-24.04
strategy:
matrix:
python: [3.9, '3.10', '3.11']
python: [3.9, '3.10', '3.11', '3.12']

steps:
- uses: actions/checkout@v2
Expand Down
2 changes: 1 addition & 1 deletion armi/bookkeeping/db/database3.py
Original file line number Diff line number Diff line change
Expand Up @@ -1462,7 +1462,7 @@ def _writeAttrs(obj, group, attrs):
)

if "attrs" not in group:
attrGroup = group.create_group("attrs", track_order=True)
attrGroup = group.create_group("attrs")
else:
attrGroup = group["attrs"]
dataName = str(len(attrGroup)) + "_" + key
Expand Down
45 changes: 33 additions & 12 deletions armi/bookkeeping/db/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,23 +418,34 @@ def writeToDB(self, h5group):
"layout/indexInData", data=self.indexInData, compression="gzip"
)
h5group.create_dataset(
"layout/numChildren", data=self.numChildren, compression="gzip"
"layout/numChildren",
data=self.numChildren,
compression="gzip",
track_order=True,
)
h5group.create_dataset(
"layout/location", data=self.location, compression="gzip"
"layout/location",
data=self.location,
compression="gzip",
track_order=True,
)
h5group.create_dataset(
"layout/locationType",
data=numpy.array(self.locationType).astype("S"),
compression="gzip",
track_order=True,
)
h5group.create_dataset(
"layout/material",
data=numpy.array(self.material).astype("S"),
compression="gzip",
track_order=True,
)
h5group.create_dataset(
"layout/temperatures", data=self.temperatures, compression="gzip"
"layout/temperatures",
data=self.temperatures,
compression="gzip",
track_order=True,
)

h5group.create_dataset(
Expand All @@ -445,31 +456,41 @@ def writeToDB(self, h5group):
compression="gzip",
)

gridsGroup = h5group.create_group("layout/grids")
gridsGroup = h5group.create_group("layout/grids", track_order=True)
gridsGroup.attrs["nGrids"] = len(self.gridParams)
gridsGroup.create_dataset(
"type", data=numpy.array([gp[0] for gp in self.gridParams]).astype("S")
"type",
data=numpy.array([gp[0] for gp in self.gridParams]).astype("S"),
track_order=True,
)

for igrid, gridParams in enumerate(gp[1] for gp in self.gridParams):
thisGroup = gridsGroup.create_group(str(igrid))
thisGroup.create_dataset("unitSteps", data=gridParams.unitSteps)
thisGroup = gridsGroup.create_group(str(igrid), track_order=True)
thisGroup.create_dataset(
"unitSteps", data=gridParams.unitSteps, track_order=True
)

for ibound, bound in enumerate(gridParams.bounds):
if bound is not None:
bound = numpy.array(bound)
thisGroup.create_dataset("bounds_{}".format(ibound), data=bound)
thisGroup.create_dataset(
"bounds_{}".format(ibound), data=bound, track_order=True
)

thisGroup.create_dataset(
"unitStepLimits", data=gridParams.unitStepLimits
"unitStepLimits", data=gridParams.unitStepLimits, track_order=True
)

offset = gridParams.offset
thisGroup.attrs["offset"] = offset is not None
if offset is not None:
thisGroup.create_dataset("offset", data=offset)
thisGroup.create_dataset("geomType", data=gridParams.geomType)
thisGroup.create_dataset("symmetry", data=gridParams.symmetry)
thisGroup.create_dataset("offset", data=offset, track_order=True)
thisGroup.create_dataset(
"geomType", data=gridParams.geomType, track_order=True
)
thisGroup.create_dataset(
"symmetry", data=gridParams.symmetry, track_order=True
)
except RuntimeError:
runLog.error("Failed to create datasets in: {}".format(h5group))
raise
Expand Down
11 changes: 6 additions & 5 deletions armi/bookkeeping/db/tests/test_database3.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,12 +350,13 @@ def test_mergeHistory(self):
self.r.p.cycle = 1
self.r.p.timeNode = 0
tnGroup = self.db.getH5Group(self.r)
randomText = "this isn't a reference to another dataset"
database3.Database3._writeAttrs(
tnGroup["layout/serialNum"],
tnGroup,
{
"fakeBigData": numpy.eye(6400),
"someString": "this isn't a reference to another dataset",
"fakeBigData": numpy.eye(64),
"someString": randomText,
},
)

Expand All @@ -369,15 +370,15 @@ def test_mergeHistory(self):

# this test is a little bit implementation-specific, but nice to be explicit
self.assertEqual(
tnGroup["layout/serialNum"].attrs["fakeBigData"],
"@/c01n00/attrs/0_fakeBigData",
tnGroup["layout/serialNum"].attrs["someString"],
randomText,
)

# exercise the _resolveAttrs function
attrs = database3.Database3._resolveAttrs(
tnGroup["layout/serialNum"].attrs, tnGroup
)
self.assertTrue(numpy.array_equal(attrs["fakeBigData"], numpy.eye(6400)))
self.assertTrue(numpy.array_equal(attrs["fakeBigData"], numpy.eye(64)))

keys = sorted(db2.keys())
self.assertEqual(len(keys), 4)
Expand Down
48 changes: 24 additions & 24 deletions armi/cases/tests/test_suiteBuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,25 +116,25 @@ def test_buildSuite(self):
SettingModifier("settingName2", value) for value in (3, 4, 5)
)

self.assertEquals(builder.modifierSets[0][0].value, 1)
self.assertEquals(builder.modifierSets[0][1].value, 3)
self.assertEqual(builder.modifierSets[0][0].value, 1)
self.assertEqual(builder.modifierSets[0][1].value, 3)

self.assertEquals(builder.modifierSets[1][0].value, 2)
self.assertEquals(builder.modifierSets[1][1].value, 3)
self.assertEqual(builder.modifierSets[1][0].value, 2)
self.assertEqual(builder.modifierSets[1][1].value, 3)

self.assertEquals(builder.modifierSets[2][0].value, 1)
self.assertEquals(builder.modifierSets[2][1].value, 4)
self.assertEqual(builder.modifierSets[2][0].value, 1)
self.assertEqual(builder.modifierSets[2][1].value, 4)

self.assertEquals(builder.modifierSets[3][0].value, 2)
self.assertEquals(builder.modifierSets[3][1].value, 4)
self.assertEqual(builder.modifierSets[3][0].value, 2)
self.assertEqual(builder.modifierSets[3][1].value, 4)

self.assertEquals(builder.modifierSets[4][0].value, 1)
self.assertEquals(builder.modifierSets[4][1].value, 5)
self.assertEqual(builder.modifierSets[4][0].value, 1)
self.assertEqual(builder.modifierSets[4][1].value, 5)

self.assertEquals(builder.modifierSets[5][0].value, 2)
self.assertEquals(builder.modifierSets[5][1].value, 5)
self.assertEqual(builder.modifierSets[5][0].value, 2)
self.assertEqual(builder.modifierSets[5][1].value, 5)

self.assertEquals(len(builder.modifierSets), 6)
self.assertEqual(len(builder.modifierSets), 6)


class TestSeparateEffectsBuilder(unittest.TestCase):
Expand All @@ -155,19 +155,19 @@ def test_buildSuite(self):
SettingModifier("settingName2", value) for value in (3, 4, 5)
)

self.assertEquals(builder.modifierSets[0][0].value, 1)
self.assertEquals(builder.modifierSets[0][0].settingName, "settingName1")
self.assertEqual(builder.modifierSets[0][0].value, 1)
self.assertEqual(builder.modifierSets[0][0].settingName, "settingName1")

self.assertEquals(builder.modifierSets[1][0].value, 2)
self.assertEquals(builder.modifierSets[1][0].settingName, "settingName1")
self.assertEqual(builder.modifierSets[1][0].value, 2)
self.assertEqual(builder.modifierSets[1][0].settingName, "settingName1")

self.assertEquals(builder.modifierSets[2][0].value, 3)
self.assertEquals(builder.modifierSets[2][0].settingName, "settingName2")
self.assertEqual(builder.modifierSets[2][0].value, 3)
self.assertEqual(builder.modifierSets[2][0].settingName, "settingName2")

self.assertEquals(builder.modifierSets[3][0].value, 4)
self.assertEquals(builder.modifierSets[3][0].settingName, "settingName2")
self.assertEqual(builder.modifierSets[3][0].value, 4)
self.assertEqual(builder.modifierSets[3][0].settingName, "settingName2")

self.assertEquals(builder.modifierSets[4][0].value, 5)
self.assertEquals(builder.modifierSets[4][0].settingName, "settingName2")
self.assertEqual(builder.modifierSets[4][0].value, 5)
self.assertEqual(builder.modifierSets[4][0].settingName, "settingName2")

self.assertEquals(len(builder.modifierSets), 5)
self.assertEqual(len(builder.modifierSets), 5)
8 changes: 1 addition & 7 deletions armi/nucDirectory/tests/test_nuclideBases.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,7 @@ def test_NaturalNuclide_atomicWeightIsAverageOfNaturallyOccuringIsotopes(self):
atomicMass = 0.0
for natIso in natNuk.getNaturalIsotopics():
atomicMass += natIso.abundance * natIso.weight
self.assertEqual(
atomicMass,
natNuk.weight,
"{} weight is {}, expected {}".format(
natNuk, natNuk.weight, atomicMass
),
)
self.assertAlmostEqual(atomicMass, natNuk.weight, delta=0.000001)

def test_nucBases_labelAndNameCollsionsAreForSameNuclide(self):
"""The name and labels for correct for nuclides.
Expand Down
4 changes: 2 additions & 2 deletions armi/reactor/assemblies.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def __init__(self, typ, assemNum=None):
"""
# If no assembly number is provided, generate a random number as a placeholder.
if assemNum is None:
assemNum = randint(-9e12, -1)
assemNum = randint(-9000000000000, -1)
name = self.makeNameFromAssemNum(assemNum)
composites.Composite.__init__(self, name)
self.p.assemNum = assemNum
Expand Down Expand Up @@ -157,7 +157,7 @@ def makeUnique(self):
otherwise have been the same object.
"""
# Default to a random negative assembly number (unique enough)
self.p.assemNum = randint(-9e12, -1)
self.p.assemNum = randint(-9000000000000, -1)
self.renumber(self.p.assemNum)

def add(self, obj: blocks.Block):
Expand Down
1 change: 1 addition & 0 deletions doc/release/0.4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Release Date: TBD

New Features
------------
#. ARMI now supports Python 3.12. (`PR#1813 <https://github.com/terrapower/armi/pull/1813>`_)
#. TBD

API Changes
Expand Down
10 changes: 7 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,19 @@ authors = [
]
dependencies = [
"coverage>=7.2.0", # Code coverage tool. Sadly baked into every Case.
"h5py>=3.0,<=3.9", # Needed because our database files are H5 format
"h5py>=3.9 ; python_version >= '3.11.0'", # Needed because our database files are H5 format
"h5py>=3.0,<=3.9 ; python_version < '3.11.0'",
"htmltree>=0.7.6", # Our reports have HTML output
"matplotlib>=3.5.3,<3.8.0", # Important plotting library
"numpy>=1.21", # Important math library
"ordered-set>=3.1.1", # A useful data structure
"pluggy>=1.2.0", # Central tool behind the ARMI Plugin system
"pyDOE>=0.3.8", # We import a Latin-hypercube algorithm to explore a phase space
"pyevtk>=1.2.0", # Handles binary VTK visualization files
"ruamel.yaml.clib<=0.2.7", # C-based core of ruamel below
"ruamel.yaml<=0.17.21", # Our foundational YAML library
"ruamel.yaml.clib ; python_version >= '3.11.0'", # C-based core of ruamel below
"ruamel.yaml ; python_version >= '3.11.0'", # Our foundational YAML library
"ruamel.yaml.clib<=0.2.7 ; python_version < '3.11.0'", # C-based core of ruamel below
"ruamel.yaml<=0.17.21 ; python_version < '3.11.0'", # Our foundational YAML library
"scipy>=1.7.0", # Used for curve-fitting and matrix math
"tabulate>=0.8.9", # Used to pretty-print tabular data
"toml>0.9.5", # Needed to parse the pyproject.toml file
Expand All @@ -58,6 +61,7 @@ classifiers = [
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Scientific/Engineering :: Information Analysis",
]

Expand Down

0 comments on commit 9ad6e6c

Please sign in to comment.