From 3883295483a8884b0680a0a972d46dc58f62c11e Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 09:15:52 -0600 Subject: [PATCH 01/39] Made all objects parsable from a bare string. --- montepy/cell.py | 8 ++++++-- montepy/data_inputs/data_input.py | 10 ++++++++-- montepy/mcnp_object.py | 21 ++++++++++++++++++--- montepy/surfaces/surface.py | 11 ++++++++--- 4 files changed, 40 insertions(+), 10 deletions(-) diff --git a/montepy/cell.py b/montepy/cell.py index 5b07d7d0..34c38308 100644 --- a/montepy/cell.py +++ b/montepy/cell.py @@ -1,8 +1,11 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. +from __future__ import annotations import copy import itertools import numbers +from typing import Union +import montepy from montepy.cells import Cells from montepy.constants import BLANK_SPACE_CONTINUE from montepy.data_inputs import importance, fill, lattice_input, universe_input, volume @@ -33,8 +36,8 @@ class Cell(Numbered_MCNP_Object): Removed the ``comments`` argument due to overall simplification of init process. - :param input: the input for the cell definition - :type input: Input + :param input: The Input syntax object this will wrap and parse. + :type input: Union[Input, str] .. seealso:: @@ -72,6 +75,7 @@ class Cell(Numbered_MCNP_Object): _parser = CellParser() def __init__(self, input=None): + self._BLOCK_TYPE = montepy.input_parser.block_type.BlockType.CELL self._material = None self._old_number = self._generate_default_node(int, -1) self._load_blank_modifiers() diff --git a/montepy/data_inputs/data_input.py b/montepy/data_inputs/data_input.py index 3beb8290..fbd04d27 100644 --- a/montepy/data_inputs/data_input.py +++ b/montepy/data_inputs/data_input.py @@ -1,4 +1,5 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. +from __future__ import annotations from abc import abstractmethod import copy @@ -14,6 +15,7 @@ from montepy.mcnp_object import MCNP_Object import re +from typing import Union class _ClassifierInput(Input): @@ -43,7 +45,7 @@ class DataInputAbstract(MCNP_Object): Parent class to describe all MCNP data inputs. :param input: the Input object representing this data input - :type input: Input + :type input: Union[Input, str] :param fast_parse: Whether or not to only parse the first word for the type of data. :type fast_parse: bool """ @@ -52,7 +54,11 @@ class DataInputAbstract(MCNP_Object): _classifier_parser = ClassifierParser() - def __init__(self, input=None, fast_parse=False): + def __init__( + self, + input: Union[montepy.input_parser.mcnp_input.Input, str] = None, + fast_parse=False, + ): self._particles = None if not fast_parse: super().__init__(input, self._parser) diff --git a/montepy/mcnp_object.py b/montepy/mcnp_object.py index c96d4126..1595aa36 100644 --- a/montepy/mcnp_object.py +++ b/montepy/mcnp_object.py @@ -1,4 +1,5 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. +from __future__ import annotations from abc import ABC, ABCMeta, abstractmethod import copy import functools @@ -19,6 +20,7 @@ import montepy import numpy as np import textwrap +from typing import Union import warnings import weakref @@ -91,18 +93,31 @@ class MCNP_Object(ABC, metaclass=_ExceptionContextAdder): For init removed ``comments``, and added ``parser`` as arguments. :param input: The Input syntax object this will wrap and parse. - :type input: Input + :type input: Union[Input, str] :param parser: The parser object to parse the input with. :type parser: MCNP_Lexer """ - def __init__(self, input, parser): + """ + The block type this input comes from. + """ + + def __init__( + self, + input: Union[montepy.input_parser.mcnp_input.Input, str], + parser: montepy.input_parser.parser_base.MCNP_Parser, + ): + self._BLOCK_TYPE = montepy.input_parser.block_type.BlockType.DATA self._problem_ref = None self._parameters = ParametersNode() self._input = None if input: - if not isinstance(input, montepy.input_parser.mcnp_input.Input): + if not isinstance(input, (montepy.input_parser.mcnp_input.Input, str)): raise TypeError("input must be an Input") + if isinstance(input, str): + input = montepy.input_parser.mcnp_input.Input( + input.split("\n"), self._BLOCK_TYPE + ) try: try: parser.restart() diff --git a/montepy/surfaces/surface.py b/montepy/surfaces/surface.py index 9612b750..94fb7964 100644 --- a/montepy/surfaces/surface.py +++ b/montepy/surfaces/surface.py @@ -1,5 +1,10 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. +from __future__ import annotations import copy +import re +from typing import Union + +import montepy from montepy.errors import * from montepy.data_inputs import transform from montepy.input_parser import syntax_node @@ -8,7 +13,6 @@ from montepy.surfaces import half_space from montepy.surfaces.surface_type import SurfaceType from montepy.utilities import * -import re class Surface(Numbered_MCNP_Object): @@ -16,12 +20,13 @@ class Surface(Numbered_MCNP_Object): Object to hold a single MCNP surface :param input: The Input object representing the input - :type input: Input + :type input: Union[Input, str] """ _parser = SurfaceParser() - def __init__(self, input=None): + def __init__(self, input: Union[montepy.input_parser.mcnp_input.Input, str] = None): + self._BLOCK_TYPE = montepy.input_parser.block_type.BlockType.SURFACE super().__init__(input, self._parser) self._periodic_surface = None self._old_periodic_surface = self._generate_default_node(int, None) From 013d15a1ba72ccf51a575689eaa359321fb1350b Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 09:19:23 -0600 Subject: [PATCH 02/39] Updated tests to test using a str init. --- tests/test_cell_problem.py | 6 ++---- tests/test_material.py | 3 +-- tests/test_surfaces.py | 4 +--- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/tests/test_cell_problem.py b/tests/test_cell_problem.py index 8dd1ed8c..cdb7ab03 100644 --- a/tests/test_cell_problem.py +++ b/tests/test_cell_problem.py @@ -12,7 +12,7 @@ class TestCellClass(TestCase): def test_bad_init(self): with self.assertRaises(TypeError): - Cell("5") + Cell(5) # TODO test updating cell geometry once done def test_cell_validator(self): @@ -29,9 +29,7 @@ def test_cell_validator(self): # TODO test geometry stuff def test_number_setter(self): - in_str = "1 0 2" - card = Input([in_str], BlockType.CELL) - cell = Cell(card) + cell = Cell("1 0 2") cell.number = 5 self.assertEqual(cell.number, 5) with self.assertRaises(TypeError): diff --git a/tests/test_material.py b/tests/test_material.py index d9267c6a..c1bfc8e9 100644 --- a/tests/test_material.py +++ b/tests/test_material.py @@ -18,8 +18,7 @@ class testMaterialClass(TestCase): def test_material_parameter_parsing(self): for line in ["M20 1001.80c 1.0 gas=0", "M20 1001.80c 1.0 gas = 0 nlib = 00c"]: - input = Input([line], BlockType.CELL) - material = Material(input) + material = Material(line) def test_material_validator(self): material = Material() diff --git a/tests/test_surfaces.py b/tests/test_surfaces.py index 9d22ef8b..51902cab 100644 --- a/tests/test_surfaces.py +++ b/tests/test_surfaces.py @@ -17,9 +17,7 @@ class testSurfaces(TestCase): def test_surface_init(self): - in_str = "1 PZ 0.0" - card = Input([in_str], BlockType.SURFACE) - surf = Surface(card) + surf = Surface("1 PZ 0.0") self.assertEqual(surf.number, 1) self.assertEqual(surf.old_number, 1) self.assertEqual(len(surf.surface_constants), 1) From 2c5350bbd62a677b884234bf98ea5214349d147a Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 09:19:39 -0600 Subject: [PATCH 03/39] Fixed case of overriding subclass var. --- montepy/mcnp_object.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/montepy/mcnp_object.py b/montepy/mcnp_object.py index 1595aa36..e2f31612 100644 --- a/montepy/mcnp_object.py +++ b/montepy/mcnp_object.py @@ -107,7 +107,10 @@ def __init__( input: Union[montepy.input_parser.mcnp_input.Input, str], parser: montepy.input_parser.parser_base.MCNP_Parser, ): - self._BLOCK_TYPE = montepy.input_parser.block_type.BlockType.DATA + try: + self._BLOCK_TYPE + except AttributeError: + self._BLOCK_TYPE = montepy.input_parser.block_type.BlockType.DATA self._problem_ref = None self._parameters = ParametersNode() self._input = None From 177287301a4f88190be92272ca58b8cf62ca9627 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 10:11:27 -0600 Subject: [PATCH 04/39] Added number parameter to all numbered mcnp objects. --- montepy/__init__.py | 3 ++- montepy/cell.py | 15 +++++++++--- montepy/data_inputs/material.py | 30 +++++++++++++++++------ montepy/data_inputs/transform.py | 27 ++++++++++++++++----- montepy/data_inputs/universe_input.py | 5 +--- montepy/input_parser/input_reader.py | 4 +-- montepy/mcnp_object.py | 2 +- montepy/numbered_mcnp_object.py | 35 +++++++++++++++++++++++++++ montepy/surfaces/axis_plane.py | 12 ++++++--- montepy/surfaces/cylinder_on_axis.py | 13 +++++++--- montepy/surfaces/cylinder_par_axis.py | 12 ++++++--- montepy/surfaces/general_plane.py | 19 +++++++++++++-- montepy/surfaces/surface.py | 14 +++++++++-- montepy/universe.py | 4 +-- 14 files changed, 155 insertions(+), 40 deletions(-) diff --git a/montepy/__init__.py b/montepy/__init__.py index 12f3b791..2782b260 100644 --- a/montepy/__init__.py +++ b/montepy/__init__.py @@ -7,14 +7,15 @@ You will receive an MCNP_Problem object that you will interact with. """ +from . import data_inputs from . import input_parser from . import constants import importlib.metadata from .input_parser.input_reader import read_input from montepy.cell import Cell -from montepy.mcnp_problem import MCNP_Problem from montepy.data_inputs.material import Material from montepy.data_inputs.transform import Transform +from montepy.mcnp_problem import MCNP_Problem from montepy.geometry_operators import Operator from montepy import geometry_operators from montepy.input_parser.mcnp_input import Jump diff --git a/montepy/cell.py b/montepy/cell.py index 34c38308..283d1f1c 100644 --- a/montepy/cell.py +++ b/montepy/cell.py @@ -35,9 +35,15 @@ class Cell(Numbered_MCNP_Object): .. versionchanged:: 0.2.0 Removed the ``comments`` argument due to overall simplification of init process. + .. versionchanged:: 1.0.0 + + Added number parameter + :param input: The Input syntax object this will wrap and parse. :type input: Union[Input, str] + :param number: The number to set for this object. + :type number: int .. seealso:: @@ -74,7 +80,11 @@ class Cell(Numbered_MCNP_Object): } _parser = CellParser() - def __init__(self, input=None): + def __init__( + self, + input: Union[montepy.input_parser.mcnp_input.Input, str] = None, + number: int = None, + ): self._BLOCK_TYPE = montepy.input_parser.block_type.BlockType.CELL self._material = None self._old_number = self._generate_default_node(int, -1) @@ -83,8 +93,7 @@ def __init__(self, input=None): self._density_node = self._generate_default_node(float, None) self._surfaces = Surfaces() self._complements = Cells() - self._number = self._generate_default_node(int, -1) - super().__init__(input, self._parser) + super().__init__(input, self._parser, number) if not input: self._generate_default_tree() self._old_number = copy.deepcopy(self._tree["cell_num"]) diff --git a/montepy/data_inputs/material.py b/montepy/data_inputs/material.py index b019ff36..1fa8183b 100644 --- a/montepy/data_inputs/material.py +++ b/montepy/data_inputs/material.py @@ -1,5 +1,11 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. +from __future__ import annotations import copy +import itertools +import re +from typing import Union +import warnings + from montepy.data_inputs import data_input, thermal_scattering from montepy.data_inputs.isotope import Isotope from montepy.data_inputs.material_component import MaterialComponent @@ -9,10 +15,7 @@ from montepy.numbered_mcnp_object import Numbered_MCNP_Object from montepy.errors import * from montepy.utilities import * -import itertools -import re - -import warnings +import montepy class Material(data_input.DataInputAbstract, Numbered_MCNP_Object): @@ -23,19 +26,30 @@ class Material(data_input.DataInputAbstract, Numbered_MCNP_Object): There is a known bug (:issue:`182`) that valid MCNP material definitions cannot be parsed. + .. versionchanged:: 1.0.0 + + Added number parameter - :param input: the input card that contains the data - :type input: Input + :param input: The Input syntax object this will wrap and parse. + :type input: Union[Input, str] + :param parser: The parser object to parse the input with. + :type parser: MCNP_Parser + :param number: The number to set for this object. + :type number: int """ _parser = MaterialParser() - def __init__(self, input=None): + def __init__( + self, + input: Union[montepy.input_parser.mcnp_input.Input, str] = None, + number: int = None, + ): self._material_components = {} self._thermal_scattering = None self._is_atom_fraction = True self._number = self._generate_default_node(int, -1) - super().__init__(input) + super().__init__(input, number) if input: num = self._input_number self._old_number = copy.deepcopy(num) diff --git a/montepy/data_inputs/transform.py b/montepy/data_inputs/transform.py index d4917642..349f7c09 100644 --- a/montepy/data_inputs/transform.py +++ b/montepy/data_inputs/transform.py @@ -1,23 +1,38 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. +from __future__ import annotations import copy +import numpy as np +import re +from typing import Union + +import montepy from montepy import mcnp_object from montepy.data_inputs import data_input from montepy.errors import * from montepy.numbered_mcnp_object import Numbered_MCNP_Object from montepy.utilities import * -import numpy as np -import re class Transform(data_input.DataInputAbstract, Numbered_MCNP_Object): """ Input to represent a transform input (TR). - :param input: The Input syntax object this will wrap and parse. - :type input: Input + .. versionchanged:: 1.0.0 + + Added number parameter + + :param input: The Input object representing the input + :type input: Union[Input, str] + :param number: The number to set for this object. + :type number: int """ - def __init__(self, input=None, pass_through=False): + def __init__( + self, + input: union[montepy.input_parser.mcnp_input.input, str] = None, + pass_through: bool = False, + number: int = None, + ): self._pass_through = pass_through self._number = self._generate_default_node(int, -1) self._old_number = self._generate_default_node(int, -1) @@ -25,7 +40,7 @@ def __init__(self, input=None, pass_through=False): self._rotation_matrix = np.array([]) self._is_in_degrees = False self._is_main_to_aux = True - super().__init__(input) + super().__init__(input, number) if input: words = self._tree["data"] i = 0 diff --git a/montepy/data_inputs/universe_input.py b/montepy/data_inputs/universe_input.py index f189f058..d22c41cc 100644 --- a/montepy/data_inputs/universe_input.py +++ b/montepy/data_inputs/universe_input.py @@ -42,10 +42,7 @@ def __init__(self, input=None, in_cell_block=False, key=None, value=None): for node in self.data: try: node.is_negatable_identifier = True - if node.value is not None: - self._old_numbers.append(node) - else: - self._old_numbers.append(node) + self._old_numbers.append(node) except ValueError: raise MalformedInputError( input, diff --git a/montepy/input_parser/input_reader.py b/montepy/input_parser/input_reader.py index 4c508a01..3cc438af 100644 --- a/montepy/input_parser/input_reader.py +++ b/montepy/input_parser/input_reader.py @@ -1,5 +1,5 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. -from montepy import mcnp_problem +import montepy from montepy.constants import DEFAULT_VERSION @@ -26,7 +26,7 @@ def read_input(destination, mcnp_version=DEFAULT_VERSION, replace=True): :raises BrokenObjectLinkError: If a reference is made to an object that is not in the input file. :raises UnknownElement: If an isotope is specified for an unknown element. """ - problem = mcnp_problem.MCNP_Problem(destination) + problem = montepy.mcnp_problem.MCNP_Problem(destination) problem.mcnp_version = mcnp_version problem.parse_input(replace=replace) return problem diff --git a/montepy/mcnp_object.py b/montepy/mcnp_object.py index e2f31612..4e2e2773 100644 --- a/montepy/mcnp_object.py +++ b/montepy/mcnp_object.py @@ -95,7 +95,7 @@ class MCNP_Object(ABC, metaclass=_ExceptionContextAdder): :param input: The Input syntax object this will wrap and parse. :type input: Union[Input, str] :param parser: The parser object to parse the input with. - :type parser: MCNP_Lexer + :type parser: MCNP_Parser """ """ diff --git a/montepy/numbered_mcnp_object.py b/montepy/numbered_mcnp_object.py index 9d79ee6c..6f465b16 100644 --- a/montepy/numbered_mcnp_object.py +++ b/montepy/numbered_mcnp_object.py @@ -1,7 +1,11 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. +from __future__ import annotations from abc import abstractmethod import copy import itertools +from typing import Union + + from montepy.errors import NumberConflictError from montepy.mcnp_object import MCNP_Object import montepy @@ -30,6 +34,37 @@ def _number_validator(self, number): class Numbered_MCNP_Object(MCNP_Object): + """ + An abstract class to represent an mcnp object that has a number. + + .. versionchanged:: 1.0.0 + + Added number parameter + + :param input: The Input syntax object this will wrap and parse. + :type input: Union[Input, str] + :param parser: The parser object to parse the input with. + :type parser: MCNP_Parser + :param number: The number to set for this object. + :type number: int + """ + + def __init__( + self, + input: Union[montepy.input_parser.mcnp_input.Input, str], + parser: montepy.input_parser.parser_base.MCNP_Parser, + number: int = None, + ): + self._number = self._generate_default_node(int, -1) + super().__init__(input, parser) + if number is not None: + if not isinstance(number, int): + raise TypeError( + f"Number must be an int. {number} of type {type(number)} given." + ) + if number < 0: + raise ValueError(f"Number must be 0 or greater. {number} given.") + self.number = number @make_prop_val_node("_number", int, validator=_number_validator) def number(self): diff --git a/montepy/surfaces/axis_plane.py b/montepy/surfaces/axis_plane.py index eae04f42..811a8ad7 100644 --- a/montepy/surfaces/axis_plane.py +++ b/montepy/surfaces/axis_plane.py @@ -9,15 +9,21 @@ class AxisPlane(Surface): """ Represents PX, PY, PZ + .. versionchanged:: 1.0.0 + + Added number parameter + :param input: The Input object representing the input - :type input: Input + :type input: Union[Input, str] + :param number: The number to set for this object. + :type number: int """ COORDINATE = {SurfaceType.PX: "x", SurfaceType.PY: "y", SurfaceType.PZ: "z"} - def __init__(self, input=None): + def __init__(self, input=None, number: int = None): self._location = self._generate_default_node(float, None) - super().__init__(input) + super().__init__(input, number) ST = SurfaceType if input: if self.surface_type not in [ST.PX, ST.PY, ST.PZ]: diff --git a/montepy/surfaces/cylinder_on_axis.py b/montepy/surfaces/cylinder_on_axis.py index 0ade7c00..78174d93 100644 --- a/montepy/surfaces/cylinder_on_axis.py +++ b/montepy/surfaces/cylinder_on_axis.py @@ -14,13 +14,20 @@ class CylinderOnAxis(Surface): """ Represents surfaces: CX, CY, CZ + .. versionchanged:: 1.0.0 + + Added number parameter + + :param input: The Input object representing the input - :type input: Input + :type input: Union[Input, str] + :param number: The number to set for this object. + :type number: int """ - def __init__(self, input=None): + def __init__(self, input=None, number: int = None): self._radius = self._generate_default_node(float, None) - super().__init__(input) + super().__init__(input, number) ST = SurfaceType if input: if self.surface_type not in [ST.CX, ST.CY, ST.CZ]: diff --git a/montepy/surfaces/cylinder_par_axis.py b/montepy/surfaces/cylinder_par_axis.py index 85f52270..a99302a5 100644 --- a/montepy/surfaces/cylinder_par_axis.py +++ b/montepy/surfaces/cylinder_par_axis.py @@ -14,8 +14,14 @@ class CylinderParAxis(Surface): """ Represents surfaces: C/X, C/Y, C/Z + .. versionchanged:: 1.0.0 + + Added number parameter + :param input: The Input object representing the input - :type input: Input + :type input: Union[Input, str] + :param number: The number to set for this object. + :type number: int """ COORDINATE_PAIRS = { @@ -26,13 +32,13 @@ class CylinderParAxis(Surface): """Which coordinate is what value for each cylinder type. """ - def __init__(self, input=None): + def __init__(self, input=None, number: int = None): self._coordinates = [ self._generate_default_node(float, None), self._generate_default_node(float, None), ] self._radius = self._generate_default_node(float, None) - super().__init__(input) + super().__init__(input, number) ST = SurfaceType if input: if self.surface_type not in [ST.C_X, ST.C_Y, ST.C_Z]: diff --git a/montepy/surfaces/general_plane.py b/montepy/surfaces/general_plane.py index 9bf118ea..7b35c650 100644 --- a/montepy/surfaces/general_plane.py +++ b/montepy/surfaces/general_plane.py @@ -1,4 +1,7 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. +from typing import Union + +import montepy from montepy.errors import * from montepy.surfaces.surface_type import SurfaceType from montepy.surfaces.surface import Surface @@ -8,12 +11,24 @@ class GeneralPlane(Surface): """ Represents P + .. versionchanged:: 1.0.0 + + Added number parameter + :param input: The Input object representing the input :type input: Input + :param input: The Input object representing the input + :type input: Union[Input, str] + :param number: The number to set for this object. + :type number: int """ - def __init__(self, input=None): - super().__init__(input) + def __init__( + self, + input: Union[montepy.input_parser.mcnp_input.Input, str] = None, + number: int = None, + ): + super().__init__(input, number) if input: if self.surface_type != SurfaceType.P: raise ValueError("A GeneralPlane must be a surface of type P") diff --git a/montepy/surfaces/surface.py b/montepy/surfaces/surface.py index 94fb7964..62a17dea 100644 --- a/montepy/surfaces/surface.py +++ b/montepy/surfaces/surface.py @@ -19,15 +19,25 @@ class Surface(Numbered_MCNP_Object): """ Object to hold a single MCNP surface + .. versionchanged:: 1.0.0 + + Added number parameter + :param input: The Input object representing the input :type input: Union[Input, str] + :param number: The number to set for this object. + :type number: int """ _parser = SurfaceParser() - def __init__(self, input: Union[montepy.input_parser.mcnp_input.Input, str] = None): + def __init__( + self, + input: union[montepy.input_parser.mcnp_input.input, str] = None, + number: int = None, + ): self._BLOCK_TYPE = montepy.input_parser.block_type.BlockType.SURFACE - super().__init__(input, self._parser) + super().__init__(input, self._parser, number) self._periodic_surface = None self._old_periodic_surface = self._generate_default_node(int, None) self._transform = None diff --git a/montepy/universe.py b/montepy/universe.py index 3a17552a..e4b7a2e3 100644 --- a/montepy/universe.py +++ b/montepy/universe.py @@ -16,7 +16,7 @@ class Universe(Numbered_MCNP_Object): :type number: int """ - def __init__(self, number): + def __init__(self, number: int): self._number = self._generate_default_node(int, -1) if not isinstance(number, int): raise TypeError("number must be int") @@ -28,7 +28,7 @@ class Parser: def parse(self, token_gen, input): return syntax_node.SyntaxNode("fake universe", {}) - super().__init__(Input(["U"], BlockType.DATA), Parser()) + super().__init__(Input(["U"], BlockType.DATA), Parser(), number) @property def cells(self): From e2a7079c1e65765b44024a439b0be0b755faebe4 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 10:11:46 -0600 Subject: [PATCH 05/39] added universal parse method. --- montepy/mcnp_problem.py | 45 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/montepy/mcnp_problem.py b/montepy/mcnp_problem.py index cd248aa3..0bec9cef 100644 --- a/montepy/mcnp_problem.py +++ b/montepy/mcnp_problem.py @@ -627,3 +627,48 @@ def __repr__(self): ret += f"{obj}\n" ret += "\n" return ret + + def parse(self, input: str): + """ + Parses the MCNP object given by the string, and links it adds it to this problem. + + This attempts to identify the input type by trying to parse it in the following order: + + #. Data Input + #. Surface + #. Cell + + This is done mostly for optimization to go from easiest parsing to hardest. + This will: + + #. Parse the input + #. Link it to other objects in the problem. Note: this will raise an error if those objects don't exist. + #. Append it to the appropriate collection + + :param input: the string describing the input. New lines are allowed but this does not need to meet MCNP line + length rules. + :type input: str + :returns: the parsed object. + :rtype: MCNP_Object + + :raises TypeError: If a str is not given + :raises ParsingError: If this is not a valid input. + :raises BrokenObjectLinkError: if the dependent objects are not already in the problem. + :raises NumberConflictError: if the object's number is already taken + """ + try: + obj = montepy.data_inputs.data_parser.parse_data(input) + except ParsingError: + try: + obj = montepy.surfaces.surface_builder.Surface(input) + except ParsingError: + obj = montepy.Cell(input) + # let final parsing error bubble up + obj.link_to_problem(self) + if isinstance(obj, montepy.Cell): + obj.update_pointers(self.cells, self.materials, self.surfaces) + elif isinstance(obj, montepy.surfaces.Surface): + obj.update_pointers(self.surfaces, self.data_inputs) + else: + obj.update_pointers(self.data_inputs) + return obj From 0009c78cb78a63a010a0a77df76c0848b540fe8f Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 10:19:58 -0600 Subject: [PATCH 06/39] Test number init. --- tests/test_cell_problem.py | 5 +++++ tests/test_material.py | 5 +++++ tests/test_surfaces.py | 10 ++++++++++ tests/test_transform.py | 2 ++ 4 files changed, 22 insertions(+) diff --git a/tests/test_cell_problem.py b/tests/test_cell_problem.py index cdb7ab03..3d98818c 100644 --- a/tests/test_cell_problem.py +++ b/tests/test_cell_problem.py @@ -158,6 +158,11 @@ def test_init(line, is_void, mat_number, density, atom_dens, parameters): assert cell.parameters[parameter]["data"][0].value == pytest.approx(value) +def test_blank_num_init(): + cell = Cell(number=5) + assert cell.number == 5 + + @pytest.mark.parametrize("line", ["foo", "foo bar", "1 foo", "1 1 foo"]) def test_malformed_init(line): with pytest.raises(montepy.errors.MalformedInputError): diff --git a/tests/test_material.py b/tests/test_material.py index c1bfc8e9..b8f86113 100644 --- a/tests/test_material.py +++ b/tests/test_material.py @@ -190,6 +190,11 @@ def test_bad_init(line): Material(input) +def test_mat_num_init(): + mat = Material(number=5) + assert mat.number == 5 + + @pytest.mark.filterwarnings("ignore") @given(st.integers(), st.integers()) def test_mat_clone(start_num, step): diff --git a/tests/test_surfaces.py b/tests/test_surfaces.py index 51902cab..d20dee31 100644 --- a/tests/test_surfaces.py +++ b/tests/test_surfaces.py @@ -77,6 +77,8 @@ def test_surface_init(self): card = Input([in_str], BlockType.SURFACE) with self.assertRaises(MalformedInputError): Surface(card) + surf = Surface(number=5) + assert surf.number == 5 def test_validator(self): surf = Surface() @@ -234,6 +236,8 @@ def test_axis_plane_init(self): surf = montepy.surfaces.axis_plane.AxisPlane( Input([bad_input], BlockType.SURFACE) ) + surf = montepy.surfaces.axis_plane.AxisPlane(number=5) + assert surf.number == 5 def test_cylinder_on_axis_init(self): bad_inputs = ["1 P 0.0", "1 CZ 0.0 10.0"] @@ -242,6 +246,8 @@ def test_cylinder_on_axis_init(self): surf = montepy.surfaces.cylinder_on_axis.CylinderOnAxis( Input([bad_input], BlockType.SURFACE) ) + surf = montepy.surfaces.cylinder_on_axis.CylinderOnAxis(number=5) + assert surf.number == 5 def test_cylinder_par_axis_init(self): bad_inputs = ["1 P 0.0", "1 C/Z 0.0"] @@ -250,6 +256,8 @@ def test_cylinder_par_axis_init(self): surf = montepy.surfaces.cylinder_par_axis.CylinderParAxis( Input([bad_input], BlockType.SURFACE) ) + surf = montepy.surfaces.cylinder_par_axis.CylinderParAxis(number=5) + assert surf.number == 5 def test_gen_plane_init(self): bad_inputs = ["1 PZ 0.0", "1 P 0.0"] @@ -258,6 +266,8 @@ def test_gen_plane_init(self): surf = montepy.surfaces.general_plane.GeneralPlane( Input([bad_input], BlockType.SURFACE) ) + surf = montepy.surfaces.general_plane.GeneralPlane(number=5) + assert surf.number == 5 def test_axis_plane_location_setter(self): in_str = "1 PZ 0.0" diff --git a/tests/test_transform.py b/tests/test_transform.py index 421530a1..b1d59574 100644 --- a/tests/test_transform.py +++ b/tests/test_transform.py @@ -48,6 +48,8 @@ def test_transform_init(self): with self.assertRaises(MalformedInputError): card = Input(["TR5:n,p 0.0 0.0 0.0"], BlockType.DATA) Transform(card) + transform = Transform(number=5) + assert transform.number == 5 # test vanilla case in_str = "tr5 " + "1.0 " * 3 + "0.0 " * 9 From d3d1acc041e228b02355c7ae64d5cf9a99e18228 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 10:54:35 -0600 Subject: [PATCH 07/39] Fixed various bugs with how default numbers are loaded. --- montepy/cell.py | 6 +++--- montepy/data_inputs/data_input.py | 14 +++++++++++--- montepy/data_inputs/material.py | 4 ++-- montepy/data_inputs/transform.py | 4 ++-- montepy/numbered_mcnp_object.py | 3 +++ montepy/surfaces/surface.py | 2 +- 6 files changed, 22 insertions(+), 11 deletions(-) diff --git a/montepy/cell.py b/montepy/cell.py index 283d1f1c..b2abb454 100644 --- a/montepy/cell.py +++ b/montepy/cell.py @@ -95,7 +95,7 @@ def __init__( self._complements = Cells() super().__init__(input, self._parser, number) if not input: - self._generate_default_tree() + self._generate_default_tree(number) self._old_number = copy.deepcopy(self._tree["cell_num"]) self._number = self._tree["cell_num"] mat_tree = self._tree["material"] @@ -574,7 +574,7 @@ def _update_values(self): for input_class, (attr, _) in self._INPUTS_TO_PROPERTY.items(): getattr(self, attr)._update_values() - def _generate_default_tree(self): + def _generate_default_tree(self, number: int = None): material = syntax_node.SyntaxNode( "material", { @@ -586,7 +586,7 @@ def _generate_default_tree(self): self._tree = syntax_node.SyntaxNode( "cell", { - "cell_num": self._generate_default_node(int, None), + "cell_num": self._generate_default_node(int, number), "material": material, "geometry": None, "parameters": syntax_node.ParametersNode(), diff --git a/montepy/data_inputs/data_input.py b/montepy/data_inputs/data_input.py index fbd04d27..9d30641e 100644 --- a/montepy/data_inputs/data_input.py +++ b/montepy/data_inputs/data_input.py @@ -65,10 +65,18 @@ def __init__( if input: self.__split_name(input) else: - input = copy.copy(input) - input.__class__ = _ClassifierInput + if input: + if isinstance(input, str): + input = _ClassifierInput( + input.split("\n"), + montepy.input_parser.block_type.BlockType.DATA, + ) + else: + input = copy.copy(input) + input.__class__ = _ClassifierInput super().__init__(input, self._classifier_parser) - self.__split_name(input) + if input: + self.__split_name(input) @staticmethod @abstractmethod diff --git a/montepy/data_inputs/material.py b/montepy/data_inputs/material.py index 1fa8183b..b1736683 100644 --- a/montepy/data_inputs/material.py +++ b/montepy/data_inputs/material.py @@ -48,8 +48,8 @@ def __init__( self._material_components = {} self._thermal_scattering = None self._is_atom_fraction = True - self._number = self._generate_default_node(int, -1) - super().__init__(input, number) + super().__init__(input) + self._load_init_num(number) if input: num = self._input_number self._old_number = copy.deepcopy(num) diff --git a/montepy/data_inputs/transform.py b/montepy/data_inputs/transform.py index 349f7c09..d8b9bb74 100644 --- a/montepy/data_inputs/transform.py +++ b/montepy/data_inputs/transform.py @@ -34,13 +34,13 @@ def __init__( number: int = None, ): self._pass_through = pass_through - self._number = self._generate_default_node(int, -1) self._old_number = self._generate_default_node(int, -1) self._displacement_vector = np.array([]) self._rotation_matrix = np.array([]) self._is_in_degrees = False self._is_main_to_aux = True - super().__init__(input, number) + super().__init__(input) + self._load_init_num(number) if input: words = self._tree["data"] i = 0 diff --git a/montepy/numbered_mcnp_object.py b/montepy/numbered_mcnp_object.py index 6f465b16..d9aa9a4a 100644 --- a/montepy/numbered_mcnp_object.py +++ b/montepy/numbered_mcnp_object.py @@ -57,6 +57,9 @@ def __init__( ): self._number = self._generate_default_node(int, -1) super().__init__(input, parser) + self._load_init_num(number) + + def _load_init_num(self, number): if number is not None: if not isinstance(number, int): raise TypeError( diff --git a/montepy/surfaces/surface.py b/montepy/surfaces/surface.py index 62a17dea..ff1bd3fb 100644 --- a/montepy/surfaces/surface.py +++ b/montepy/surfaces/surface.py @@ -37,6 +37,7 @@ def __init__( number: int = None, ): self._BLOCK_TYPE = montepy.input_parser.block_type.BlockType.SURFACE + self._number = self._generate_default_node(int, -1) super().__init__(input, self._parser, number) self._periodic_surface = None self._old_periodic_surface = self._generate_default_node(int, None) @@ -46,7 +47,6 @@ def __init__( self._is_white_boundary = False self._surface_constants = [] self._surface_type = self._generate_default_node(str, None) - self._number = self._generate_default_node(int, -1) self._modifier = self._generate_default_node(str, None) # surface number if input: From 350accd0349713abed6abbf877c73b960a79e964 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 10:58:23 -0600 Subject: [PATCH 08/39] Added #88 to changelog. --- doc/source/changelog.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index 27b2202a..84007efd 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -2,6 +2,17 @@ MontePy Changelog ***************** +1.0 releases +============ + +#Next Version# +-------------- + +**Features Added** + +* Added ability to parse all MCNP objects from a string (:pull:`595`). +* Added function: :func:`~montepy.mcnp_problem.MCNP_Problem.parse` to parse arbitrary MCNP object (:pull:`595`). + 0.5 releases ============ From c8b5187f6be1f855dec40a39b3bee53adcb8bb49 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 11:09:00 -0600 Subject: [PATCH 09/39] Tested parse. --- tests/test_integration.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/test_integration.py b/tests/test_integration.py index c569c31c..f164be81 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -1166,3 +1166,21 @@ def test_read_write_cycle(file): ) else: raise e + + +def test_arbitrary_parse(simple_problem): + cell = simple_problem.parse("20 0 -1005") + assert cell in simple_problem.cells + assert cell.number == 20 + assert cell.surfaces[1005] in simple_problem.surfaces + surf = simple_problem.parse("5 SO 7.5") + assert surf in simple_problem.surfaces + assert surf.number == 5 + mat = simple_problem.parse("m123 1001.80c 1.0 8016.80c 2.0") + assert mat in simple_problem.materials + assert mat in simple_problem.data_inputs + assert mat.number == 123 + transform = simple_problem.parse("tr25 0 0 1") + assert transform in simple_problem.transforms + with pytest.raises(ParsingError): + simple_problem.parse("123 hello this is invalid") From a2d60813cfbcd8f389a839c6800f85cb1ef2f41f Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 11:09:11 -0600 Subject: [PATCH 10/39] Actually appended the objects to self. --- montepy/mcnp_problem.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/montepy/mcnp_problem.py b/montepy/mcnp_problem.py index 0bec9cef..93be8d09 100644 --- a/montepy/mcnp_problem.py +++ b/montepy/mcnp_problem.py @@ -667,8 +667,15 @@ def parse(self, input: str): obj.link_to_problem(self) if isinstance(obj, montepy.Cell): obj.update_pointers(self.cells, self.materials, self.surfaces) - elif isinstance(obj, montepy.surfaces.Surface): + self.cells.append(obj) + elif isinstance(obj, montepy.surfaces.surface.Surface): obj.update_pointers(self.surfaces, self.data_inputs) + self.surfaces.append(obj) else: obj.update_pointers(self.data_inputs) + self.data_inputs.append(obj) + if isinstance(obj, Material): + self._materials.append(obj, False) + if isinstance(obj, transform.Transform): + self._transforms.append(obj, False) return obj From c8dd2e4dd8980ef3c703c0050a8d1c113572be97 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 11:17:26 -0600 Subject: [PATCH 11/39] Updated starting guide to use number constructor. --- doc/source/starting.rst | 56 ++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/doc/source/starting.rst b/doc/source/starting.rst index ec413b6b..9c182fc6 100644 --- a/doc/source/starting.rst +++ b/doc/source/starting.rst @@ -267,8 +267,7 @@ The ``NumberedObjectCollection`` has various mechanisms internally to avoid numb import montepy prob = montepy.read_input("tests/inputs/test.imcnp") - cell = montepy.Cell() - cell.number = 2 + cell = montepy.Cell(number = 2) prob.cells.append(cell) .. testoutput:: @@ -334,21 +333,23 @@ Using the generators in this way does not cause any issues, but there are ways t by making "stale" information. This can be done by making a copy of it with ``list()``. ->>> for num in problem.cells.numbers: -... print(num) -1 -2 -3 -99 -5 ->>> numbers = list(problem.cells.numbers) ->>> numbers -[1, 2, 3, 99, 5] ->>> problem.cells[1].number = 1000 ->>> 1000 in problem.cells.numbers -True ->>> 1000 in numbers -False +.. doctest:: + + >>> for num in problem.cells.numbers: + ... print(num) + 1 + 2 + 3 + 99 + 5 + >>> numbers = list(problem.cells.numbers) + >>> numbers + [1, 2, 3, 99, 5] + >>> problem.cells[1].number = 1000 + >>> 1000 in problem.cells.numbers + True + >>> 1000 in numbers + False Oh no! When we made a list of the numbers we broke the link, and the new list won't update when the numbers of the cells change, and you can cause issues this way. @@ -587,23 +588,17 @@ Order of precedence and grouping is automatically handled by Python so you can e .. testcode:: # build blank surfaces - bottom_plane = montepy.surfaces.axis_plane.AxisPlane() + bottom_plane = montepy.surfaces.axis_plane.AxisPlane(number=1) bottom_plane.location = 0.0 - top_plane = montepy.surfaces.axis_plane.AxisPlane() + top_plane = montepy.surfaces.axis_plane.AxisPlane(number=2) top_plane.location = 10.0 - fuel_cylinder = montepy.surfaces.cylinder_on_axis.CylinderOnAxis() + fuel_cylinder = montepy.surfaces.cylinder_on_axis.CylinderOnAxis(number=3) fuel_cylinder.radius = 1.26 / 2 - clad_cylinder = montepy.surfaces.cylinder_on_axis.CylinderOnAxis() + clad_cylinder = montepy.surfaces.cylinder_on_axis.CylinderOnAxis( number=4) clad_cylinder.radius = (1.26 / 2) + 1e-3 # fuel, gap, cladding - clad_od = montepy.surfaces.cylinder_on_axis.CylinderOnAxis() + clad_od = montepy.surfaces.cylinder_on_axis.CylinderOnAxis(number=5) clad_od.radius = clad_cylinder.radius + 0.1 # add thickness - other_fuel = montepy.surfaces.cylinder_on_axis.CylinderOnAxis() - other_fuel.radius = 3.0 - bottom_plane.number = 1 - top_plane.number = 2 - fuel_cylinder.number = 3 - clad_cylinder.number = 4 - clad_od.number = 5 + other_fuel = montepy.surfaces.cylinder_on_axis.CylinderOnAxis(number=6) #make weird truncated fuel sample slug_half_space = +bottom_plane & -top_plane & -fuel_cylinder @@ -795,8 +790,7 @@ You can also easy apply a transform to the filling universe with: .. testcode:: import numpy as np - transform = montepy.data_inputs.transform.Transform() - transform.number = 5 + transform = montepy.data_inputs.transform.Transform(number=5) transform.displacement_vector = np.array([1, 2, 0]) cell.fill.tranform = transform From 085cc3ffb19a9a2206f900136823cfcdc9794671 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 11:17:39 -0600 Subject: [PATCH 12/39] test type enforcement. --- tests/test_cell_problem.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_cell_problem.py b/tests/test_cell_problem.py index 3d98818c..c1a7dff8 100644 --- a/tests/test_cell_problem.py +++ b/tests/test_cell_problem.py @@ -161,6 +161,10 @@ def test_init(line, is_void, mat_number, density, atom_dens, parameters): def test_blank_num_init(): cell = Cell(number=5) assert cell.number == 5 + with pytest.raises(TypeError): + Cell(number = "hi") + with pytest.raises(ValueError): + Cell(number = -1) @pytest.mark.parametrize("line", ["foo", "foo bar", "1 foo", "1 1 foo"]) From fb68afbd2ccfa45caa89aec04ada997a46f36ece Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 11:23:14 -0600 Subject: [PATCH 13/39] Documented how to use parse. --- doc/source/starting.rst | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/doc/source/starting.rst b/doc/source/starting.rst index 9c182fc6..40bf77a9 100644 --- a/doc/source/starting.rst +++ b/doc/source/starting.rst @@ -365,6 +365,35 @@ If a ``Cell`` or a group of ``Cells`` are cloned their numbers will be to change However, if a whole :class:`~montepy.mcnp_problem.MCNP_Problem` is cloned these objects will not have their numbers changed. For an example for how to clone a numbered object see :ref:`Cloning a Cell`. +Creating Objects from a String +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Sometimes its more convenient to create an MCNP object from its input string for MCNP, rather than setting a lot of properties, +or the object you need isn't supported by MontePy yet. +In this case there are a few ways to generate this object. +First all :class:`~montepy.mcnp_object.MCNP_Object` constructors can take a string: + +.. doctest:: + + >>> cell = montepy.Cell("1 0 -2 imp:n=1") + >>> cell.number + 1 + >>> cell.importance[montepy.particle.NEUTRON] + 1.0 + +This object is still unlinked from other objects, and won't be kept with a problem. +So there is also :func:`~montepy.mcnp_problem.MCNP_Problem.parse`. +This takes a string, and then creates the MCNP object, +links it to the problem, +links it to its other objects (e.g., surfaces, materials, etc.), +and appends it to necessary collections: + +.. testcode:: + + cell = problem.parse("123 0 -1005") + assert cell in problem.cells + assert cell.surfaces[1005] is problem.surfaces[1005] + Surfaces -------- From cb17eac89d60929b0a5f2fee84aae0706e70fcdd Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 11:24:38 -0600 Subject: [PATCH 14/39] Formatted with black. --- tests/test_cell_problem.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_cell_problem.py b/tests/test_cell_problem.py index c1a7dff8..e448a7bc 100644 --- a/tests/test_cell_problem.py +++ b/tests/test_cell_problem.py @@ -162,9 +162,9 @@ def test_blank_num_init(): cell = Cell(number=5) assert cell.number == 5 with pytest.raises(TypeError): - Cell(number = "hi") + Cell(number="hi") with pytest.raises(ValueError): - Cell(number = -1) + Cell(number=-1) @pytest.mark.parametrize("line", ["foo", "foo bar", "1 foo", "1 1 foo"]) From a194a4585f144b536679249c6f92bc246b825a23 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 22 Nov 2024 11:28:21 -0600 Subject: [PATCH 15/39] Fixed typo in doctest. --- doc/source/starting.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/starting.rst b/doc/source/starting.rst index 40bf77a9..35627204 100644 --- a/doc/source/starting.rst +++ b/doc/source/starting.rst @@ -378,7 +378,7 @@ First all :class:`~montepy.mcnp_object.MCNP_Object` constructors can take a stri >>> cell = montepy.Cell("1 0 -2 imp:n=1") >>> cell.number 1 - >>> cell.importance[montepy.particle.NEUTRON] + >>> cell.importance[montepy.Particle.NEUTRON] 1.0 This object is still unlinked from other objects, and won't be kept with a problem. From 813d35f2fb8e8b4e0ba7fcb5c049551d9f64fe74 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Thu, 5 Dec 2024 14:58:12 -0600 Subject: [PATCH 16/39] Post-merge black formatting. --- montepy/data_inputs/material.py | 3 +-- tests/test_material.py | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/montepy/data_inputs/material.py b/montepy/data_inputs/material.py index 1f469cc9..ac297b5a 100644 --- a/montepy/data_inputs/material.py +++ b/montepy/data_inputs/material.py @@ -20,7 +20,6 @@ from montepy.particle import LibraryType - MAX_PRINT_ELEMENTS: int = 5 """ The maximum number of elements to print in a material string descripton. @@ -269,7 +268,7 @@ class Material(data_input.DataInputAbstract, Numbered_MCNP_Object): * :manual62:`106` .. versionchanged:: 1.0.0 - + * Added number parameter * This was the primary change for this release. For more details on what changed see :ref:`migrate 0 1`. diff --git a/tests/test_material.py b/tests/test_material.py index 213d8d83..71010351 100644 --- a/tests/test_material.py +++ b/tests/test_material.py @@ -498,7 +498,6 @@ def test_mat_num_init(_): mat = Material(number=5) assert mat.number == 5 - @settings(suppress_health_check=[HealthCheck.function_scoped_fixture]) @given( lib_num=st.integers(0, 99), From eba0d1df8e379bc0830397c18d84576506e0e596 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Thu, 5 Dec 2024 17:01:19 -0600 Subject: [PATCH 17/39] Fixed name errors. --- montepy/data_inputs/material.py | 5 ++++- montepy/data_inputs/transform.py | 2 +- montepy/mcnp_object.py | 1 + montepy/surfaces/surface.py | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/montepy/data_inputs/material.py b/montepy/data_inputs/material.py index ac297b5a..629e6d7c 100644 --- a/montepy/data_inputs/material.py +++ b/montepy/data_inputs/material.py @@ -1,10 +1,13 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. from __future__ import annotations +import collections as co import copy import itertools +import math import re -from typing import Union +from typing import Generator, Union import warnings +import weakref import montepy from montepy.data_inputs import data_input, thermal_scattering diff --git a/montepy/data_inputs/transform.py b/montepy/data_inputs/transform.py index d8b9bb74..ace3a396 100644 --- a/montepy/data_inputs/transform.py +++ b/montepy/data_inputs/transform.py @@ -29,7 +29,7 @@ class Transform(data_input.DataInputAbstract, Numbered_MCNP_Object): def __init__( self, - input: union[montepy.input_parser.mcnp_input.input, str] = None, + input: Union[montepy.input_parser.mcnp_input.input, str] = None, pass_through: bool = False, number: int = None, ): diff --git a/montepy/mcnp_object.py b/montepy/mcnp_object.py index cd9654c0..5e110db1 100644 --- a/montepy/mcnp_object.py +++ b/montepy/mcnp_object.py @@ -7,6 +7,7 @@ import numpy as np import sys import textwrap +from typing import Union import warnings import weakref diff --git a/montepy/surfaces/surface.py b/montepy/surfaces/surface.py index de730c89..5a98fe09 100644 --- a/montepy/surfaces/surface.py +++ b/montepy/surfaces/surface.py @@ -33,7 +33,7 @@ class Surface(Numbered_MCNP_Object): def __init__( self, - input: union[montepy.input_parser.mcnp_input.input, str] = None, + input: Union[montepy.input_parser.mcnp_input.input, str] = None, number: int = None, ): self._CHILD_OBJ_MAP = { From 403fa45cc9632034e9ce32c7315daade220055e4 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 6 Dec 2024 09:35:43 -0600 Subject: [PATCH 18/39] Made lazy pretty print, and abandoned parens. --- montepy/input_parser/syntax_node.py | 61 +++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/montepy/input_parser/syntax_node.py b/montepy/input_parser/syntax_node.py index 7d8843dd..3ada5f2f 100644 --- a/montepy/input_parser/syntax_node.py +++ b/montepy/input_parser/syntax_node.py @@ -196,6 +196,19 @@ def flatten(self): ret += node.flatten() return ret + def pretty_str(self): + INDENT = 2 + if not self.nodes: + return f"" + ret = f"" def __repr__(self): return str(self) @@ -311,6 +324,18 @@ def flatten(self): ret += node.flatten() return ret + def pretty_str(self): + INDENT = 2 + ret = f"" ) def __repr__(self): @@ -570,7 +595,7 @@ def __init__(self, token=None, is_comment=False): self.append(token, is_comment) def __str__(self): - return f"(Padding, {self._nodes})" + return f"" def __repr__(self): return str(self) @@ -1296,7 +1321,7 @@ def token(self): return self._token def __str__(self): - return f"(Value, {self._value}, padding: {self._padding})" + return f"" def __repr__(self): return str(self) @@ -1805,7 +1830,18 @@ def format(self): return ret def __repr__(self): - return f"(Isotopes: {self.nodes})" + return f"(Materials: {self.nodes})" + + def pretty_str(self): + INDENT = 2 + ret = f" +""" + @property def comments(self): if self.padding is not None: @@ -2509,7 +2556,7 @@ def append(self, val, is_default=False): self._nodes[key] = val def __str__(self): - return f"(Parameters, {self.nodes})" + return f"" def __repr__(self): return str(self) From a1897ba53b65e770abcd2e6e744dbb553efc1e4a Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 6 Dec 2024 13:40:54 -0600 Subject: [PATCH 19/39] Made sure mat number is never padded. --- montepy/data_inputs/material.py | 1 + 1 file changed, 1 insertion(+) diff --git a/montepy/data_inputs/material.py b/montepy/data_inputs/material.py index 629e6d7c..6fa70f5a 100644 --- a/montepy/data_inputs/material.py +++ b/montepy/data_inputs/material.py @@ -351,6 +351,7 @@ def _grab_default(self, param: syntax_node.SyntaxNode): def _create_default_tree(self): classifier = syntax_node.ClassifierNode() classifier.number = self._number + classifier.number.never_pad = True classifier.prefix = syntax_node.ValueNode("M", str, never_pad=True) classifier.padding = syntax_node.PaddingNode(" ") mats = syntax_node.MaterialsNode("mat stuff") From 624cbd8a8cd379f0faf8c64ad27e66bcbb4fdb66 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 6 Dec 2024 13:41:13 -0600 Subject: [PATCH 20/39] Switched positional to keyword arg. --- montepy/mcnp_problem.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/montepy/mcnp_problem.py b/montepy/mcnp_problem.py index 66720a31..3dd9a386 100644 --- a/montepy/mcnp_problem.py +++ b/montepy/mcnp_problem.py @@ -671,7 +671,7 @@ def parse(self, input: str): obj.update_pointers(self.data_inputs) self.data_inputs.append(obj) if isinstance(obj, Material): - self._materials.append(obj, False) + self._materials.append(obj, insert_in_data=False) if isinstance(obj, transform.Transform): - self._transforms.append(obj, False) + self._transforms.append(obj, insert_in_data=False) return obj From 2cf7f2a4a035de9f3ac54f865525c0f2e67babe8 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 6 Dec 2024 14:08:09 -0600 Subject: [PATCH 21/39] Tested pretty str. --- tests/test_syntax_parsing.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_syntax_parsing.py b/tests/test_syntax_parsing.py index cbd80e82..d7035e3b 100644 --- a/tests/test_syntax_parsing.py +++ b/tests/test_syntax_parsing.py @@ -440,6 +440,7 @@ def test_syntax_trailing_comments(self): def test_syntax_str(self): str(self.test_node) repr(self.test_node) + self.test_node.pretty_str() class TestGeometryTree(TestCase): @@ -478,6 +479,7 @@ def test_geometry_str(self): test = self.test_tree str(test) repr(test) + test.pretty_str() def test_geometry_comments(self): test = copy.deepcopy(self.test_tree) @@ -696,6 +698,7 @@ def test_list_str(self): list_node.append(syntax_node.ValueNode("1.0", float)) str(list_node) repr(list_node) + list_node.pretty_str() def test_list_slicing(self): list_node = syntax_node.ListNode("list") @@ -793,6 +796,7 @@ def test_isotopes_str(self): isotopes.append_nuclide(("isotope_fraction", zaid, concentration)) str(isotopes) repr(isotopes) + isotopes.pretty_str() def test_isotopes_iter(self): isotopes = syntax_node.MaterialsNode("test") @@ -1573,6 +1577,7 @@ def test_parameter_dict(self): def test_parameter_str(self): str(self.param) repr(self.param) + self.param.pretty_str() def test_parameter_format(self): self.assertEqual(self.param.format(), "vol=1.0") From eca2d48f25603f75457346125f8b8ce72ec8e020 Mon Sep 17 00:00:00 2001 From: "Micah D. Gale" Date: Fri, 6 Dec 2024 14:08:24 -0600 Subject: [PATCH 22/39] Handled more pretty str edge cases. --- montepy/input_parser/syntax_node.py | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/montepy/input_parser/syntax_node.py b/montepy/input_parser/syntax_node.py index 3ada5f2f..8ed8e139 100644 --- a/montepy/input_parser/syntax_node.py +++ b/montepy/input_parser/syntax_node.py @@ -390,6 +390,27 @@ def __str__(self): f"{f'Short:{self._right_short_type.value}' if self._right_short_type else ''}>" ) + def pretty_str(self): + INDENT = 2 + ret = f"" + def pretty_str(self): + return str(self) + def __repr__(self): return str(self) @@ -2561,6 +2588,21 @@ def __str__(self): def __repr__(self): return str(self) + def pretty_str(self): + INDENT = 2 + ret = f" Date: Fri, 13 Dec 2024 23:05:05 -0600 Subject: [PATCH 23/39] Updated changelog to point to issue and not PR. --- doc/source/changelog.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index d8ed053b..a94bcf7f 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst @@ -20,8 +20,8 @@ MontePy Changelog * Made ``Material.is_atom_fraction`` settable (:issue:`511`). * Made NumberedObjectCollections act like a set (:issue:`138`). * Automatically added children objects, e.g., the surfaces in a cell, to the problem when the cell is added to the problem (:issue:`63`). -* Added ability to parse all MCNP objects from a string (:pull:`595`). -* Added function: :func:`~montepy.mcnp_problem.MCNP_Problem.parse` to parse arbitrary MCNP object (:pull:`595`). +* Added ability to parse all MCNP objects from a string (:issue:`88`). +* Added function: :func:`~montepy.mcnp_problem.MCNP_Problem.parse` to parse arbitrary MCNP object (:issue:`88`). * An error is now raised when typos in object attributes are used, e.g., ``cell.nubmer`` (:issue:`508`). From 7dcbbd7cc02ffdea4ab9f8ece9ce80b9e57eb679 Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Fri, 13 Dec 2024 23:07:02 -0600 Subject: [PATCH 24/39] Removed errant doc string. --- montepy/mcnp_object.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/montepy/mcnp_object.py b/montepy/mcnp_object.py index 5e110db1..c45d7201 100644 --- a/montepy/mcnp_object.py +++ b/montepy/mcnp_object.py @@ -106,10 +106,6 @@ class MCNP_Object(ABC, metaclass=_ExceptionContextAdder): :type parser: MCNP_Parser """ - """ - The block type this input comes from. - """ - def __init__( self, input: Union[montepy.input_parser.mcnp_input.Input, str], From 5f83b970d9e98453da2027bc232b52a6db041f94 Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Fri, 13 Dec 2024 23:07:41 -0600 Subject: [PATCH 25/39] Updated all object init to use a type alias hint. --- montepy/cell.py | 4 ++-- montepy/data_inputs/cell_modifier.py | 12 +++++++++--- montepy/data_inputs/data_input.py | 10 ++++++---- montepy/data_inputs/data_parser.py | 6 ++++-- montepy/data_inputs/fill.py | 12 +++++++++--- montepy/data_inputs/importance.py | 12 +++++++++--- montepy/data_inputs/lattice_input.py | 13 ++++++++++--- montepy/data_inputs/material.py | 4 ++-- montepy/data_inputs/thermal_scattering.py | 10 ++++++---- montepy/data_inputs/transform.py | 4 ++-- montepy/data_inputs/universe_input.py | 12 +++++++++--- montepy/mcnp_object.py | 4 +++- montepy/numbered_mcnp_object.py | 4 ++-- montepy/surfaces/axis_plane.py | 5 +++-- montepy/surfaces/cylinder_on_axis.py | 4 ++-- montepy/surfaces/cylinder_par_axis.py | 4 ++-- montepy/surfaces/general_plane.py | 4 ++-- montepy/surfaces/surface.py | 4 ++-- montepy/surfaces/surface_builder.py | 6 +++--- 19 files changed, 87 insertions(+), 47 deletions(-) diff --git a/montepy/cell.py b/montepy/cell.py index 0281c168..356b45e7 100644 --- a/montepy/cell.py +++ b/montepy/cell.py @@ -13,7 +13,7 @@ from montepy.input_parser.cell_parser import CellParser from montepy.input_parser import syntax_node from montepy.errors import * -from montepy.numbered_mcnp_object import Numbered_MCNP_Object +from montepy.numbered_mcnp_object import Numbered_MCNP_Object, InitInput from montepy.data_inputs.material import Material from montepy.geometry_operators import Operator from montepy.surfaces.half_space import HalfSpace, UnitHalfSpace @@ -113,7 +113,7 @@ class Cell(Numbered_MCNP_Object): def __init__( self, - input: Union[montepy.input_parser.mcnp_input.Input, str] = None, + input: InitInput = None, number: int = None, ): self._BLOCK_TYPE = montepy.input_parser.block_type.BlockType.CELL diff --git a/montepy/data_inputs/cell_modifier.py b/montepy/data_inputs/cell_modifier.py index 230e44e5..f6d2ad89 100644 --- a/montepy/data_inputs/cell_modifier.py +++ b/montepy/data_inputs/cell_modifier.py @@ -1,7 +1,7 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. from abc import abstractmethod import montepy -from montepy.data_inputs.data_input import DataInputAbstract +from montepy.data_inputs.data_input import DataInputAbstract, InitInput from montepy.input_parser import syntax_node from montepy.input_parser.block_type import BlockType from montepy.input_parser.mcnp_input import Input, Jump @@ -15,7 +15,7 @@ class CellModifierInput(DataInputAbstract): Examples: IMP, VOL, etc. :param input: the Input object representing this data input - :type input: Input + :type input: Union[Input, str] :param in_cell_block: if this card came from the cell block of an input file. :type in_cell_block: bool :param key: the key from the key-value pair in a cell @@ -24,7 +24,13 @@ class CellModifierInput(DataInputAbstract): :type value: SyntaxNode """ - def __init__(self, input=None, in_cell_block=False, key=None, value=None): + def __init__( + self, + input: InitInput = None, + in_cell_block: bool = False, + key: str = None, + value: syntax_node.SyntaxNode = None, + ): fast_parse = False if key and value: input = Input([key], BlockType.DATA) diff --git a/montepy/data_inputs/data_input.py b/montepy/data_inputs/data_input.py index e48f9b98..daeab526 100644 --- a/montepy/data_inputs/data_input.py +++ b/montepy/data_inputs/data_input.py @@ -12,7 +12,7 @@ ) from montepy.input_parser.mcnp_input import Input from montepy.particle import Particle -from montepy.mcnp_object import MCNP_Object +from montepy.mcnp_object import MCNP_Object, InitInput import re from typing import Union @@ -56,7 +56,7 @@ class DataInputAbstract(MCNP_Object): def __init__( self, - input: Union[montepy.input_parser.mcnp_input.Input, str] = None, + input: InitInput = None, fast_parse=False, ): self._particles = None @@ -280,14 +280,16 @@ class DataInput(DataInputAbstract): Catch-all for all other MCNP data inputs. :param input: the Input object representing this data input - :type input: Input + :type input: Union[Input, str] :param fast_parse: Whether or not to only parse the first word for the type of data. :type fast_parse: bool :param prefix: The input prefix found during parsing (internal use only) :type prefix: str """ - def __init__(self, input=None, fast_parse=False, prefix=None): + def __init__( + self, input: InitInput = None, fast_parse: bool = False, prefix: str = None + ): if prefix: self._load_correct_parser(prefix) super().__init__(input, fast_parse) diff --git a/montepy/data_inputs/data_parser.py b/montepy/data_inputs/data_parser.py index 7d0ca9a2..3d456f7c 100644 --- a/montepy/data_inputs/data_parser.py +++ b/montepy/data_inputs/data_parser.py @@ -1,4 +1,6 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. + +import montepy from montepy.data_inputs import ( data_input, fill, @@ -26,7 +28,7 @@ } -def parse_data(input): +def parse_data(input: montepy.mcnp_object.InitInput): """ Parses the data input as the appropriate object if it is supported. @@ -34,7 +36,7 @@ def parse_data(input): Removed the ``comment`` parameter, as it's in the syntax tree directly now. :param input: the Input object for this Data input - :type input: Input + :type input: Union[Input, str] :return: the parsed DataInput object :rtype: DataInput """ diff --git a/montepy/data_inputs/fill.py b/montepy/data_inputs/fill.py index 1801a70b..2c3653d0 100644 --- a/montepy/data_inputs/fill.py +++ b/montepy/data_inputs/fill.py @@ -1,6 +1,6 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. import itertools as it -from montepy.data_inputs.cell_modifier import CellModifierInput +from montepy.data_inputs.cell_modifier import CellModifierInput, InitInput from montepy.data_inputs.transform import Transform from montepy.errors import * from montepy.input_parser.block_type import BlockType @@ -17,7 +17,7 @@ class Fill(CellModifierInput): Object to handle the ``FILL`` input in cell and data blocks. :param input: the Input object representing this data input - :type input: Input + :type input: Union[Input, str] :param in_cell_block: if this card came from the cell block of an input file. :type in_cell_block: bool :param key: the key from the key-value pair in a cell @@ -31,7 +31,13 @@ class Fill(CellModifierInput): Maps the dimension to its axis number """ - def __init__(self, input=None, in_cell_block=False, key=None, value=None): + def __init__( + self, + input: InitInput = None, + in_cell_block: bool = False, + key: str = None, + value: syntax_node.SyntaxNode = None, + ): self._old_number = self._generate_default_node(int, None) self._old_numbers = None self._universe = None diff --git a/montepy/data_inputs/importance.py b/montepy/data_inputs/importance.py index 0315aefc..74bbcab0 100644 --- a/montepy/data_inputs/importance.py +++ b/montepy/data_inputs/importance.py @@ -2,7 +2,7 @@ import collections import copy import math -from montepy.data_inputs.cell_modifier import CellModifierInput +from montepy.data_inputs.cell_modifier import CellModifierInput, InitInput from montepy.errors import * from montepy.constants import DEFAULT_VERSION, rel_tol, abs_tol from montepy.input_parser import syntax_node @@ -31,7 +31,7 @@ class Importance(CellModifierInput): A data input that sets the importance for a cell(s). :param input: the Input object representing this data input - :type input: Input + :type input: Union[Input, str] :param in_cell_block: if this card came from the cell block of an input file. :type in_cell_block: bool :param key: the key from the key-value pair in a cell @@ -40,7 +40,13 @@ class Importance(CellModifierInput): :type value: SyntaxNode """ - def __init__(self, input=None, in_cell_block=False, key=None, value=None): + def __init__( + self, + input: InitInput = None, + in_cell_block: bool = False, + key: str = None, + value: syntax_node.SyntaxNode = None, + ): self._particle_importances = {} self._real_tree = {} self._part_combos = [] diff --git a/montepy/data_inputs/lattice_input.py b/montepy/data_inputs/lattice_input.py index 69bc69be..4f12e11c 100644 --- a/montepy/data_inputs/lattice_input.py +++ b/montepy/data_inputs/lattice_input.py @@ -1,6 +1,7 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. import itertools -from montepy.data_inputs.cell_modifier import CellModifierInput + +from montepy.data_inputs.cell_modifier import CellModifierInput, InitInput from montepy.data_inputs.lattice import Lattice from montepy.errors import * from montepy.input_parser.mcnp_input import Jump @@ -14,7 +15,7 @@ class LatticeInput(CellModifierInput): Object to handle the inputs from ``LAT``. :param input: the Input object representing this data input - :type input: Input + :type input: Union[Input, str] :param in_cell_block: if this card came from the cell block of an input file. :type in_cell_block: bool :param key: the key from the key-value pair in a cell @@ -23,7 +24,13 @@ class LatticeInput(CellModifierInput): :type value: SyntaxNode """ - def __init__(self, input=None, in_cell_block=False, key=None, value=None): + def __init__( + self, + input: InitInput = None, + in_cell_block: bool = False, + key: str = None, + value: syntax_node.SyntaxNode = None, + ): super().__init__(input, in_cell_block, key, value) self._lattice = self._generate_default_node(int, None) self._lattice._convert_to_enum(Lattice, True, int) diff --git a/montepy/data_inputs/material.py b/montepy/data_inputs/material.py index 6fa70f5a..caafbfa3 100644 --- a/montepy/data_inputs/material.py +++ b/montepy/data_inputs/material.py @@ -17,7 +17,7 @@ from montepy.input_parser import syntax_node from montepy.input_parser.material_parser import MaterialParser from montepy import mcnp_object -from montepy.numbered_mcnp_object import Numbered_MCNP_Object +from montepy.numbered_mcnp_object import Numbered_MCNP_Object, InitInput from montepy.errors import * from montepy.utilities import * from montepy.particle import LibraryType @@ -287,7 +287,7 @@ class Material(data_input.DataInputAbstract, Numbered_MCNP_Object): def __init__( self, - input: Union[montepy.input_parser.mcnp_input.Input, str] = None, + input: InitInput = None, number: int = None, ): self._components = [] diff --git a/montepy/data_inputs/thermal_scattering.py b/montepy/data_inputs/thermal_scattering.py index 11d6974c..f2879b51 100644 --- a/montepy/data_inputs/thermal_scattering.py +++ b/montepy/data_inputs/thermal_scattering.py @@ -1,10 +1,12 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. -from montepy.data_inputs.data_input import DataInputAbstract +from __future__ import annotations + +import montepy +from montepy.data_inputs.data_input import DataInputAbstract, InitInput from montepy.input_parser.thermal_parser import ThermalParser from montepy import mcnp_object from montepy.errors import * from montepy.utilities import * -import montepy class ThermalScatteringLaw(DataInputAbstract): @@ -21,14 +23,14 @@ class ThermalScatteringLaw(DataInputAbstract): * :manual62:`110` :param input: the Input object representing this data input - :type input: Input + :type input: Union[Input, str] :param material: the parent Material object that owns this :type material: Material """ _parser = ThermalParser() - def __init__(self, input="", material=None): + def __init__(self, input: InitInput = "", material: montepy.Material = None): self._old_number = self._generate_default_node(int, -1) self._parent_material = None self._scattering_laws = [] diff --git a/montepy/data_inputs/transform.py b/montepy/data_inputs/transform.py index ace3a396..9658c806 100644 --- a/montepy/data_inputs/transform.py +++ b/montepy/data_inputs/transform.py @@ -9,7 +9,7 @@ from montepy import mcnp_object from montepy.data_inputs import data_input from montepy.errors import * -from montepy.numbered_mcnp_object import Numbered_MCNP_Object +from montepy.numbered_mcnp_object import Numbered_MCNP_Object, InitInput from montepy.utilities import * @@ -29,7 +29,7 @@ class Transform(data_input.DataInputAbstract, Numbered_MCNP_Object): def __init__( self, - input: Union[montepy.input_parser.mcnp_input.input, str] = None, + input: InitInput = None, pass_through: bool = False, number: int = None, ): diff --git a/montepy/data_inputs/universe_input.py b/montepy/data_inputs/universe_input.py index d22c41cc..923b59c6 100644 --- a/montepy/data_inputs/universe_input.py +++ b/montepy/data_inputs/universe_input.py @@ -1,6 +1,6 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. import itertools -from montepy.data_inputs.cell_modifier import CellModifierInput +from montepy.data_inputs.cell_modifier import CellModifierInput, InitInput from montepy.errors import * from montepy.constants import DEFAULT_VERSION from montepy.input_parser.mcnp_input import Jump @@ -16,7 +16,7 @@ class UniverseInput(CellModifierInput): and data blocks. :param input: the Input object representing this data input - :type input: Input + :type input: Union[Input, str] :param in_cell_block: if this card came from the cell block of an input file. :type in_cell_block: bool :param key: the key from the key-value pair in a cell @@ -25,7 +25,13 @@ class UniverseInput(CellModifierInput): :type value: SyntaxNode """ - def __init__(self, input=None, in_cell_block=False, key=None, value=None): + def __init__( + self, + input: InitInput = None, + in_cell_block: bool = False, + key: str = None, + value: syntax_node.SyntaxNode = None, + ): self._universe = None self._old_numbers = [] self._old_number = self._generate_default_node(int, Jump()) diff --git a/montepy/mcnp_object.py b/montepy/mcnp_object.py index c45d7201..59d16d86 100644 --- a/montepy/mcnp_object.py +++ b/montepy/mcnp_object.py @@ -26,6 +26,8 @@ ) import montepy +InitInput = Union[montepy.input_parser.mcnp_input.Input, str] + class _ExceptionContextAdder(ABCMeta): """ @@ -108,7 +110,7 @@ class MCNP_Object(ABC, metaclass=_ExceptionContextAdder): def __init__( self, - input: Union[montepy.input_parser.mcnp_input.Input, str], + input: InitInput, parser: montepy.input_parser.parser_base.MCNP_Parser, ): try: diff --git a/montepy/numbered_mcnp_object.py b/montepy/numbered_mcnp_object.py index 6b536ee1..31c14d82 100644 --- a/montepy/numbered_mcnp_object.py +++ b/montepy/numbered_mcnp_object.py @@ -7,7 +7,7 @@ from montepy.errors import NumberConflictError -from montepy.mcnp_object import MCNP_Object +from montepy.mcnp_object import MCNP_Object, InitInput import montepy from montepy.utilities import * @@ -51,7 +51,7 @@ class Numbered_MCNP_Object(MCNP_Object): def __init__( self, - input: Union[montepy.input_parser.mcnp_input.Input, str], + input: InitInput, parser: montepy.input_parser.parser_base.MCNP_Parser, number: int = None, ): diff --git a/montepy/surfaces/axis_plane.py b/montepy/surfaces/axis_plane.py index 811a8ad7..5c9edb10 100644 --- a/montepy/surfaces/axis_plane.py +++ b/montepy/surfaces/axis_plane.py @@ -1,6 +1,7 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. + from .surface_type import SurfaceType -from .surface import Surface +from .surface import Surface, InitInput from montepy.errors import * from montepy.utilities import * @@ -21,7 +22,7 @@ class AxisPlane(Surface): COORDINATE = {SurfaceType.PX: "x", SurfaceType.PY: "y", SurfaceType.PZ: "z"} - def __init__(self, input=None, number: int = None): + def __init__(self, input: InitInput = None, number: int = None): self._location = self._generate_default_node(float, None) super().__init__(input, number) ST = SurfaceType diff --git a/montepy/surfaces/cylinder_on_axis.py b/montepy/surfaces/cylinder_on_axis.py index 78174d93..93d99f65 100644 --- a/montepy/surfaces/cylinder_on_axis.py +++ b/montepy/surfaces/cylinder_on_axis.py @@ -1,6 +1,6 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. from .surface_type import SurfaceType -from .surface import Surface +from .surface import Surface, InitInput from montepy.errors import * from montepy.utilities import * @@ -25,7 +25,7 @@ class CylinderOnAxis(Surface): :type number: int """ - def __init__(self, input=None, number: int = None): + def __init__(self, input: InitInput = None, number: int = None): self._radius = self._generate_default_node(float, None) super().__init__(input, number) ST = SurfaceType diff --git a/montepy/surfaces/cylinder_par_axis.py b/montepy/surfaces/cylinder_par_axis.py index a99302a5..3ada7c58 100644 --- a/montepy/surfaces/cylinder_par_axis.py +++ b/montepy/surfaces/cylinder_par_axis.py @@ -1,6 +1,6 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. from .surface_type import SurfaceType -from .surface import Surface +from .surface import Surface, InitInput from montepy.errors import * from montepy.utilities import * @@ -32,7 +32,7 @@ class CylinderParAxis(Surface): """Which coordinate is what value for each cylinder type. """ - def __init__(self, input=None, number: int = None): + def __init__(self, input: InitInput = None, number: int = None): self._coordinates = [ self._generate_default_node(float, None), self._generate_default_node(float, None), diff --git a/montepy/surfaces/general_plane.py b/montepy/surfaces/general_plane.py index 7b35c650..224ea782 100644 --- a/montepy/surfaces/general_plane.py +++ b/montepy/surfaces/general_plane.py @@ -4,7 +4,7 @@ import montepy from montepy.errors import * from montepy.surfaces.surface_type import SurfaceType -from montepy.surfaces.surface import Surface +from montepy.surfaces.surface import Surface, InitInput class GeneralPlane(Surface): @@ -25,7 +25,7 @@ class GeneralPlane(Surface): def __init__( self, - input: Union[montepy.input_parser.mcnp_input.Input, str] = None, + input: InitInput = None, number: int = None, ): super().__init__(input, number) diff --git a/montepy/surfaces/surface.py b/montepy/surfaces/surface.py index 5a98fe09..856a0bb9 100644 --- a/montepy/surfaces/surface.py +++ b/montepy/surfaces/surface.py @@ -9,7 +9,7 @@ from montepy.data_inputs import transform from montepy.input_parser import syntax_node from montepy.input_parser.surface_parser import SurfaceParser -from montepy.numbered_mcnp_object import Numbered_MCNP_Object +from montepy.numbered_mcnp_object import Numbered_MCNP_Object, InitInput from montepy.surfaces import half_space from montepy.surfaces.surface_type import SurfaceType from montepy.utilities import * @@ -33,7 +33,7 @@ class Surface(Numbered_MCNP_Object): def __init__( self, - input: Union[montepy.input_parser.mcnp_input.input, str] = None, + input: InitInput = None, number: int = None, ): self._CHILD_OBJ_MAP = { diff --git a/montepy/surfaces/surface_builder.py b/montepy/surfaces/surface_builder.py index d72fa99d..d3b5e025 100644 --- a/montepy/surfaces/surface_builder.py +++ b/montepy/surfaces/surface_builder.py @@ -1,13 +1,13 @@ # Copyright 2024, Battelle Energy Alliance, LLC All Rights Reserved. from montepy.surfaces.axis_plane import AxisPlane -from montepy.surfaces.surface import Surface +from montepy.surfaces.surface import Surface, InitInput from montepy.surfaces.surface_type import SurfaceType from montepy.surfaces.cylinder_on_axis import CylinderOnAxis from montepy.surfaces.cylinder_par_axis import CylinderParAxis from montepy.surfaces.general_plane import GeneralPlane -def surface_builder(input): +def surface_builder(input: InitInput): """ Builds a Surface object for the type of Surface @@ -15,7 +15,7 @@ def surface_builder(input): The ``comments`` argument has been removed with the simpler init function. :param input: The Input object representing the input - :type input: Input + :type input: Union[Input, str] :returns: A Surface object properly parsed. If supported a sub-class of Surface will be given. :rtype: Surface """ From e855ca28d12d70184d48506d2f1c2b89293dc466 Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Fri, 13 Dec 2024 23:10:11 -0600 Subject: [PATCH 26/39] Updated typeerror with more guidance. --- montepy/mcnp_object.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/montepy/mcnp_object.py b/montepy/mcnp_object.py index 59d16d86..b52bec50 100644 --- a/montepy/mcnp_object.py +++ b/montepy/mcnp_object.py @@ -121,8 +121,8 @@ def __init__( self._parameters = ParametersNode() self._input = None if input: - if not isinstance(input, (montepy.input_parser.mcnp_input.Input, str)): - raise TypeError("input must be an Input") + if not isinstance(input, InitInput): + raise TypeError(f"input must be an Input or str. {input} given.") if isinstance(input, str): input = montepy.input_parser.mcnp_input.Input( input.split("\n"), self._BLOCK_TYPE From 09cf9f9f2fd3f1812698b4552e33cbbecde47c22 Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Sun, 15 Dec 2024 14:44:07 -0600 Subject: [PATCH 27/39] Py39 can't check isisntance of a Union type. --- montepy/mcnp_object.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/montepy/mcnp_object.py b/montepy/mcnp_object.py index b52bec50..82f9fb29 100644 --- a/montepy/mcnp_object.py +++ b/montepy/mcnp_object.py @@ -121,7 +121,7 @@ def __init__( self._parameters = ParametersNode() self._input = None if input: - if not isinstance(input, InitInput): + if not isinstance(input, (montepy.input_parser.mcnp_input.Input, str)): raise TypeError(f"input must be an Input or str. {input} given.") if isinstance(input, str): input = montepy.input_parser.mcnp_input.Input( From 736851a95563cc2927fb89599eadccb6e53536d3 Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Sun, 15 Dec 2024 14:55:45 -0600 Subject: [PATCH 28/39] Fixed typo with pyproject from merge. --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ae36d00a..04d9ab7c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,8 +54,8 @@ doc = [ "pydata_sphinx_theme", "sphinx-favicon", "sphinx-copybutton", - "sphinx_autodoc_typehints" - "sphinx-copybutton" + "sphinx_autodoc_typehints", + "sphinx-copybutton", ] format = ["black>=23.3.0"] build = [ From 9556f84ab80009c0b361dd6ab1f143bcc37b2955 Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Sat, 11 Jan 2025 13:51:20 -0600 Subject: [PATCH 29/39] Fixed circular import. --- montepy/mcnp_problem.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/montepy/mcnp_problem.py b/montepy/mcnp_problem.py index 3dd9a386..17e25dc7 100644 --- a/montepy/mcnp_problem.py +++ b/montepy/mcnp_problem.py @@ -19,7 +19,7 @@ from montepy.data_inputs import parse_data from montepy.input_parser import input_syntax_reader, block_type, mcnp_input from montepy.input_parser.input_file import MCNP_InputFile -from montepy.universes import Universes +from montepy.universes import Universe, Universes from montepy.transforms import Transforms import montepy @@ -40,7 +40,7 @@ class MCNP_Problem: surface.Surface: Surfaces, Material: Materials, transform.Transform: Transforms, - montepy.universe.Universe: Universes, + Universe: Universes, } def __init__(self, destination): From 7f18ee7453028b2829ea0f5e05fef6e1ed5cd79d Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Sat, 11 Jan 2025 13:52:17 -0600 Subject: [PATCH 30/39] Added append option to MCNP_Problem.parse. --- montepy/mcnp_problem.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/montepy/mcnp_problem.py b/montepy/mcnp_problem.py index 17e25dc7..7244c3ae 100644 --- a/montepy/mcnp_problem.py +++ b/montepy/mcnp_problem.py @@ -624,7 +624,7 @@ def __repr__(self): ret += "\n" return ret - def parse(self, input: str): + def parse(self, input: str, append: bool = True) -> montepy.mcnp_object.MCNP_Object: """ Parses the MCNP object given by the string, and links it adds it to this problem. @@ -644,6 +644,8 @@ def parse(self, input: str): :param input: the string describing the input. New lines are allowed but this does not need to meet MCNP line length rules. :type input: str + :param append: Whether to append this parsed object to this problem. + :type append: bool :returns: the parsed object. :rtype: MCNP_Object @@ -663,15 +665,18 @@ def parse(self, input: str): obj.link_to_problem(self) if isinstance(obj, montepy.Cell): obj.update_pointers(self.cells, self.materials, self.surfaces) - self.cells.append(obj) + if append: + self.cells.append(obj) elif isinstance(obj, montepy.surfaces.surface.Surface): obj.update_pointers(self.surfaces, self.data_inputs) - self.surfaces.append(obj) + if append: + self.surfaces.append(obj) else: obj.update_pointers(self.data_inputs) - self.data_inputs.append(obj) - if isinstance(obj, Material): - self._materials.append(obj, insert_in_data=False) - if isinstance(obj, transform.Transform): - self._transforms.append(obj, insert_in_data=False) + if append: + self.data_inputs.append(obj) + if isinstance(obj, Material): + self._materials.append(obj, insert_in_data=False) + if isinstance(obj, transform.Transform): + self._transforms.append(obj, insert_in_data=False) return obj From ffcb68d8fec2f8d8b570a6a0efffb0c7d1536036 Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Sat, 11 Jan 2025 13:52:36 -0600 Subject: [PATCH 31/39] Tested parse append. --- tests/test_integration.py | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/tests/test_integration.py b/tests/test_integration.py index 69eb2c96..278cd6d1 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -1194,18 +1194,20 @@ def test_read_write_cycle(file): def test_arbitrary_parse(simple_problem): - cell = simple_problem.parse("20 0 -1005") - assert cell in simple_problem.cells - assert cell.number == 20 - assert cell.surfaces[1005] in simple_problem.surfaces - surf = simple_problem.parse("5 SO 7.5") - assert surf in simple_problem.surfaces - assert surf.number == 5 - mat = simple_problem.parse("m123 1001.80c 1.0 8016.80c 2.0") - assert mat in simple_problem.materials - assert mat in simple_problem.data_inputs - assert mat.number == 123 - transform = simple_problem.parse("tr25 0 0 1") - assert transform in simple_problem.transforms - with pytest.raises(ParsingError): - simple_problem.parse("123 hello this is invalid") + simple_problem = simple_problem.clone() + for append in [False, True]: + cell = simple_problem.parse("20 0 -1005", append) + assert (cell in simple_problem.cells) == append + assert cell.number == 20 + assert cell.surfaces[1005] in simple_problem.surfaces + surf = simple_problem.parse("5 SO 7.5", append) + assert (surf in simple_problem.surfaces) == append + assert surf.number == 5 + mat = simple_problem.parse("m123 1001.80c 1.0 8016.80c 2.0", append) + assert (mat in simple_problem.materials) == append + assert (mat in simple_problem.data_inputs) == append + assert mat.number == 123 + transform = simple_problem.parse("tr25 0 0 1", append) + assert (transform in simple_problem.transforms) == append + with pytest.raises(ParsingError): + simple_problem.parse("123 hello this is invalid") From 6b9baf71d53846a5d30b10869ad9a02bb891061b Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Sat, 11 Jan 2025 15:25:48 -0600 Subject: [PATCH 32/39] Promoted parsing functions to be top level functions. --- montepy/__init__.py | 1 + montepy/surfaces/__init__.py | 3 +++ 2 files changed, 4 insertions(+) diff --git a/montepy/__init__.py b/montepy/__init__.py index 9ce09352..591939b9 100644 --- a/montepy/__init__.py +++ b/montepy/__init__.py @@ -18,6 +18,7 @@ from montepy.data_inputs.transform import Transform from montepy.data_inputs.nuclide import Library, Nuclide from montepy.data_inputs.element import Element +from montepy.data_inputs.thermal_scattering import ThermalScatteringLaw # geometry from montepy.geometry_operators import Operator diff --git a/montepy/surfaces/__init__.py b/montepy/surfaces/__init__.py index e2e29558..47a2cc3a 100644 --- a/montepy/surfaces/__init__.py +++ b/montepy/surfaces/__init__.py @@ -13,3 +13,6 @@ from .half_space import HalfSpace, UnitHalfSpace from .surface import Surface from .surface_type import SurfaceType + +# promote functions +from .surface_builder import surface_builder as parse_surface From 565d19cb78c4467caba05c9c82e0b62d245b5c85 Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Sat, 11 Jan 2025 15:26:12 -0600 Subject: [PATCH 33/39] Made parse_surface function name more pythonic. --- montepy/surfaces/surface_builder.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/montepy/surfaces/surface_builder.py b/montepy/surfaces/surface_builder.py index d3b5e025..e8bbc1eb 100644 --- a/montepy/surfaces/surface_builder.py +++ b/montepy/surfaces/surface_builder.py @@ -7,7 +7,7 @@ from montepy.surfaces.general_plane import GeneralPlane -def surface_builder(input: InitInput): +def parse_surface(input: InitInput): """ Builds a Surface object for the type of Surface @@ -32,3 +32,17 @@ def surface_builder(input: InitInput): return GeneralPlane(input) else: return buffer_surface + + +surface_builder = parse_surface +""" +Alias for :func:`parse_surface`. + +:deprecated: 1.0.0 + Renamed to be :func:`parse_surface` to be more pythonic. + +:param input: The Input object representing the input +:type input: Union[Input, str] +:returns: A Surface object properly parsed. If supported a sub-class of Surface will be given. +:rtype: Surface +""" From e76db62524a894a866a081472357c3367cfbe940 Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Sat, 11 Jan 2025 15:28:54 -0600 Subject: [PATCH 34/39] hid pretty_str as it's not ready yet. --- montepy/input_parser/syntax_node.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/montepy/input_parser/syntax_node.py b/montepy/input_parser/syntax_node.py index 8ed8e139..6aceb8c0 100644 --- a/montepy/input_parser/syntax_node.py +++ b/montepy/input_parser/syntax_node.py @@ -196,7 +196,7 @@ def flatten(self): ret += node.flatten() return ret - def pretty_str(self): + def _pretty_str(self): INDENT = 2 if not self.nodes: return f"" @@ -324,7 +324,7 @@ def flatten(self): ret += node.flatten() return ret - def pretty_str(self): + def _pretty_str(self): INDENT = 2 ret = f"" ) - def pretty_str(self): + def _pretty_str(self): INDENT = 2 ret = f"" - def pretty_str(self): + def _pretty_str(self): return str(self) def __repr__(self): @@ -1859,7 +1859,7 @@ def format(self): def __repr__(self): return f"(Materials: {self.nodes})" - def pretty_str(self): + def _pretty_str(self): INDENT = 2 ret = f" Date: Sat, 11 Jan 2025 15:30:20 -0600 Subject: [PATCH 35/39] Added demo of parse functions. --- doc/source/starting.rst | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/doc/source/starting.rst b/doc/source/starting.rst index 71064c5e..11ce42bb 100644 --- a/doc/source/starting.rst +++ b/doc/source/starting.rst @@ -386,6 +386,38 @@ First all :class:`~montepy.mcnp_object.MCNP_Object` constructors can take a stri 1 >>> cell.importance[montepy.Particle.NEUTRON] 1.0 + >>> # surfaces + >>> surf = montepy.AxisPlane("5 PZ 10") + >>> surf.number + 5 + >>> surf.location + 10.0 + >>> # materials + >>> mat = montepy.Material("M1 1001.80c 2 8016.80c 1") + >>> mat.number + 1 + >>> thermal_scat = montepy.ThermalScatteringLaw("MT1 lwrt.40t") + >>> thermal_scat.old_number + 1 + >>> #object linking hasn't occuring + >>> print(thermal_scat.parent_material) + None + +For data inputs and surfaces there are some helper functions that help parse all objects of that type, +and return the appropriate object. +For surfaces this is: :func:`~montepy.surfaces.surface_builder.parse_surface`, +and for data inputs this is :func:`~montepy.data_inputs.data_parser.parse_data`. + +.. doctest:: + >>> surf = montepy.parse_surface("1 cz 5.0") + >>> type(surf) + foo + >>> surf.radius + 5.0 + >>> mat = montepy.parse_data("m1 1001.80c 1") + >>> type(mat) + foo + This object is still unlinked from other objects, and won't be kept with a problem. So there is also :func:`~montepy.mcnp_problem.MCNP_Problem.parse`. From 843780d5ea23e9f767bd9e9502ddd4b2ac7cc8ab Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Sat, 11 Jan 2025 15:32:29 -0600 Subject: [PATCH 36/39] Added demo of append option. --- doc/source/starting.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/source/starting.rst b/doc/source/starting.rst index 11ce42bb..f0873b28 100644 --- a/doc/source/starting.rst +++ b/doc/source/starting.rst @@ -424,13 +424,15 @@ So there is also :func:`~montepy.mcnp_problem.MCNP_Problem.parse`. This takes a string, and then creates the MCNP object, links it to the problem, links it to its other objects (e.g., surfaces, materials, etc.), -and appends it to necessary collections: +and appends it to necessary collections (if requested): .. testcode:: cell = problem.parse("123 0 -1005") assert cell in problem.cells assert cell.surfaces[1005] is problem.surfaces[1005] + cell = problem.parse("124 0 -1005", append=False) + assert cell not in problem.cells Surfaces -------- From 8b184dec2f0c5aa62e04823cb4a7f78fec915e75 Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Sat, 11 Jan 2025 15:37:51 -0600 Subject: [PATCH 37/39] Updated tests for pretty_str change. --- montepy/input_parser/syntax_node.py | 13 +++++-------- tests/test_syntax_parsing.py | 10 +++++----- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/montepy/input_parser/syntax_node.py b/montepy/input_parser/syntax_node.py index 6aceb8c0..7abcb6bc 100644 --- a/montepy/input_parser/syntax_node.py +++ b/montepy/input_parser/syntax_node.py @@ -202,7 +202,7 @@ def _pretty_str(self): return f"" ret = f" Date: Sat, 11 Jan 2025 15:45:33 -0600 Subject: [PATCH 38/39] Updated references to deprecated surface_builder. --- montepy/__init__.py | 1 + montepy/mcnp_problem.py | 6 +++--- montepy/surfaces/__init__.py | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/montepy/__init__.py b/montepy/__init__.py index 591939b9..129a6d62 100644 --- a/montepy/__init__.py +++ b/montepy/__init__.py @@ -19,6 +19,7 @@ from montepy.data_inputs.nuclide import Library, Nuclide from montepy.data_inputs.element import Element from montepy.data_inputs.thermal_scattering import ThermalScatteringLaw +from montepy.data_inputs.data_parser import parse_data # geometry from montepy.geometry_operators import Operator diff --git a/montepy/mcnp_problem.py b/montepy/mcnp_problem.py index 7244c3ae..247a199a 100644 --- a/montepy/mcnp_problem.py +++ b/montepy/mcnp_problem.py @@ -339,7 +339,7 @@ def parse_input(self, check_input=False, replace=True): OBJ_MATCHER = { block_type.BlockType.CELL: (Cell, self._cells), block_type.BlockType.SURFACE: ( - surface_builder.surface_builder, + surface_builder.parse_surface, self._surfaces, ), block_type.BlockType.DATA: (parse_data, self._data_inputs), @@ -655,10 +655,10 @@ def parse(self, input: str, append: bool = True) -> montepy.mcnp_object.MCNP_Obj :raises NumberConflictError: if the object's number is already taken """ try: - obj = montepy.data_inputs.data_parser.parse_data(input) + obj = montepy.parse_data(input) except ParsingError: try: - obj = montepy.surfaces.surface_builder.Surface(input) + obj = montepy.parse_surface(input) except ParsingError: obj = montepy.Cell(input) # let final parsing error bubble up diff --git a/montepy/surfaces/__init__.py b/montepy/surfaces/__init__.py index 47a2cc3a..872f4aac 100644 --- a/montepy/surfaces/__init__.py +++ b/montepy/surfaces/__init__.py @@ -15,4 +15,4 @@ from .surface_type import SurfaceType # promote functions -from .surface_builder import surface_builder as parse_surface +from .surface_builder import parse_surface From 4838a8603f0cad308eff8b7b6d33f41b1766877b Mon Sep 17 00:00:00 2001 From: Micah Gale Date: Sat, 11 Jan 2025 15:56:52 -0600 Subject: [PATCH 39/39] Removed all version change markers for 0.2.0 I figure that 0.2.0 was really the second major release, so marking the changes from the first to second major release now that we are on the third is no longer necessary. --- montepy/cell.py | 3 -- montepy/data_inputs/cell_modifier.py | 6 ---- montepy/data_inputs/data_parser.py | 3 -- montepy/input_parser/cell_parser.py | 3 -- montepy/input_parser/data_parser.py | 6 ---- montepy/input_parser/input_syntax_reader.py | 6 ---- montepy/input_parser/mcnp_input.py | 7 ----- montepy/input_parser/parser_base.py | 9 ------ montepy/input_parser/read_parser.py | 3 -- montepy/input_parser/shortcuts.py | 3 -- montepy/input_parser/surface_parser.py | 3 -- montepy/input_parser/syntax_node.py | 33 --------------------- montepy/input_parser/tally_parser.py | 2 -- montepy/input_parser/thermal_parser.py | 3 -- montepy/input_parser/tokens.py | 22 -------------- montepy/mcnp_object.py | 11 ------- montepy/surfaces/half_space.py | 6 ---- montepy/surfaces/surface_builder.py | 3 -- 18 files changed, 132 deletions(-) diff --git a/montepy/cell.py b/montepy/cell.py index 356b45e7..7ad0e0b3 100644 --- a/montepy/cell.py +++ b/montepy/cell.py @@ -381,9 +381,6 @@ def geometry(self): """ The Geometry for this problem. - .. versionadded:: 0.2.0 - Added with the new ability to represent true CSG geometry logic. - The HalfSpace tree that is able to represent this cell's geometry. MontePy's geometry is based upon dividers, which includes both Surfaces, and cells. A half-space is created by choosing one side of the divider. diff --git a/montepy/data_inputs/cell_modifier.py b/montepy/data_inputs/cell_modifier.py index f6d2ad89..6ddf90c0 100644 --- a/montepy/data_inputs/cell_modifier.py +++ b/montepy/data_inputs/cell_modifier.py @@ -184,8 +184,6 @@ def _tree_value(self): """ The ValueNode that holds the information for this instance, that should be included in the data block. - .. versionadded:: 0.2.0 - :returns: The ValueNode to update the data-block syntax tree with. :rtype: ValueNode """ @@ -197,8 +195,6 @@ def _collect_new_values(self): This will be a list in the same order as :func:`montepy.mcnp_problem.MCNP_Problem.cells`. - .. versionadded:: 0.2.0 - :returns: a list of the ValueNodes to update the data block syntax tree with :rtype: list """ @@ -213,8 +209,6 @@ def _collect_new_values(self): def _update_cell_values(self): """ Updates values in the syntax tree when in the cell block. - - .. versionadded:: 0.2.0 """ pass diff --git a/montepy/data_inputs/data_parser.py b/montepy/data_inputs/data_parser.py index 3d456f7c..32b85181 100644 --- a/montepy/data_inputs/data_parser.py +++ b/montepy/data_inputs/data_parser.py @@ -32,9 +32,6 @@ def parse_data(input: montepy.mcnp_object.InitInput): """ Parses the data input as the appropriate object if it is supported. - .. versionchanged:: 0.2.0 - Removed the ``comment`` parameter, as it's in the syntax tree directly now. - :param input: the Input object for this Data input :type input: Union[Input, str] :return: the parsed DataInput object diff --git a/montepy/input_parser/cell_parser.py b/montepy/input_parser/cell_parser.py index 65d347e6..f9b4ed5c 100644 --- a/montepy/input_parser/cell_parser.py +++ b/montepy/input_parser/cell_parser.py @@ -8,9 +8,6 @@ class CellParser(MCNP_Parser): """ The parser for parsing a Cell input. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :returns: a syntax tree of the cell. :rtype: SyntaxNode """ diff --git a/montepy/input_parser/data_parser.py b/montepy/input_parser/data_parser.py index 497e8e7b..25fa98f7 100644 --- a/montepy/input_parser/data_parser.py +++ b/montepy/input_parser/data_parser.py @@ -9,9 +9,6 @@ class DataParser(MCNP_Parser): """ A parser for almost all data inputs. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :returns: a syntax tree for the data input. :rtype: SyntaxNode """ @@ -148,9 +145,6 @@ class ClassifierParser(DataParser): """ A parser for parsing the first word or classifier of a data input. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :returns: the classifier of the data input. :rtype: ClassifierNode """ diff --git a/montepy/input_parser/input_syntax_reader.py b/montepy/input_parser/input_syntax_reader.py index 86a7a129..086ca917 100644 --- a/montepy/input_parser/input_syntax_reader.py +++ b/montepy/input_parser/input_syntax_reader.py @@ -59,9 +59,6 @@ def read_front_matters(fh, mcnp_version): .. warning:: This function will not close the file handle. - .. versionchanged:: 0.2.0 - ``fh`` was changed to be an MCNP_InputFile to hold more information. - :param fh: The file handle of the input file. :type fh: MCNP_InputFile :param mcnp_version: The version of MCNP that the input is intended for. @@ -105,9 +102,6 @@ def read_data(fh, mcnp_version, block_type=None, recursion=False): .. warning:: This function will not close the file handle. - .. versionchanged:: 0.2.0 - ``file_wrapper`` was added to better track which file is being read. - :param fh: The file handle of the input file. :type fh: MCNP_InputFile :param mcnp_version: The version of MCNP that the input is intended for. diff --git a/montepy/input_parser/mcnp_input.py b/montepy/input_parser/mcnp_input.py index 6f6fb9f4..f3380a1a 100644 --- a/montepy/input_parser/mcnp_input.py +++ b/montepy/input_parser/mcnp_input.py @@ -69,9 +69,6 @@ class ParsingNode(ABC): """ Object to represent a single coherent MCNP input, such as an input. - .. versionadded:: 0.2.0 - This was added as part of the parser rework. - :param input_lines: the lines read straight from the input file. :type input_lines: list """ @@ -114,10 +111,6 @@ class Input(ParsingNode): """ Represents a single MCNP "Input" e.g. a single cell definition. - .. versionadded:: 0.2.0 - This was added as part of the parser rework, and rename. - This was a replacement for :class:`Card`. - :param input_lines: the lines read straight from the input file. :type input_lines: list :param block_type: An enum showing which of three MCNP blocks this was inside of. diff --git a/montepy/input_parser/parser_base.py b/montepy/input_parser/parser_base.py index d725cc24..471e2626 100644 --- a/montepy/input_parser/parser_base.py +++ b/montepy/input_parser/parser_base.py @@ -12,9 +12,6 @@ class MetaBuilder(sly.yacc.ParserMeta): Custom MetaClass for allowing subclassing of MCNP_Parser. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - Note: overloading functions is not allowed. """ @@ -57,9 +54,6 @@ def _flatten_rules(classname, basis, attributes): class SLY_Supressor: """ This is a fake logger meant to mostly make warnings dissapear. - - .. versionadded:: 0.2.0 - This was added with the major parser rework. """ def __init__(self): @@ -111,9 +105,6 @@ def __len__(self): class MCNP_Parser(Parser, metaclass=MetaBuilder): """ Base class for all MCNP parsers that provides basics. - - .. versionadded:: 0.2.0 - This was added with the major parser rework. """ # Remove this if trying to see issues with parser diff --git a/montepy/input_parser/read_parser.py b/montepy/input_parser/read_parser.py index ab46c302..a106f7f9 100644 --- a/montepy/input_parser/read_parser.py +++ b/montepy/input_parser/read_parser.py @@ -6,9 +6,6 @@ class ReadParser(MCNP_Parser): """ A parser for handling "read" inputs. - - .. versionadded:: 0.2.0 - This was added with the major parser rework. """ debugfile = None diff --git a/montepy/input_parser/shortcuts.py b/montepy/input_parser/shortcuts.py index 14237101..f6aabe48 100644 --- a/montepy/input_parser/shortcuts.py +++ b/montepy/input_parser/shortcuts.py @@ -5,9 +5,6 @@ class Shortcuts(Enum): """ Enumeration of the possible MCNP shortcuts. - - .. versionadded:: 0.2.0 - This was added with the major parser rework. """ REPEAT = "r" diff --git a/montepy/input_parser/surface_parser.py b/montepy/input_parser/surface_parser.py index f4fc7d3c..fd6f8414 100644 --- a/montepy/input_parser/surface_parser.py +++ b/montepy/input_parser/surface_parser.py @@ -8,9 +8,6 @@ class SurfaceParser(MCNP_Parser): """ A parser for MCNP surfaces. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :rtype: SyntaxNode """ diff --git a/montepy/input_parser/syntax_node.py b/montepy/input_parser/syntax_node.py index 7abcb6bc..af8d6c78 100644 --- a/montepy/input_parser/syntax_node.py +++ b/montepy/input_parser/syntax_node.py @@ -25,9 +25,6 @@ class SyntaxNodeBase(ABC): A syntax node is any component of the syntax tree for a parsed input. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :param name: a name for labeling this node. :type name: str """ @@ -225,9 +222,6 @@ class SyntaxNode(SyntaxNodeBase): if key in syntax_node: pass - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :param name: a name for labeling this node. :type name: str :param parse_dict: the dictionary of the syntax tree nodes. @@ -341,9 +335,6 @@ class GeometryTree(SyntaxNodeBase): """ A syntax tree that is a binary tree for representing CSG geometry logic. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - .. versionchanged:: 0.4.1 Added left/right_short_type @@ -601,9 +592,6 @@ class PaddingNode(SyntaxNodeBase): """ A syntax tree node to represent a collection of sequential padding elements. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :param token: The first padding token for this node. :type token: str :param is_comment: If the token provided is a comment. @@ -789,9 +777,6 @@ class CommentNode(SyntaxNodeBase): """ Object to represent a comment in an MCNP problem. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :param input: the token from the lexer :type input: Token """ @@ -909,9 +894,6 @@ class ValueNode(SyntaxNodeBase): This stores the original input token, the current value, and the possible associated padding. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :param token: the original token for the ValueNode. :type token: str :param token_type: the type for the ValueNode. @@ -1418,9 +1400,6 @@ class ParticleNode(SyntaxNodeBase): """ A node to hold particles information in a :class:`ClassifierNode`. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :param name: the name for the node. :type name: str :param token: the original token from parsing @@ -1554,9 +1533,6 @@ class ListNode(SyntaxNodeBase): """ A node to represent a list of values. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :param name: the name of this node. :type name: str """ @@ -1902,9 +1878,6 @@ class ShortcutNode(ListNode): This takes the shortcut tokens, and expands it into their "virtual" values. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :param p: the parsing object to parse. :type p: sly.yacc.YaccProduction :param short_type: the type of the shortcut. @@ -2361,9 +2334,6 @@ class ClassifierNode(SyntaxNodeBase): """ A node to represent the classifier for a :class:`montepy.data_input.DataInput` - .. versionadded:: 0.2.0 - This was added with the major parser rework. - e.g., represents ``M4``, ``F104:n,p``, ``IMP:n,e``. """ @@ -2531,9 +2501,6 @@ class ParametersNode(SyntaxNodeBase): This behaves like a dictionary and is accessible by their key* - .. versionadded:: 0.2.0 - This was added with the major parser rework. - .. Note:: How to access values. diff --git a/montepy/input_parser/tally_parser.py b/montepy/input_parser/tally_parser.py index 00867dee..7c50b07f 100644 --- a/montepy/input_parser/tally_parser.py +++ b/montepy/input_parser/tally_parser.py @@ -7,8 +7,6 @@ class TallyParser(DataParser): """ A barebone parser for parsing tallies before they are fully implemented. - .. versionadded:: 0.2.0 - :returns: a syntax tree for the data input. :rtype: SyntaxNode """ diff --git a/montepy/input_parser/thermal_parser.py b/montepy/input_parser/thermal_parser.py index c668c6d7..4f2e41e0 100644 --- a/montepy/input_parser/thermal_parser.py +++ b/montepy/input_parser/thermal_parser.py @@ -7,9 +7,6 @@ class ThermalParser(DataParser): """ A parser for thermal scattering law inputs. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - :rtype: SyntaxNode """ diff --git a/montepy/input_parser/tokens.py b/montepy/input_parser/tokens.py index a62856c2..5a765f61 100644 --- a/montepy/input_parser/tokens.py +++ b/montepy/input_parser/tokens.py @@ -11,8 +11,6 @@ class MCNP_Lexer(Lexer): Provides ~90% of the tokens definition. - .. versionadded:: 0.2.0 - This was added with the major parser rework. """ tokens = { @@ -324,10 +322,6 @@ def find_column(text, token): Uses 0-indexing. - .. versionadded:: 0.2.0 - This was added with the major parser rework. - - :param text: the text being lexed. :type text: str :param token: the token currently being processed @@ -343,10 +337,6 @@ def find_column(text, token): class ParticleLexer(MCNP_Lexer): """ A lexer for lexing an input that has particles in it. - - .. versionadded:: 0.2.0 - This was added with the major parser rework. - """ tokens = { @@ -426,10 +416,6 @@ def TEXT(self, t): class CellLexer(ParticleLexer): """ A lexer for cell inputs that allows particles. - - .. versionadded:: 0.2.0 - This was added with the major parser rework. - """ tokens = { @@ -457,10 +443,6 @@ class CellLexer(ParticleLexer): class DataLexer(ParticleLexer): """ A lexer for data inputs. - - .. versionadded:: 0.2.0 - This was added with the major parser rework. - """ tokens = { @@ -500,10 +482,6 @@ class SurfaceLexer(MCNP_Lexer): The main difference is that ``p`` will be interpreted as a plane, and not a photon. - - .. versionadded:: 0.2.0 - This was added with the major parser rework. - """ tokens = { diff --git a/montepy/mcnp_object.py b/montepy/mcnp_object.py index 82f9fb29..54e15f63 100644 --- a/montepy/mcnp_object.py +++ b/montepy/mcnp_object.py @@ -68,7 +68,6 @@ def __new__(meta, classname, bases, attributes): """ This will replace all properties and callable attributes with wrapped versions. - """ new_attrs = {} for key, value in attributes.items(): @@ -98,10 +97,6 @@ class MCNP_Object(ABC, metaclass=_ExceptionContextAdder): """ Abstract class for semantic representations of MCNP inputs. - .. versionchanged:: 0.2.0 - Generally significant changes for parser rework. - For init removed ``comments``, and added ``parser`` as arguments. - :param input: The Input syntax object this will wrap and parse. :type input: Union[Input, str] :param parser: The parser object to parse the input with. @@ -177,8 +172,6 @@ def _generate_default_node(value_type: type, default, padding: str = " "): None is generally a safe default value to provide. - .. versionadded:: 0.2.0 - :param value_type: the data type for the ValueNode. :type value_type: Class :param default: the default value to provide (type needs to agree with value_type) @@ -219,8 +212,6 @@ def _update_values(self): The most common need is to update a value based on the number for an object pointed at, e.g., the material number in a cell definition. - .. versionadded:: 0.2.0 - """ pass @@ -258,8 +249,6 @@ def leading_comments(self) -> list[PaddingNode]: """ Any comments that come before the beginning of the input proper. - .. versionadded:: 0.2.0 - :returns: the leading comments. :rtype: list """ diff --git a/montepy/surfaces/half_space.py b/montepy/surfaces/half_space.py index e571b6d1..68095684 100644 --- a/montepy/surfaces/half_space.py +++ b/montepy/surfaces/half_space.py @@ -16,9 +16,6 @@ class HalfSpace: """ Class representing a geometry half_space. - .. versionadded:: 0.2.0 - This was added as the core of the rework to how MCNP geometries are implemented. - The term `half-spaces `_ in MontePy is used very loosely, and is not mathematically rigorous. In MontePy a divider is a something that splits a space (R\\ :sup:`3` ) into two half-spaces. At the simplest this would @@ -480,9 +477,6 @@ class UnitHalfSpace(HalfSpace): """ The leaf node for the HalfSpace tree. - .. versionadded:: 0.2.0 - This was added as the core of the rework to how MCNP geometries are implemented. - This can only be used as leaves and represents one half_space of a a divider. The easiest way to generate one is with the divider with unary operators. diff --git a/montepy/surfaces/surface_builder.py b/montepy/surfaces/surface_builder.py index e8bbc1eb..a86cd139 100644 --- a/montepy/surfaces/surface_builder.py +++ b/montepy/surfaces/surface_builder.py @@ -11,9 +11,6 @@ def parse_surface(input: InitInput): """ Builds a Surface object for the type of Surface - .. versionchanged:: 0.2.0 - The ``comments`` argument has been removed with the simpler init function. - :param input: The Input object representing the input :type input: Union[Input, str] :returns: A Surface object properly parsed. If supported a sub-class of Surface will be given.