diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py index 9d456c833d..e1e17b20ea 100644 --- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py +++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py @@ -6,8 +6,10 @@ import io import json #To parse the product-to-id mapping file. import os.path #To find the product-to-id mapping. import sys -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List, Optional, cast import xml.etree.ElementTree as ET +from typing import Dict +from typing import Iterator from UM.Resources import Resources from UM.Logger import Logger @@ -132,7 +134,7 @@ class XmlMaterialProfile(InstanceContainer): "version": self.CurrentFdmMaterialVersion}) ## Begin Metadata Block - builder.start("metadata") + builder.start("metadata") # type: ignore metadata = copy.deepcopy(self.getMetaData()) # setting_version is derived from the "version" tag in the schema, so don't serialize it into a file @@ -156,21 +158,21 @@ class XmlMaterialProfile(InstanceContainer): metadata.pop("name", "") ## Begin Name Block - builder.start("name") + builder.start("name") # type: ignore - builder.start("brand") + builder.start("brand") # type: ignore builder.data(metadata.pop("brand", "")) builder.end("brand") - builder.start("material") + builder.start("material") # type: ignore builder.data(metadata.pop("material", "")) builder.end("material") - builder.start("color") + builder.start("color") # type: ignore builder.data(metadata.pop("color_name", "")) builder.end("color") - builder.start("label") + builder.start("label") # type: ignore builder.data(self.getName()) builder.end("label") @@ -178,7 +180,7 @@ class XmlMaterialProfile(InstanceContainer): ## End Name Block for key, value in metadata.items(): - builder.start(key) + builder.start(key) # type: ignore if value is not None: #Nones get handled well by the builder. #Otherwise the builder always expects a string. #Deserialize expects the stringified version. @@ -190,10 +192,10 @@ class XmlMaterialProfile(InstanceContainer): ## End Metadata Block ## Begin Properties Block - builder.start("properties") + builder.start("properties") # type: ignore for key, value in properties.items(): - builder.start(key) + builder.start(key) # type: ignore builder.data(value) builder.end(key) @@ -201,14 +203,14 @@ class XmlMaterialProfile(InstanceContainer): ## End Properties Block ## Begin Settings Block - builder.start("settings") + builder.start("settings") # type: ignore if self.getMetaDataEntry("definition") == "fdmprinter": for instance in self.findInstances(): self._addSettingElement(builder, instance) - machine_container_map = {} - machine_variant_map = {} + machine_container_map = {} # type: Dict[str, InstanceContainer] + machine_variant_map = {} # type: Dict[str, Dict[str, Any]] variant_manager = CuraApplication.getInstance().getVariantManager() @@ -248,7 +250,7 @@ class XmlMaterialProfile(InstanceContainer): product = product_name break - builder.start("machine") + builder.start("machine") # type: ignore builder.start("machine_identifier", { "manufacturer": container.getMetaDataEntry("machine_manufacturer", definition_metadata.get("manufacturer", "Unknown")), @@ -264,7 +266,7 @@ class XmlMaterialProfile(InstanceContainer): self._addSettingElement(builder, instance) # Find all hotend sub-profiles corresponding to this material and machine and add them to this profile. - buildplate_dict = {} + buildplate_dict = {} # type: Dict[str, Any] for variant_name, variant_dict in machine_variant_map[definition_id].items(): variant_type = variant_dict["variant_node"].metadata["hardware_type"] from cura.Machines.VariantManager import VariantType @@ -812,11 +814,14 @@ class XmlMaterialProfile(InstanceContainer): if label is not None and label.text is not None: base_metadata["name"] = label.text else: - base_metadata["name"] = cls._profile_name(material.text, color.text) + if material is not None and color is not None: + base_metadata["name"] = cls._profile_name(material.text, color.text) + else: + base_metadata["name"] = "Unknown Material" - base_metadata["brand"] = brand.text if brand.text is not None else "Unknown Brand" - base_metadata["material"] = material.text if material.text is not None else "Unknown Type" - base_metadata["color_name"] = color.text if color.text is not None else "Unknown Color" + base_metadata["brand"] = brand.text if brand is not None and brand.text is not None else "Unknown Brand" + base_metadata["material"] = material.text if material is not None and material.text is not None else "Unknown Type" + base_metadata["color_name"] = color.text if color is not None and color.text is not None else "Unknown Color" continue #Setting_version is derived from the "version" tag in the schema earlier, so don't set it here. @@ -836,13 +841,13 @@ class XmlMaterialProfile(InstanceContainer): tag_name = _tag_without_namespace(entry) property_values[tag_name] = entry.text - base_metadata["approximate_diameter"] = str(round(float(property_values.get("diameter", 2.85)))) # In mm + base_metadata["approximate_diameter"] = str(round(float(cast(float, property_values.get("diameter", 2.85))))) # In mm base_metadata["properties"] = property_values base_metadata["definition"] = "fdmprinter" compatible_entries = data.iterfind("./um:settings/um:setting[@key='hardware compatible']", cls.__namespaces) try: - common_compatibility = cls._parseCompatibleValue(next(compatible_entries).text) + common_compatibility = cls._parseCompatibleValue(next(compatible_entries).text) # type: ignore except StopIteration: #No 'hardware compatible' setting. common_compatibility = True base_metadata["compatible"] = common_compatibility @@ -856,7 +861,8 @@ class XmlMaterialProfile(InstanceContainer): for entry in machine.iterfind("./um:setting", cls.__namespaces): key = entry.get("key") if key == "hardware compatible": - machine_compatibility = cls._parseCompatibleValue(entry.text) + if entry.text is not None: + machine_compatibility = cls._parseCompatibleValue(entry.text) for identifier in machine.iterfind("./um:machine_identifier", cls.__namespaces): machine_id_list = product_id_map.get(identifier.get("product"), []) @@ -891,7 +897,7 @@ class XmlMaterialProfile(InstanceContainer): result_metadata.append(new_material_metadata) buildplates = machine.iterfind("./um:buildplate", cls.__namespaces) - buildplate_map = {} + buildplate_map = {} # type: Dict[str, Dict[str, bool]] buildplate_map["buildplate_compatible"] = {} buildplate_map["buildplate_recommended"] = {} for buildplate in buildplates: @@ -912,10 +918,11 @@ class XmlMaterialProfile(InstanceContainer): buildplate_recommended = True for entry in settings: key = entry.get("key") - if key == "hardware compatible": - buildplate_compatibility = cls._parseCompatibleValue(entry.text) - elif key == "hardware recommended": - buildplate_recommended = cls._parseCompatibleValue(entry.text) + if entry.text is not None: + if key == "hardware compatible": + buildplate_compatibility = cls._parseCompatibleValue(entry.text) + elif key == "hardware recommended": + buildplate_recommended = cls._parseCompatibleValue(entry.text) buildplate_map["buildplate_compatible"][buildplate_id] = buildplate_compatibility buildplate_map["buildplate_recommended"][buildplate_id] = buildplate_recommended @@ -929,7 +936,8 @@ class XmlMaterialProfile(InstanceContainer): for entry in hotend.iterfind("./um:setting", cls.__namespaces): key = entry.get("key") if key == "hardware compatible": - hotend_compatibility = cls._parseCompatibleValue(entry.text) + if entry.text is not None: + hotend_compatibility = cls._parseCompatibleValue(entry.text) new_hotend_specific_material_id = container_id + "_" + machine_id + "_" + hotend_name.replace(" ", "_")