From 16d7ec0641508ad5799623548dcbbc7a9570ff27 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 17 Jun 2020 16:57:56 -0500 Subject: [PATCH 1/2] Sort XML attributes to preserve pre-Python 3.8 XML writing behavior --- openmc/_xml.py | 18 ++++++++++++++++++ openmc/data/library.py | 3 ++- openmc/geometry.py | 1 + openmc/material.py | 4 +++- openmc/plots.py | 3 ++- openmc/settings.py | 3 ++- openmc/tallies.py | 3 ++- 7 files changed, 30 insertions(+), 5 deletions(-) diff --git a/openmc/_xml.py b/openmc/_xml.py index b49d19209..32679fd89 100644 --- a/openmc/_xml.py +++ b/openmc/_xml.py @@ -43,3 +43,21 @@ def get_text(elem, name, default=None): else: child = elem.find(name) return child.text if child is not None else default + + +def reorder_attributes(root): + """Sort attributes in XML to preserve pre-Python 3.8 behavior + + Parameters + ---------- + root : xml.etree.ElementTree.Element + Root element + + """ + for el in root.iter(): + attrib = el.attrib + if len(attrib) > 1: + # adjust attribute order, e.g. by sorting + attribs = sorted(attrib.items()) + attrib.clear() + attrib.update(attribs) diff --git a/openmc/data/library.py b/openmc/data/library.py index a66260b92..cd0fe0895 100644 --- a/openmc/data/library.py +++ b/openmc/data/library.py @@ -5,7 +5,7 @@ import pathlib import h5py from openmc.mixin import EqualityMixin -from openmc._xml import clean_indentation +from openmc._xml import clean_indentation, reorder_attributes class DataLibrary(EqualityMixin): @@ -112,6 +112,7 @@ class DataLibrary(EqualityMixin): clean_indentation(root) # Write XML file + reorder_attributes(root) # TODO: Remove when support is Python 3.8+ tree = ET.ElementTree(root) tree.write(str(path), xml_declaration=True, encoding='utf-8', method='xml') diff --git a/openmc/geometry.py b/openmc/geometry.py index 450f223b1..3becde9a7 100644 --- a/openmc/geometry.py +++ b/openmc/geometry.py @@ -110,6 +110,7 @@ class Geometry: p /= 'geometry.xml' # Write the XML Tree to the geometry.xml file + xml.reorder_attributes(root_element) # TODO: Remove when support is Python 3.8+ tree = ET.ElementTree(root_element) tree.write(str(p), xml_declaration=True, encoding='utf-8') diff --git a/openmc/material.py b/openmc/material.py index 92f5132c5..2ab36cf7e 100644 --- a/openmc/material.py +++ b/openmc/material.py @@ -12,7 +12,7 @@ import numpy as np import openmc import openmc.data import openmc.checkvalue as cv -from ._xml import clean_indentation +from ._xml import clean_indentation, reorder_attributes from .mixin import IDManagerMixin @@ -1239,6 +1239,7 @@ class Materials(cv.CheckedList): clean_indentation(element, level=1) element.tail = element.tail.strip(' ') fh.write(' ') + reorder_attributes(element) # TODO: Remove when support is Python 3.8+ ET.ElementTree(element).write(fh, encoding='unicode') # Write the elements. @@ -1247,6 +1248,7 @@ class Materials(cv.CheckedList): clean_indentation(element, level=1) element.tail = element.tail.strip(' ') fh.write(' ') + reorder_attributes(element) # TODO: Remove when support is Python 3.8+ ET.ElementTree(element).write(fh, encoding='unicode') # Write the closing tag for the root element. diff --git a/openmc/plots.py b/openmc/plots.py index 05ce684df..33020c48a 100644 --- a/openmc/plots.py +++ b/openmc/plots.py @@ -8,7 +8,7 @@ import numpy as np import openmc import openmc.checkvalue as cv -from ._xml import clean_indentation +from ._xml import clean_indentation, reorder_attributes from .mixin import IDManagerMixin @@ -844,5 +844,6 @@ class Plots(cv.CheckedList): p /= 'plots.xml' # Write the XML Tree to the plots.xml file + reorder_attributes(self._plots_file) # TODO: Remove when support is Python 3.8+ tree = ET.ElementTree(self._plots_file) tree.write(str(p), xml_declaration=True, encoding='utf-8') diff --git a/openmc/settings.py b/openmc/settings.py index 677442755..16d4e9578 100644 --- a/openmc/settings.py +++ b/openmc/settings.py @@ -6,7 +6,7 @@ from xml.etree import ElementTree as ET import openmc.checkvalue as cv from . import VolumeCalculation, Source, RegularMesh -from ._xml import clean_indentation, get_text +from ._xml import clean_indentation, get_text, reorder_attributes class RunMode(Enum): @@ -1375,6 +1375,7 @@ class Settings: p /= 'settings.xml' # Write the XML Tree to the settings.xml file + reorder_attributes(root_element) # TODO: Remove when support is Python 3.8+ tree = ET.ElementTree(root_element) tree.write(str(p), xml_declaration=True, encoding='utf-8') diff --git a/openmc/tallies.py b/openmc/tallies.py index cf09c1416..646482ede 100644 --- a/openmc/tallies.py +++ b/openmc/tallies.py @@ -14,7 +14,7 @@ import scipy.sparse as sps import openmc import openmc.checkvalue as cv -from ._xml import clean_indentation +from ._xml import clean_indentation, reorder_attributes from .mixin import IDManagerMixin @@ -3143,5 +3143,6 @@ class Tallies(cv.CheckedList): p /= 'tallies.xml' # Write the XML Tree to the tallies.xml file + reorder_attributes(root_element) # TODO: Remove when support is Python 3.8+ tree = ET.ElementTree(root_element) tree.write(str(p), xml_declaration=True, encoding='utf-8') From ca10c58c8a2c61a774e560aedd8a8891e86df816 Mon Sep 17 00:00:00 2001 From: Paul Romano Date: Wed, 17 Jun 2020 22:08:56 -0500 Subject: [PATCH 2/2] Ensure boundary_type is used by keyword in several spots --- openmc/mesh.py | 20 +++++++++---------- .../photon_production/test.py | 4 ++-- .../resonance_scattering/test.py | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/openmc/mesh.py b/openmc/mesh.py index 1c934996f..8f6cccb80 100644 --- a/openmc/mesh.py +++ b/openmc/mesh.py @@ -361,14 +361,14 @@ class RegularMesh(MeshBase): n_dim = len(self.dimension) # Build the cell which will contain the lattice - xplanes = [openmc.XPlane(self.lower_left[0], bc[0]), - openmc.XPlane(self.upper_right[0], bc[1])] + xplanes = [openmc.XPlane(self.lower_left[0], boundary_type=bc[0]), + openmc.XPlane(self.upper_right[0], boundary_type=bc[1])] if n_dim == 1: - yplanes = [openmc.YPlane(-1e10, 'reflective'), - openmc.YPlane(1e10, 'reflective')] + yplanes = [openmc.YPlane(-1e10, boundary_type='reflective'), + openmc.YPlane(1e10, boundary_type='reflective')] else: - yplanes = [openmc.YPlane(self.lower_left[1], bc[2]), - openmc.YPlane(self.upper_right[1], bc[3])] + yplanes = [openmc.YPlane(self.lower_left[1], boundary_type=bc[2]), + openmc.YPlane(self.upper_right[1], boundary_type=bc[3])] if n_dim <= 2: # Would prefer to have the z ranges be the max supported float, but @@ -378,11 +378,11 @@ class RegularMesh(MeshBase): # inconsistency between what numpy uses as the max float and what # Fortran expects for a real(8), so this avoids code complication # and achieves the same goal. - zplanes = [openmc.ZPlane(-1e10, 'reflective'), - openmc.ZPlane(1e10, 'reflective')] + zplanes = [openmc.ZPlane(-1e10, boundary_type='reflective'), + openmc.ZPlane(1e10, boundary_type='reflective')] else: - zplanes = [openmc.ZPlane(self.lower_left[2], bc[4]), - openmc.ZPlane(self.upper_right[2], bc[5])] + zplanes = [openmc.ZPlane(self.lower_left[2], boundary_type=bc[4]), + openmc.ZPlane(self.upper_right[2], boundary_type=bc[5])] root_cell = openmc.Cell() root_cell.region = ((+xplanes[0] & -xplanes[1]) & (+yplanes[0] & -yplanes[1]) & diff --git a/tests/regression_tests/photon_production/test.py b/tests/regression_tests/photon_production/test.py index c20d4487a..f56e83535 100644 --- a/tests/regression_tests/photon_production/test.py +++ b/tests/regression_tests/photon_production/test.py @@ -13,9 +13,9 @@ def model(): model.materials.append(mat) cyl = openmc.XCylinder(r=1.0, boundary_type='vacuum') - x_plane_left = openmc.XPlane(-1.0, 'vacuum') + x_plane_left = openmc.XPlane(-1.0, boundary_type='vacuum') x_plane_center = openmc.XPlane(1.0) - x_plane_right = openmc.XPlane(1.0e9, 'vacuum') + x_plane_right = openmc.XPlane(1.0e9, boundary_type='vacuum') inner_cyl_left = openmc.Cell() inner_cyl_right = openmc.Cell() diff --git a/tests/regression_tests/resonance_scattering/test.py b/tests/regression_tests/resonance_scattering/test.py index 588ba7c97..e77dd9258 100644 --- a/tests/regression_tests/resonance_scattering/test.py +++ b/tests/regression_tests/resonance_scattering/test.py @@ -17,7 +17,7 @@ class ResonanceScatteringTestHarness(PyAPITestHarness): mats_file.export_to_xml() # Geometry - dumb_surface = openmc.XPlane(100, 'reflective') + dumb_surface = openmc.XPlane(100, boundary_type='reflective') c1 = openmc.Cell(cell_id=1, fill=mat, region=-dumb_surface) root_univ = openmc.Universe(universe_id=0, cells=[c1]) geometry = openmc.Geometry(root_univ)