diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index 34ffca47..e98f6600 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -10,6 +10,8 @@ MontePy Changelog **Bugs Fixed** +* Fixed a bug where surface type mnemonics (e.g. ``SO``, ``PZ``) were always written in uppercase, discarding the original case supplied by the user (e.g. ``sO``, ``Pz``) (:issue:`522`). + * Fixed a bug where ``append_renumber`` raised a ``TypeError`` when called with an object whose ``number`` is ``None`` (e.g. an object created with no arguments) (:issue:`880`). * Fixed a bug where the importance of cells made from scratch are usually not printed to the output file (:pull:`921`). diff --git a/montepy/input_parser/syntax_node.py b/montepy/input_parser/syntax_node.py index 741b0722..eb34d55e 100644 --- a/montepy/input_parser/syntax_node.py +++ b/montepy/input_parser/syntax_node.py @@ -1257,6 +1257,26 @@ def _value_changed(self): return not math.isclose( self._print_value, self._og_value, rel_tol=rel_tol, abs_tol=abs_tol ) + if isinstance(self._type, type) and issubclass(self._type, enum.Enum): + canonical = self.value.value + if isinstance(canonical, str): + # Compare case-insensitively: the original token may differ in + # case from the normalised enum value (e.g. "sO" → SO). + # If they match modulo case the field is unchanged and the + # original token casing is preserved on write. + # + # _og_value may not be a string for integer-based enums (e.g. + # Lattice), where convert_to_int() runs before convert_to_enum() + # leaving _og_value as an int. Normalise to str for the + # case-insensitive compare. + og = ( + self._og_value + if isinstance(self._og_value, str) + else str(self._og_value) + ) + return canonical.upper() != og.upper() + # Integer-valued enums (e.g. Lattice): case is irrelevant; fall + # through to the exact-equality check below. return self.value != self._og_value def _avoid_rounding_truncation(self): diff --git a/tests/test_surfaces.py b/tests/test_surfaces.py index 66b2c9ca..55012dc3 100644 --- a/tests/test_surfaces.py +++ b/tests/test_surfaces.py @@ -603,3 +603,21 @@ def test_surface_is_white_bound_setter(cp_simple_problem, in_str, expected): verify_prob_export(cp_simple_problem, surf) with pytest.raises(TypeError): surf.is_white_boundary = 1 + + +@pytest.mark.parametrize( + "in_str,expected", + [ + ("1 so 0.0", "1 so 0.0"), + ("1 sO 0.0", "1 sO 0.0"), + ("1 So 0.0", "1 So 0.0"), + ("1 SO 0.0", "1 SO 0.0"), + ("1 pz 0.0", "1 pz 0.0"), + ("1 PZ 0.0", "1 PZ 0.0"), + ("1 Pz 0.0", "1 Pz 0.0"), + ], +) +def test_surface_preserves_mnemonic_case(in_str, expected): + """Surface mnemonics should be written with the original case (issue #522).""" + surf = Surface(in_str) + assert surf.mcnp_str() == expected