diff --git a/cura/CuraActions.py b/cura/CuraActions.py index 93a18318df..49f7e740a9 100644 --- a/cura/CuraActions.py +++ b/cura/CuraActions.py @@ -3,7 +3,7 @@ from PyQt5.QtCore import QObject, QUrl from PyQt5.QtGui import QDesktopServices -from typing import List, TYPE_CHECKING +from typing import List, TYPE_CHECKING, cast from UM.Event import CallFunctionEvent from UM.FlameProfiler import pyqtSlot @@ -61,8 +61,10 @@ class CuraActions(QObject): operation = GroupedOperation() for node in Selection.getAllSelectedObjects(): current_node = node - while current_node.getParent() and current_node.getParent().callDecoration("isGroup"): - current_node = current_node.getParent() + parent_node = current_node.getParent() + while parent_node and parent_node.callDecoration("isGroup"): + current_node = parent_node + parent_node = current_node.getParent() # This was formerly done with SetTransformOperation but because of # unpredictable matrix deconstruction it was possible that mirrors @@ -150,13 +152,13 @@ class CuraActions(QObject): root = cura.CuraApplication.CuraApplication.getInstance().getController().getScene().getRoot() - nodes_to_change = [] + nodes_to_change = [] # type: List[SceneNode] for node in Selection.getAllSelectedObjects(): parent_node = node # Find the parent node to change instead while parent_node.getParent() != root: - parent_node = parent_node.getParent() + parent_node = cast(SceneNode, parent_node.getParent()) - for single_node in BreadthFirstIterator(parent_node): #type: ignore #Ignore type error because iter() should get called automatically by Python syntax. + for single_node in BreadthFirstIterator(parent_node): # type: ignore #Ignore type error because iter() should get called automatically by Python syntax. nodes_to_change.append(single_node) if not nodes_to_change: diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py index f1d8e81b3a..e863689e21 100644 --- a/cura/PrintInformation.py +++ b/cura/PrintInformation.py @@ -14,8 +14,7 @@ from UM.Logger import Logger from UM.Qt.Duration import Duration from UM.Scene.SceneNode import SceneNode from UM.i18n import i18nCatalog -from UM.MimeTypeDatabase import MimeTypeDatabase - +from UM.MimeTypeDatabase import MimeTypeDatabase, MimeTypeNotFoundError from typing import TYPE_CHECKING @@ -361,7 +360,7 @@ class PrintInformation(QObject): try: mime_type = MimeTypeDatabase.getMimeTypeForFile(name) data = mime_type.stripExtension(name) - except: + except MimeTypeNotFoundError: Logger.log("w", "Unsupported Mime Type Database file extension %s", name) if data is not None and check_name is not None: @@ -402,7 +401,7 @@ class PrintInformation(QObject): return ''.join(char for char in unicodedata.normalize('NFD', to_strip) if unicodedata.category(char) != 'Mn') @pyqtSlot(result = "QVariantMap") - def getFeaturePrintTimes(self): + def getFeaturePrintTimes(self) -> Dict[str, Duration]: result = {} if self._active_build_plate not in self._print_times_per_feature: self._initPrintTimesPerFeature(self._active_build_plate) diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 226a352602..e3d7eedd9a 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -66,7 +66,7 @@ class MachineManager(QObject): self.machine_extruder_material_update_dict = collections.defaultdict(list) #type: Dict[str, List[Callable[[], None]]] - self._instance_container_timer = QTimer() #type: QTimer + self._instance_container_timer = QTimer() # type: QTimer self._instance_container_timer.setInterval(250) self._instance_container_timer.setSingleShot(True) self._instance_container_timer.timeout.connect(self.__emitChangedSignals) @@ -76,7 +76,7 @@ class MachineManager(QObject): self._application.globalContainerStackChanged.connect(self._onGlobalContainerChanged) self._container_registry.containerLoadComplete.connect(self._onContainersChanged) - ## When the global container is changed, active material probably needs to be updated. + # When the global container is changed, active material probably needs to be updated. self.globalContainerChanged.connect(self.activeMaterialChanged) self.globalContainerChanged.connect(self.activeVariantChanged) self.globalContainerChanged.connect(self.activeQualityChanged) @@ -117,15 +117,15 @@ class MachineManager(QObject): self._material_incompatible_message = Message(catalog.i18nc("@info:status", "The selected material is incompatible with the selected machine or configuration."), - title = catalog.i18nc("@info:title", "Incompatible Material")) #type: Message + title = catalog.i18nc("@info:title", "Incompatible Material")) # type: Message - containers = CuraContainerRegistry.getInstance().findInstanceContainers(id = self.activeMaterialId) #type: List[InstanceContainer] + containers = CuraContainerRegistry.getInstance().findInstanceContainers(id = self.activeMaterialId) # type: List[InstanceContainer] if containers: containers[0].nameChanged.connect(self._onMaterialNameChanged) - self._material_manager = self._application.getMaterialManager() #type: MaterialManager - self._variant_manager = self._application.getVariantManager() #type: VariantManager - self._quality_manager = self._application.getQualityManager() #type: QualityManager + self._material_manager = self._application.getMaterialManager() # type: MaterialManager + self._variant_manager = self._application.getVariantManager() # type: VariantManager + self._quality_manager = self._application.getQualityManager() # type: QualityManager # When the materials lookup table gets updated, it can mean that a material has its name changed, which should # be reflected on the GUI. This signal emission makes sure that it happens. @@ -158,7 +158,7 @@ class MachineManager(QObject): blurSettings = pyqtSignal() # Emitted to force fields in the advanced sidebar to un-focus, so they update properly outputDevicesChanged = pyqtSignal() - currentConfigurationChanged = pyqtSignal() # Emitted every time the current configurations of the machine changes + currentConfigurationChanged = pyqtSignal() # Emitted every time the current configurations of the machine changes printerConnectedStatusChanged = pyqtSignal() # Emitted every time the active machine change or the outputdevices change rootMaterialChanged = pyqtSignal() @@ -203,7 +203,7 @@ class MachineManager(QObject): extruder_configuration.hotendID = extruder.variant.getName() if extruder.variant != empty_variant_container else None self._current_printer_configuration.extruderConfigurations.append(extruder_configuration) - # an empty build plate configuration from the network printer is presented as an empty string, so use "" for an + # An empty build plate configuration from the network printer is presented as an empty string, so use "" for an # empty build plate. self._current_printer_configuration.buildplateConfiguration = self._global_container_stack.getProperty("machine_buildplate_type", "value") if self._global_container_stack.variant != empty_variant_container else "" self.currentConfigurationChanged.emit() @@ -249,7 +249,7 @@ class MachineManager(QObject): self.updateNumberExtrudersEnabled() self.globalContainerChanged.emit() - # after switching the global stack we reconnect all the signals and set the variant and material references + # After switching the global stack we reconnect all the signals and set the variant and material references if self._global_container_stack: self._application.getPreferences().setValue("cura/active_machine", self._global_container_stack.getId()) @@ -263,7 +263,7 @@ class MachineManager(QObject): if global_variant.getMetaDataEntry("hardware_type") != "buildplate": self._global_container_stack.setVariant(empty_variant_container) - # set the global material to empty as we now use the extruder stack at all times - CURA-4482 + # Set the global material to empty as we now use the extruder stack at all times - CURA-4482 global_material = self._global_container_stack.material if global_material != empty_material_container: self._global_container_stack.setMaterial(empty_material_container) @@ -421,7 +421,7 @@ class MachineManager(QObject): # Not a very pretty solution, but the extruder manager doesn't really know how many extruders there are machine_extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value") extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks() - count = 1 # we start with the global stack + count = 1 # We start with the global stack for stack in extruder_stacks: md = stack.getMetaData() if "position" in md and int(md["position"]) >= machine_extruder_count: @@ -648,7 +648,7 @@ class MachineManager(QObject): new_value = self._active_container_stack.getProperty(key, "value") extruder_stacks = [stack for stack in ExtruderManager.getInstance().getActiveExtruderStacks()] - # check in which stack the value has to be replaced + # Check in which stack the value has to be replaced for extruder_stack in extruder_stacks: if extruder_stack != self._active_container_stack and extruder_stack.getProperty(key, "value") != new_value: extruder_stack.userChanges.setProperty(key, "value", new_value) # TODO: nested property access, should be improved @@ -664,7 +664,7 @@ class MachineManager(QObject): for key in self._active_container_stack.userChanges.getAllKeys(): new_value = self._active_container_stack.getProperty(key, "value") - # check if the value has to be replaced + # Check if the value has to be replaced extruder_stack.userChanges.setProperty(key, "value", new_value) @pyqtProperty(str, notify = activeVariantChanged) @@ -733,7 +733,7 @@ class MachineManager(QObject): # If the machine that is being removed is the currently active machine, set another machine as the active machine. activate_new_machine = (self._global_container_stack and self._global_container_stack.getId() == machine_id) - # activate a new machine before removing a machine because this is safer + # Activate a new machine before removing a machine because this is safer if activate_new_machine: machine_stacks = CuraContainerRegistry.getInstance().findContainerStacksMetadata(type = "machine") other_machine_stacks = [s for s in machine_stacks if s["id"] != machine_id] @@ -917,9 +917,12 @@ class MachineManager(QObject): if settable_per_extruder: limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder")) - extruder_position = str(max(0, limit_to_extruder)) - extruder_stack = self._global_container_stack.extruders[extruder_position] - extruder_stack.userChanges.setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value")) + extruder_position = max(0, limit_to_extruder) + extruder_stack = self.getExtruder(extruder_position) + if extruder_stack: + extruder_stack.userChanges.setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value")) + else: + Logger.log("e", "Unable to find extruder on position %s", extruder_position) global_user_container.removeInstance(setting_key) # Signal that the global stack has changed @@ -928,10 +931,9 @@ class MachineManager(QObject): @pyqtSlot(int, result = QObject) def getExtruder(self, position: int) -> Optional[ExtruderStack]: - extruder = None if self._global_container_stack: - extruder = self._global_container_stack.extruders.get(str(position)) - return extruder + return self._global_container_stack.extruders.get(str(position)) + return None def updateDefaultExtruder(self) -> None: if self._global_container_stack is None: @@ -997,12 +999,12 @@ class MachineManager(QObject): if not enabled and position == ExtruderManager.getInstance().activeExtruderIndex: ExtruderManager.getInstance().setActiveExtruderIndex(int(self._default_extruder_position)) - # ensure that the quality profile is compatible with current combination, or choose a compatible one if available + # Ensure that the quality profile is compatible with current combination, or choose a compatible one if available self._updateQualityWithMaterial() self.extruderChanged.emit() - # update material compatibility color + # Update material compatibility color self.activeQualityGroupChanged.emit() - # update items in SettingExtruder + # Update items in SettingExtruder ExtruderManager.getInstance().extrudersChanged.emit(self._global_container_stack.getId()) # Make sure the front end reflects changes self.forceUpdateAllSettings() @@ -1076,7 +1078,6 @@ class MachineManager(QObject): return result - # # Sets all quality and quality_changes containers to empty_quality and empty_quality_changes containers # for all stacks in the currently active machine. # @@ -1135,7 +1136,7 @@ class MachineManager(QObject): def _setQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup") -> None: if self._global_container_stack is None: - return #Can't change that. + return # Can't change that. quality_type = quality_changes_group.quality_type # A custom quality can be created based on "not supported". # In that case, do not set quality containers to empty. @@ -1205,7 +1206,7 @@ class MachineManager(QObject): self.rootMaterialChanged.emit() def activeMaterialsCompatible(self) -> bool: - # check material - variant compatibility + # Check material - variant compatibility if self._global_container_stack is not None: if Util.parseBool(self._global_container_stack.getMetaDataEntry("has_materials", False)): for position, extruder in self._global_container_stack.extruders.items(): @@ -1415,7 +1416,7 @@ class MachineManager(QObject): material_diameter, root_material_id) self.setMaterial(position, material_node) - ## global_stack: if you want to provide your own global_stack instead of the current active one + ## Global_stack: if you want to provide your own global_stack instead of the current active one # if you update an active machine, special measures have to be taken. @pyqtSlot(str, "QVariant") def setMaterial(self, position: str, container_node, global_stack: Optional["GlobalStack"] = None) -> None: diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.py b/plugins/PostProcessingPlugin/PostProcessingPlugin.py index 11ee610bec..78f9cc0516 100644 --- a/plugins/PostProcessingPlugin/PostProcessingPlugin.py +++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.py @@ -55,14 +55,14 @@ class PostProcessingPlugin(QObject, Extension): def selectedScriptDefinitionId(self) -> Optional[str]: try: return self._script_list[self._selected_script_index].getDefinitionId() - except: + except IndexError: return "" @pyqtProperty(str, notify=selectedIndexChanged) def selectedScriptStackId(self) -> Optional[str]: try: return self._script_list[self._selected_script_index].getStackId() - except: + except IndexError: return "" ## Execute all post-processing scripts on the gcode. diff --git a/plugins/USBPrinting/AutoDetectBaudJob.py b/plugins/USBPrinting/AutoDetectBaudJob.py index 8b37c4b29d..6f1af6727a 100644 --- a/plugins/USBPrinting/AutoDetectBaudJob.py +++ b/plugins/USBPrinting/AutoDetectBaudJob.py @@ -3,6 +3,7 @@ from UM.Job import Job from UM.Logger import Logger +from plugins.USBPrinting.avr_isp import ispBase from .avr_isp.stk500v2 import Stk500v2 @@ -14,12 +15,12 @@ from serial import Serial, SerialException # It tries a pre-set list of baud rates. All these baud rates are validated by requesting the temperature a few times # and checking if the results make sense. If getResult() is not None, it was able to find a correct baud rate. class AutoDetectBaudJob(Job): - def __init__(self, serial_port): + def __init__(self, serial_port: int) -> None: super().__init__() self._serial_port = serial_port self._all_baud_rates = [115200, 250000, 230400, 57600, 38400, 19200, 9600] - def run(self): + def run(self) -> None: Logger.log("d", "Auto detect baud rate started.") wait_response_timeouts = [3, 15, 30] wait_bootloader_times = [1.5, 5, 15] @@ -32,7 +33,7 @@ class AutoDetectBaudJob(Job): try: programmer.connect(self._serial_port) serial = programmer.leaveISP() - except: + except ispBase.IspError: programmer.close() for retry in range(tries): @@ -58,7 +59,7 @@ class AutoDetectBaudJob(Job): # We already have a serial connection, just change the baud rate. try: serial.baudrate = baud_rate - except: + except ValueError: continue sleep(wait_bootloader) # Ensure that we are not talking to the boot loader. 1.5 seconds seems to be the magic number successful_responses = 0 @@ -81,5 +82,5 @@ class AutoDetectBaudJob(Job): return serial.write(b"M105\n") - sleep(15) # Give the printer some time to init and try again. + sleep(15) # Give the printer some time to init and try again. self.setResult(None) # Unable to detect the correct baudrate.