diff --git a/nexus_constructor/json/load_from_json.py b/nexus_constructor/json/load_from_json.py index c3124354d..d32d73660 100644 --- a/nexus_constructor/json/load_from_json.py +++ b/nexus_constructor/json/load_from_json.py @@ -1,6 +1,6 @@ import json from json import JSONDecodeError -from typing import Dict, Optional, Tuple, Union +from typing import Dict, Optional, Tuple, Union, cast from nexus_constructor.common_attrs import ( NX_CLASSES_WITH_PLACEHOLDERS, @@ -71,7 +71,7 @@ class JSONReader: def __init__(self): - self.entry_node: Group = None + self.entry_node: Group = cast(Group, None) self.model = Model() self.sample_name: str = "" self.warnings = JsonWarningsContainer() @@ -114,8 +114,11 @@ def _set_components_depends_on(self): except KeyError: self.warnings.append( TransformDependencyMissing( - f"Component {component_name} depends on {depends_on_id.transform_name} in component " - f"{depends_on_id.component_name}, but that transform was not successfully loaded from the JSON" + f"Component {component_name} depends on " + + (depends_on_id.transform_name if depends_on_id is not None else "Unknown") + + " in component " + + (depends_on_id.component_name if depends_on_id is not None else "Unknown") + + ", but that transform was not successfully loaded from the JSON" ) ) @@ -139,9 +142,11 @@ def _set_transforms_depends_on(self): except KeyError: self.warnings.append( TransformDependencyMissing( - f"Transformation {transform_id.transform_name} in component {transform_id.component_name} " - f"depends on {depends_on_id.transform_name} in component {depends_on_id.component_name}, " - f"but that transform was not successfully loaded from the JSON" + f"Transformation {transform_id.transform_name} in component {transform_id.component_name} depends on " + + (depends_on_id.transform_name if depends_on_id is not None else "Unknown") + + " in component " + + (depends_on_id.component_name if depends_on_id is not None else "Unknown") + + ", but that transform was not successfully loaded from the JSON" ) ) @@ -199,14 +204,14 @@ def load_model_from_json(self, filename: str) -> bool: return self._load_from_json_dict(json_dict) def _load_from_json_dict(self, json_dict: Dict) -> bool: - self.entry_node = self._read_json_object(json_dict[CommonKeys.CHILDREN][0]) + self.entry_node = cast(Group, self._read_json_object(json_dict[CommonKeys.CHILDREN][0])) self.model.entry.attributes = self.entry_node.attributes for child in self.entry_node.children: if isinstance(child, (Dataset, Link, FileWriter, Group)): self.model.entry[child.name] = child else: self.model.entry.children.append(child) - child.parent_node = self.model.entry + child.parent_node = cast(str, self.model.entry) self._set_transforms_depends_on() self._set_components_depends_on() self._append_transformations_to_nx_group() @@ -231,16 +236,16 @@ def _replace_placeholder(self, placeholder: str): } return None - def _read_json_object(self, json_object: Dict, parent_node: Group = None): + def _read_json_object(self, json_object: Dict, parent_node: Group = cast(Group, None)): """ Tries to create a component based on the contents of the JSON file. :param json_object: A component from the JSON dictionary. :param parent_name: The name of the parent object. Used for warning messages if something goes wrong. """ - nexus_object: Union[Group, FileWriterModule] = None + nexus_object: Union[Group, FileWriterModule] = cast(Group, None) use_placeholder = False if isinstance(json_object, str) and json_object in PLACEHOLDER_WITH_NX_CLASSES: - json_object = self._replace_placeholder(json_object) + json_object = cast(Dict, self._replace_placeholder(json_object)) if not json_object: return use_placeholder = True @@ -253,13 +258,13 @@ def _read_json_object(self, json_object: Dict, parent_node: Group = None): except KeyError: self._add_object_warning(CommonKeys.NAME, parent_node) return None - nx_class = _find_nx_class(json_object.get(CommonKeys.ATTRIBUTES)) + nx_class = _find_nx_class(cast(list, json_object.get(CommonKeys.ATTRIBUTES))) if nx_class == SAMPLE_CLASS_NAME: self.sample_name = name if not self._validate_nx_class(name, nx_class): self._add_object_warning(f"valid Nexus class {nx_class}", parent_node) if nx_class in COMPONENT_TYPES: - nexus_object = Component(name=name, parent_node=parent_node) + nexus_object = Component(name=name, parent_node=cast(str, parent_node)) children_dict = json_object[CommonKeys.CHILDREN] self._add_transform_and_shape_to_component(nexus_object, children_dict) self.model.append_component(nexus_object) @@ -282,12 +287,12 @@ def _read_json_object(self, json_object: Dict, parent_node: Group = None): ) and json_object[NodeType.CONFIG][ CommonKeys.NAME ] == CommonAttrs.DEPENDS_ON: - nexus_object = None + nexus_object = cast(Group, None) elif module_type in [x.value for x in WriterModules]: nexus_object = create_fw_module_object( module_type, json_object[NodeType.CONFIG], parent_node ) - nexus_object.parent_node = parent_node + nexus_object.parent_node = cast(str, parent_node) else: self._add_object_warning("valid module type", parent_node) return None @@ -376,7 +381,7 @@ def _add_transform_and_shape_to_component(self, component, children_dict): ) transformation_reader.add_transformations_to_component() self.warnings += transformation_reader.warnings - depends_on = _find_depends_on_path(children_dict, component.name) + depends_on: str = cast(str, _find_depends_on_path(children_dict, component.name)) if depends_on not in [".", "", None]: if depends_on[0] != "/": # we are always in the NXtransformations group but the path could be anything diff --git a/nexus_constructor/json/transformation_reader.py b/nexus_constructor/json/transformation_reader.py index 9fd90c7af..ecba5f8b6 100644 --- a/nexus_constructor/json/transformation_reader.py +++ b/nexus_constructor/json/transformation_reader.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Optional, Tuple, Union +from typing import Any, Dict, List, Optional, Tuple, Union, cast from PySide6.QtGui import QVector3D @@ -127,7 +127,7 @@ def _get_transformation_attribute( self, attribute_name: Union[str, List[str]], json_transformation: dict, - transform_name: str = None, + transform_name: str = "", failure_value: Any = None, ) -> Any: """ @@ -323,15 +323,14 @@ def _create_transformations(self, json_transformations: list): angle_or_magnitude = 0.0 else: continue - temp_depends_on = None transform = self.parent_component._create_and_add_transform( name=name, - transformation_type=transformation_type, + transformation_type=cast(str, transformation_type), angle_or_magnitude=angle_or_magnitude, units=units, vector=QVector3D(*vector), - depends_on=temp_depends_on, + depends_on=cast(Transformation, None), values=values, ) offset = self._find_attribute_in_list(CommonAttrs.OFFSET, name, attributes) diff --git a/nexus_constructor/model/component.py b/nexus_constructor/model/component.py index b225398f6..960e92474 100644 --- a/nexus_constructor/model/component.py +++ b/nexus_constructor/model/component.py @@ -88,6 +88,8 @@ class Component(Group): has_link = attr.ib(type=bool, default=None) component_info: "ComponentInfo" = None stored_transforms: list = None + name: str = None + parent_node: str = None @property def stored_items(self) -> List: @@ -271,7 +273,7 @@ def _create_and_add_transform( units: str, vector: QVector3D, depends_on: Transformation, - values: Union[Dataset, Group], + values: Union[Dataset, Group, StreamModule], target_pos: int = -1, ) -> Transformation: if name is None: diff --git a/nexus_constructor/model/module.py b/nexus_constructor/model/module.py index 1219310b2..9412fcd12 100644 --- a/nexus_constructor/model/module.py +++ b/nexus_constructor/model/module.py @@ -57,7 +57,8 @@ class StreamModules(Enum): @attr.s class FileWriterModule(ABC): - attributes = attr.ib(type=Attributes, factory=Attributes, init=False) + name: str = None + parent_node: str = None attributes = attr.ib(type=Attributes, factory=Attributes, init=False) writer_module = attr.ib(type=str, init=False) parent_node = attr.ib(type="Group")