From 1d4ba577a95f5e3d9ecc0279f02685a9b86d5814 Mon Sep 17 00:00:00 2001 From: Fabien Castan Date: Wed, 30 Apr 2025 19:13:53 +0200 Subject: [PATCH 1/4] Apply flynt to use f-strings --- meshroom/common/PySignal.py | 8 ++--- meshroom/common/qt.py | 2 +- meshroom/core/__init__.py | 2 +- meshroom/core/attribute.py | 36 +++++++++---------- meshroom/core/desc/node.py | 6 ++-- meshroom/core/exception.py | 4 +-- meshroom/core/graph.py | 19 +++++----- meshroom/core/node.py | 20 +++++------ meshroom/core/stats.py | 30 ++++++++-------- meshroom/core/taskManager.py | 6 ++-- meshroom/core/test.py | 2 +- meshroom/multiview.py | 2 +- meshroom/nodes/general/Publish.py | 6 ++-- meshroom/submitters/simpleFarmSubmitter.py | 4 +-- meshroom/ui/app.py | 22 ++++++------ meshroom/ui/commands.py | 30 ++++++++-------- meshroom/ui/components/csvData.py | 2 +- meshroom/ui/components/filepath.py | 2 +- meshroom/ui/graph.py | 10 +++--- .../MaterialIcons/generate_material_icons.py | 2 +- meshroom/ui/reconstruction.py | 26 +++++++------- meshroom/ui/utils.py | 6 ++-- 22 files changed, 123 insertions(+), 124 deletions(-) diff --git a/meshroom/common/PySignal.py b/meshroom/common/PySignal.py index 7b93e162f3..a3ae844c0b 100644 --- a/meshroom/common/PySignal.py +++ b/meshroom/common/PySignal.py @@ -86,7 +86,7 @@ def connect(self, slot): Connects the signal to any callable object """ if not callable(slot): - raise ValueError("Connection to non-callable '%s' object failed" % slot.__class__.__name__) + raise ValueError(f"Connection to non-callable '{slot.__class__.__name__}' object failed") if isinstance(slot, (partial, Signal)) or '<' in slot.__name__: # If it's a partial, a Signal or a lambda. The '<' check is the only py2 and py3 compatible way I could find @@ -199,7 +199,7 @@ def emit(self, signalName, *args, **kwargs): Emits a signal by name if it exists. Any additional args or kwargs are passed to the signal :param signalName: the signal name to emit """ - assert signalName in self, "%s is not a registered signal" % signalName + assert signalName in self, f"{signalName} is not a registered signal" self[signalName].emit(*args, **kwargs) def connect(self, signalName, slot): @@ -208,7 +208,7 @@ def connect(self, signalName, slot): :param signalName: the signal name to connect to :param slot: the callable slot to register """ - assert signalName in self, "%s is not a registered signal" % signalName + assert signalName in self, f"{signalName} is not a registered signal" self[signalName].connect(slot) def block(self, signals=None, isBlocked=True): @@ -230,7 +230,7 @@ def block(self, signals=None, isBlocked=True): for signal in signals: if signal not in self: - raise RuntimeError("Could not find signal matching %s" % signal) + raise RuntimeError(f"Could not find signal matching {signal}") self[signal].block(isBlocked) diff --git a/meshroom/common/qt.py b/meshroom/common/qt.py index 6e067dbe13..7b6496dee1 100644 --- a/meshroom/common/qt.py +++ b/meshroom/common/qt.py @@ -279,7 +279,7 @@ def _referenceItem(self, item): if key is None: return if key in self._objectByKey: - raise ValueError("Object key {}:{} is not unique".format(self._keyAttrName, key)) + raise ValueError(f"Object key {self._keyAttrName}:{key} is not unique") self._objectByKey[key] = item diff --git a/meshroom/core/__init__.py b/meshroom/core/__init__.py index 148b6119f4..4d948543e8 100644 --- a/meshroom/core/__init__.py +++ b/meshroom/core/__init__.py @@ -89,7 +89,7 @@ def loadClasses(folder, packageName, classType): try: pluginMod = importlib.import_module(pluginModuleName, package=package.__name__) plugins = [plugin for name, plugin in inspect.getmembers(pluginMod, inspect.isclass) - if plugin.__module__ == '{}.{}'.format(package.__name__, pluginName) + if plugin.__module__ == f'{package.__name__}.{pluginName}' and issubclass(plugin, classType)] if not plugins: logging.warning(f"No class defined in plugin: {pluginModuleName}") diff --git a/meshroom/core/attribute.py b/meshroom/core/attribute.py index 59856e4290..f3cc617b0a 100644 --- a/meshroom/core/attribute.py +++ b/meshroom/core/attribute.py @@ -91,19 +91,19 @@ def getName(self): def getFullName(self): """ Name inside the Graph: groupName.name """ if isinstance(self.root, ListAttribute): - return '{}[{}]'.format(self.root.getFullName(), self.root.index(self)) + return f'{self.root.getFullName()}[{self.root.index(self)}]' elif isinstance(self.root, GroupAttribute): - return '{}.{}'.format(self.root.getFullName(), self.getName()) + return f'{self.root.getFullName()}.{self.getName()}' return self.getName() def getFullNameToNode(self): """ Name inside the Graph: nodeName.groupName.name """ - return '{}.{}'.format(self.node.name, self.getFullName()) + return f'{self.node.name}.{self.getFullName()}' def getFullNameToGraph(self): """ Name inside the Graph: graphName.nodeName.groupName.name """ graphName = self.node.graph.name if self.node.graph else "UNDEFINED" - return '{}.{}'.format(graphName, self.getFullNameToNode()) + return f'{graphName}.{self.getFullNameToNode()}' def asLinkExpr(self): """ Return link expression for this Attribute """ @@ -130,17 +130,17 @@ def getFullLabel(self): if isinstance(self.root, ListAttribute): return self.root.getFullLabel() elif isinstance(self.root, GroupAttribute): - return '{} {}'.format(self.root.getFullLabel(), self.getLabel()) + return f'{self.root.getFullLabel()} {self.getLabel()}' return self.getLabel() def getFullLabelToNode(self): """ Label inside the Graph: nodeLabel groupLabel Label """ - return '{} {}'.format(self.node.label, self.getFullLabel()) + return f'{self.node.label} {self.getFullLabel()}' def getFullLabelToGraph(self): """ Label inside the Graph: graphName nodeLabel groupLabel Label """ graphName = self.node.graph.name if self.node.graph else "UNDEFINED" - return '{} {}'.format(graphName, self.getFullLabelToNode()) + return f'{graphName} {self.getFullLabelToNode()}' def getEnabled(self): if isinstance(self.desc.enabled, types.FunctionType): @@ -350,7 +350,7 @@ def _applyExpr(self): g.addEdge(node.attribute(linkAttrName), self) except KeyError as err: logging.warning('Connect Attribute from Expression failed.') - logging.warning('Expression: "{exp}"\nError: "{err}".'.format(exp=v, err=err)) + logging.warning(f'Expression: "{v}"\nError: "{err}".') self.resetToDefaultValue() def getExportValue(self): @@ -389,11 +389,11 @@ def getValueStr(self, withQuotes=True): assert (isinstance(self.value, Sequence) and not isinstance(self.value, str)) v = self.attributeDesc.joinChar.join(self.getEvalValue()) if withQuotes and v: - return '"{}"'.format(v) + return f'"{v}"' return v # String, File, single value Choice are based on strings and should includes quotes to deal with spaces if withQuotes and isinstance(self.attributeDesc, (desc.StringParam, desc.File, desc.ChoiceParam)): - return '"{}"'.format(self.getEvalValue()) + return f'"{self.getEvalValue()}"' return str(self.getEvalValue()) def defaultValue(self): @@ -685,7 +685,7 @@ def getValueStr(self, withQuotes=True): else: v = self.attributeDesc.joinChar.join([v.getValueStr(withQuotes=False) for v in self.value]) if withQuotes and v: - return '"{}"'.format(v) + return f'"{v}"' return v def updateInternals(self): @@ -730,11 +730,11 @@ def _set_value(self, exportedValue): self._value.get(key).value = v elif isinstance(value, (list, tuple)): if len(self.desc._groupDesc) != len(value): - raise AttributeError("Incorrect number of values on GroupAttribute: {}".format(str(value))) + raise AttributeError(f"Incorrect number of values on GroupAttribute: {str(value)}") for attrDesc, v in zip(self.desc._groupDesc, value): self._value.get(attrDesc.name).value = v else: - raise AttributeError("Failed to set on GroupAttribute: {}".format(str(value))) + raise AttributeError(f"Failed to set on GroupAttribute: {str(value)}") def upgradeValue(self, exportedValue): value = self.validateValue(exportedValue) @@ -745,11 +745,11 @@ def upgradeValue(self, exportedValue): self._value.get(key).upgradeValue(v) elif isinstance(value, (list, tuple)): if len(self.desc._groupDesc) != len(value): - raise AttributeError("Incorrect number of values on GroupAttribute: {}".format(str(value))) + raise AttributeError(f"Incorrect number of values on GroupAttribute: {str(value)}") for attrDesc, v in zip(self.desc._groupDesc, value): self._value.get(attrDesc.name).upgradeValue(v) else: - raise AttributeError("Failed to set on GroupAttribute: {}".format(str(value))) + raise AttributeError(f"Failed to set on GroupAttribute: {str(value)}") def initValue(self): self._value = DictModel(keyAttrName='name', parent=self) @@ -816,7 +816,7 @@ def getValueStr(self, withQuotes=True): strBegin = self.attributeDesc.brackets[0] strEnd = self.attributeDesc.brackets[1] else: - raise AttributeError("Incorrect brackets on GroupAttribute: {}".format(self.attributeDesc.brackets)) + raise AttributeError(f"Incorrect brackets on GroupAttribute: {self.attributeDesc.brackets}") # particular case when using space separator spaceSep = self.attributeDesc.joinChar == ' ' @@ -827,8 +827,8 @@ def getValueStr(self, withQuotes=True): s = self.attributeDesc.joinChar.join(sortedSubValues) if withQuotes and not spaceSep: - return '"{}{}{}"'.format(strBegin, s, strEnd) - return '{}{}{}'.format(strBegin, s, strEnd) + return f'"{strBegin}{s}{strEnd}"' + return f'{strBegin}{s}{strEnd}' def updateInternals(self): super(GroupAttribute, self).updateInternals() diff --git a/meshroom/core/desc/node.py b/meshroom/core/desc/node.py index da887b629f..5f364c1ad6 100644 --- a/meshroom/core/desc/node.py +++ b/meshroom/core/desc/node.py @@ -193,7 +193,7 @@ def executeChunkCommandLine(self, chunk, cmd, env=None): if chunk.subprocess.returncode != 0: with open(chunk.logFile, 'r') as logF: logContent = ''.join(logF.readlines()) - raise RuntimeError('Error on node "{}":\nLog:\n{}'.format(chunk.name, logContent)) + raise RuntimeError(f'Error on node "{chunk.name}":\nLog:\n{logContent}') finally: chunk.subprocess = None @@ -299,12 +299,12 @@ def __init__(self): AVCommandLineNode.cmdMem = '' memSize = cgroup.getCgroupMemorySize() if memSize > 0: - AVCommandLineNode.cmdMem = ' --maxMemory={memSize}'.format(memSize=memSize) + AVCommandLineNode.cmdMem = f' --maxMemory={memSize}' AVCommandLineNode.cmdCore = '' coresCount = cgroup.getCgroupCpuCount() if coresCount > 0: - AVCommandLineNode.cmdCore = ' --maxCores={coresCount}'.format(coresCount=coresCount) + AVCommandLineNode.cmdCore = f' --maxCores={coresCount}' AVCommandLineNode.cgroupParsed = True diff --git a/meshroom/core/exception.py b/meshroom/core/exception.py index 2365f8e21a..fe8e834cd4 100644 --- a/meshroom/core/exception.py +++ b/meshroom/core/exception.py @@ -39,9 +39,9 @@ def __init__(self, nodeType, msg=None): class NodeUpgradeError(GraphException): def __init__(self, nodeName, details=None): - msg = "Failed to upgrade node {}".format(nodeName) + msg = f"Failed to upgrade node {nodeName}" if details: - msg += ": {}".format(details) + msg += f": {details}" super(NodeUpgradeError, self).__init__(msg) diff --git a/meshroom/core/graph.py b/meshroom/core/graph.py index 8197602d17..90440ea8a3 100644 --- a/meshroom/core/graph.py +++ b/meshroom/core/graph.py @@ -66,7 +66,7 @@ def __init__(self, src, dst, parent=None): super(Edge, self).__init__(parent) self._src = weakref.ref(src) self._dst = weakref.ref(dst) - self._repr = " {} -> {}".format(self._src(), self._dst()) + self._repr = f" {self._src()} -> {self._dst()}" @property def src(self): @@ -839,12 +839,12 @@ def findNodeCandidates(self, nodeNameExpr: str) -> list[Node]: def findNode(self, nodeExpr: str) -> Node: candidates = self.findNodeCandidates('^' + nodeExpr) if not candidates: - raise KeyError('No node candidate for "{}"'.format(nodeExpr)) + raise KeyError(f'No node candidate for "{nodeExpr}"') if len(candidates) > 1: for c in candidates: if c.name == nodeExpr: return c - raise KeyError('Multiple node candidates for "{}": {}'.format(nodeExpr, str([c.name for c in candidates]))) + raise KeyError(f'Multiple node candidates for "{nodeExpr}": {str([c.name for c in candidates])}') return candidates[0] def findNodes(self, nodesExpr): @@ -870,7 +870,7 @@ def addEdge(self, srcAttr, dstAttr): if srcAttr.node.graph != self or dstAttr.node.graph != self: raise RuntimeError('The attributes of the edge should be part of a common graph.') if dstAttr in self.edges.keys(): - raise RuntimeError('Destination attribute "{}" is already connected.'.format(dstAttr.getFullNameToNode())) + raise RuntimeError(f'Destination attribute "{dstAttr.getFullNameToNode()}" is already connected.') edge = Edge(srcAttr, dstAttr) self.edges.add(edge) self.markNodesDirty(dstAttr.node) @@ -887,7 +887,7 @@ def addEdges(self, *edges): @changeTopology def removeEdge(self, dstAttr): if dstAttr not in self.edges.keys(): - raise RuntimeError('Attribute "{}" is not connected'.format(dstAttr.getFullNameToNode())) + raise RuntimeError(f'Attribute "{dstAttr.getFullNameToNode()}" is not connected') edge = self.edges.pop(dstAttr) self.markNodesDirty(dstAttr.node) dstAttr.valueChanged.emit() @@ -1639,8 +1639,7 @@ def executeGraph(graph, toNodes=None, forceCompute=False, forceStatus=False): node=n+1, nbNodes=len(nodes), chunk=c+1, nbChunks=len(node.chunks), nodeName=node.nodeType)) else: - print('\n[{node}/{nbNodes}] {nodeName}'.format( - node=n + 1, nbNodes=len(nodes), nodeName=node.nodeType)) + print(f'\n[{n + 1}/{len(nodes)}] {node.nodeType}') chunk.process(forceCompute) node.postprocess() except Exception as e: @@ -1661,8 +1660,8 @@ def submitGraph(graph, submitter, toNodes=None, submitLabel="{projectName}"): logging.warning('Nothing to compute') return - logging.info("Nodes to process: {}".format(edgesToProcess)) - logging.info("Edges to process: {}".format(edgesToProcess)) + logging.info(f"Nodes to process: {edgesToProcess}") + logging.info(f"Edges to process: {edgesToProcess}") sub = None if submitter: @@ -1680,7 +1679,7 @@ def submitGraph(graph, submitter, toNodes=None, submitLabel="{projectName}"): for node in nodesToProcess: node.submit() # update node status except Exception as e: - logging.error("Error on submit : {}".format(e)) + logging.error(f"Error on submit : {e}") def submit(graphFile, submitter, toNode=None, submitLabel="{projectName}"): diff --git a/meshroom/core/node.py b/meshroom/core/node.py index 4deee8dd70..be6141e923 100644 --- a/meshroom/core/node.py +++ b/meshroom/core/node.py @@ -339,7 +339,7 @@ def index(self): @property def name(self): if self.range.blockSize: - return "{}({})".format(self.node.name, self.index) + return f"{self.node.name}({self.index})" else: return self.node.name @@ -479,7 +479,7 @@ def isFinished(self): def process(self, forceCompute=False, inCurrentEnv=False): if not forceCompute and self._status.status == Status.SUCCESS: - logging.info("Node chunk already computed: {}".format(self.name)) + logging.info(f"Node chunk already computed: {self.name}") return # Start the process environment for nodes running in isolation. @@ -517,7 +517,7 @@ def process(self, forceCompute=False, inCurrentEnv=False): if executionStatus: self.upgradeStatusTo(executionStatus) - logging.info(" - elapsed time: {}".format(self._status.elapsedTimeStr)) + logging.info(f" - elapsed time: {self._status.elapsedTimeStr}") # Ask and wait for the stats thread to stop self.statThread.stopRequest() self.statThread.join() @@ -735,7 +735,7 @@ def nameToLabel(self, name): str: the high-level label from the technical node name """ t, idx = name.split("_") - return "{}{}".format(t, idx if int(idx) > 1 else "") + return f"{t}{idx if int(idx) > 1 else ''}" def getDocumentation(self): if not self.nodeDesc: @@ -899,7 +899,7 @@ def _buildAttributeCmdVars(cmdVars, name, attr): if group is not None: # If there is a valid command line "group" v = attr.getValueStr(withQuotes=True) - cmdVars[name] = "--{name} {value}".format(name=name, value=v) + cmdVars[name] = f"--{name} {v}" # xxValue is exposed without quotes to allow to compose expressions cmdVars[name + "Value"] = attr.getValueStr(withQuotes=False) @@ -970,7 +970,7 @@ def _buildAttributeCmdVars(cmdVars, name, attr): v = attr.getValueStr(withQuotes=True) - self._cmdVars[name] = '--{name} {value}'.format(name=name, value=v) + self._cmdVars[name] = f'--{name} {v}' # xxValue is exposed without quotes to allow to compose expressions self._cmdVars[name + 'Value'] = attr.getValueStr(withQuotes=False) @@ -1307,7 +1307,7 @@ def loadOutputAttr(self): return valuesFile = self.valuesFile if not os.path.exists(valuesFile): - logging.warning("No output attr file: {}".format(valuesFile)) + logging.warning(f"No output attr file: {valuesFile}") return # logging.warning("load output attr: {}, value: {}".format(self.name, valuesFile)) @@ -1806,7 +1806,7 @@ def _updateChunks(self): chunk.range = range except RuntimeError: # TODO: set node internal status to error - logging.warning("Invalid Parallelization on node {}".format(self._name)) + logging.warning(f"Invalid Parallelization on node {self._name}") self._chunks.clear() else: if len(self._chunks) != 1: @@ -2001,7 +2001,7 @@ def _addAttribute(self, name, val, isOutput, internalAttr=False): @property def issueDetails(self): if self.issue == CompatibilityIssue.UnknownNodeType: - return "Unknown node type: '{}'.".format(self.nodeType) + return f"Unknown node type: '{self.nodeType}'." elif self.issue == CompatibilityIssue.VersionConflict: return "Node version '{}' conflicts with current version '{}'.".format( self.nodeDict["version"], nodeVersion(self.nodeDesc) @@ -2077,7 +2077,7 @@ def upgrade(self): try: upgradedAttrValues = node.nodeDesc.upgradeAttributeValues(attrValues, self.version) except Exception as e: - logging.error("Error in the upgrade implementation of the node: {}.\n{}".format(self.name, repr(e))) + logging.error(f"Error in the upgrade implementation of the node: {self.name}.\n{repr(e)}") upgradedAttrValues = attrValues if not isinstance(upgradedAttrValues, dict): diff --git a/meshroom/core/stats.py b/meshroom/core/stats.py index 7b031d3c71..1074cf64ee 100644 --- a/meshroom/core/stats.py +++ b/meshroom/core/stats.py @@ -24,8 +24,8 @@ def bytes2human(n): for s in reversed(symbols): if n >= prefix[s]: value = float(n) / prefix[s] - return '%.2f %s' % (value, s) - return '%.2f B' % (n) + return f'{value:.2f} {s}' + return f'{n:.2f} B' class ComputerStatistics: @@ -57,7 +57,7 @@ def initOnFirstTime(self): if self.nvidia_smi is None: # Could not be found from the environment path, # try to find it from system drive with default installation path - default_nvidia_smi = "%s\\Program Files\\NVIDIA Corporation\\NVSMI\\nvidia-smi.exe" % os.environ['systemdrive'] + default_nvidia_smi = f"{os.environ['systemdrive']}\\Program Files\\NVIDIA Corporation\\NVSMI\\nvidia-smi.exe" if os.path.isfile(default_nvidia_smi): self.nvidia_smi = default_nvidia_smi else: @@ -84,7 +84,7 @@ def update(self): self._addKV('ioCounters', psutil.disk_io_counters()) self.updateGpu() except Exception as e: - logging.debug('Failed to get statistics: "{}".'.format(str(e))) + logging.debug(f'Failed to get statistics: "{str(e)}".') def updateGpu(self): if not self.nvidia_smi: @@ -99,38 +99,38 @@ def updateGpu(self): try: self.gpuName = gpuTree.find('product_name').text except Exception as e: - logging.debug('Failed to get gpuName: "{}".'.format(str(e))) + logging.debug(f'Failed to get gpuName: "{str(e)}".') pass try: gpuMemoryUsed = gpuTree.find('fb_memory_usage').find('used').text.split(" ")[0] self._addKV('gpuMemoryUsed', gpuMemoryUsed) except Exception as e: - logging.debug('Failed to get gpuMemoryUsed: "{}".'.format(str(e))) + logging.debug(f'Failed to get gpuMemoryUsed: "{str(e)}".') pass try: self.gpuMemoryTotal = gpuTree.find('fb_memory_usage').find('total').text.split(" ")[0] except Exception as e: - logging.debug('Failed to get gpuMemoryTotal: "{}".'.format(str(e))) + logging.debug(f'Failed to get gpuMemoryTotal: "{str(e)}".') pass try: gpuUsed = gpuTree.find('utilization').find('gpu_util').text.split(" ")[0] self._addKV('gpuUsed', gpuUsed) except Exception as e: - logging.debug('Failed to get gpuUsed: "{}".'.format(str(e))) + logging.debug(f'Failed to get gpuUsed: "{str(e)}".') pass try: gpuTemperature = gpuTree.find('temperature').find('gpu_temp').text.split(" ")[0] self._addKV('gpuTemperature', gpuTemperature) except Exception as e: - logging.debug('Failed to get gpuTemperature: "{}".'.format(str(e))) + logging.debug(f'Failed to get gpuTemperature: "{str(e)}".') pass except subprocess.TimeoutExpired as e: - logging.debug('Timeout when retrieving information from nvidia_smi: "{}".'.format(str(e))) + logging.debug(f'Timeout when retrieving information from nvidia_smi: "{str(e)}".') p.kill() outs, errs = p.communicate() return except Exception as e: - logging.debug('Failed to get information from nvidia_smi: "{}".'.format(str(e))) + logging.debug(f'Failed to get information from nvidia_smi: "{str(e)}".') return def toDict(self): @@ -263,22 +263,22 @@ def toDict(self): def fromDict(self, d): version = d.get('fileVersion', 0.0) if version != self.fileVersion: - logging.debug('Statistics: file version was {} and the current version is {}.'.format(version, self.fileVersion)) + logging.debug(f'Statistics: file version was {version} and the current version is {self.fileVersion}.') self.computer = ComputerStatistics() self.process = ProcStatistics() self.times = [] try: self.computer.fromDict(d.get('computer', {})) except Exception as e: - logging.debug('Failed while loading statistics: computer: "{}".'.format(str(e))) + logging.debug(f'Failed while loading statistics: computer: "{str(e)}".') try: self.process.fromDict(d.get('process', {})) except Exception as e: - logging.debug('Failed while loading statistics: process: "{}".'.format(str(e))) + logging.debug(f'Failed while loading statistics: process: "{str(e)}".') try: self.times = d.get('times', []) except Exception as e: - logging.debug('Failed while loading statistics: times: "{}".'.format(str(e))) + logging.debug(f'Failed while loading statistics: times: "{str(e)}".') bytesPerGiga = 1024. * 1024. * 1024. diff --git a/meshroom/core/taskManager.py b/meshroom/core/taskManager.py index 7d9c52b1fa..8d2b64f6bb 100644 --- a/meshroom/core/taskManager.py +++ b/meshroom/core/taskManager.py @@ -426,8 +426,8 @@ def submit(self, graph, submitter=None, toNodes=None, submitLabel="{projectName} flowEdges = graph.flowEdges(startNodes=toNodes) edgesToProcess = set(edgesToProcess).intersection(flowEdges) - logging.info("Nodes to process: {}".format(nodesToProcess)) - logging.info("Edges to process: {}".format(edgesToProcess)) + logging.info(f"Nodes to process: {nodesToProcess}") + logging.info(f"Edges to process: {edgesToProcess}") try: res = sub.submit(nodesToProcess, edgesToProcess, graph.filepath, submitLabel=submitLabel) @@ -442,7 +442,7 @@ def submit(self, graph, submitter=None, toNodes=None, submitLabel="{projectName} if not allReady: self.raiseDependenciesMessage("SUBMITTING") except Exception as e: - logging.error("Error on submit : {}".format(e)) + logging.error(f"Error on submit : {e}") def submitFromFile(self, graphFile, submitter, toNode=None, submitLabel="{projectName}"): """ diff --git a/meshroom/core/test.py b/meshroom/core/test.py index 85e7a021b7..cec7b774a7 100644 --- a/meshroom/core/test.py +++ b/meshroom/core/test.py @@ -54,7 +54,7 @@ def checkTemplateVersions(path: str, nodesAlreadyLoaded: bool = False) -> bool: break if compatibilityIssue is not None: - print("{} in {} for node {}".format(compatibilityIssue, path, nodeType)) + print(f"{compatibilityIssue} in {path} for node {nodeType}") return False return True diff --git a/meshroom/multiview.py b/meshroom/multiview.py index bf5f4224f6..c8c84e9c49 100644 --- a/meshroom/multiview.py +++ b/meshroom/multiview.py @@ -161,7 +161,7 @@ def mvsPipeline(graph, sfm=None): list of Node: the created nodes """ if sfm and not sfm.nodeType == "StructureFromMotion": - raise ValueError("Invalid node type. Expected StructureFromMotion, got {}.".format(sfm.nodeType)) + raise ValueError(f"Invalid node type. Expected StructureFromMotion, got {sfm.nodeType}.") prepareDenseScene = graph.addNewNode('PrepareDenseScene', input=sfm.output if sfm else "") diff --git a/meshroom/nodes/general/Publish.py b/meshroom/nodes/general/Publish.py index 2d41ef1336..8110b2cf64 100644 --- a/meshroom/nodes/general/Publish.py +++ b/meshroom/nodes/general/Publish.py @@ -71,7 +71,7 @@ def processChunk(self, chunk): if not outFiles: error = 'Publish: input files listed, but nothing to publish' chunk.logger.error(error) - chunk.logger.info('Listed input files: {}'.format([i.value for i in chunk.node.inputFiles.value])) + chunk.logger.info(f'Listed input files: {[i.value for i in chunk.node.inputFiles.value]}') raise RuntimeError(error) if not os.path.exists(chunk.node.output.value): @@ -79,10 +79,10 @@ def processChunk(self, chunk): for iFile, oFile in outFiles.items(): if os.path.isdir(iFile): # If the input is a directory, copy the directory's content - chunk.logger.info('Publish directory {} into {}'.format(iFile, oFile)) + chunk.logger.info(f'Publish directory {iFile} into {oFile}') du.copy_tree(iFile, oFile) else: - chunk.logger.info('Publish file {} into {}'.format(iFile, oFile)) + chunk.logger.info(f'Publish file {iFile} into {oFile}') shutil.copyfile(iFile, oFile) chunk.logger.info('Publish end') finally: diff --git a/meshroom/submitters/simpleFarmSubmitter.py b/meshroom/submitters/simpleFarmSubmitter.py index 2628c29164..04a6b6d954 100644 --- a/meshroom/submitters/simpleFarmSubmitter.py +++ b/meshroom/submitters/simpleFarmSubmitter.py @@ -46,9 +46,9 @@ def __init__(self, parent=None): continue v = p.split('-') self.reqPackages.append('-'.join([v[0], resolvedVersions[v[0]]])) - logging.debug('REZ Packages: {}'.format(str(self.reqPackages))) + logging.debug(f'REZ Packages: {str(self.reqPackages)}') elif 'REZ_MESHROOM_VERSION' in os.environ: - self.reqPackages = ["meshroom-{}".format(os.environ.get('REZ_MESHROOM_VERSION', ''))] + self.reqPackages = [f"meshroom-{os.environ.get('REZ_MESHROOM_VERSION', '')}"] else: self.reqPackages = None diff --git a/meshroom/ui/app.py b/meshroom/ui/app.py index 11f921b42d..3d5addd3d3 100644 --- a/meshroom/ui/app.py +++ b/meshroom/ui/app.py @@ -372,13 +372,13 @@ def _retrieveThumbnailPath(self, filepath: str) -> str: return viewpoints[0].get("path", "") except FileNotFoundError: - logging.info("File {} not found on disk.".format(filepath)) + logging.info(f"File {filepath} not found on disk.") except (json.JSONDecodeError, UnicodeDecodeError): - logging.info("Error while loading file {}.".format(filepath)) + logging.info(f"Error while loading file {filepath}.") except KeyError as err: - logging.info("The following key does not exist: {}".format(str(err))) + logging.info(f"The following key does not exist: {str(err)}") except Exception as err: - logging.info("Exception: {}".format(str(err))) + logging.info(f"Exception: {str(err)}") return "" @@ -436,7 +436,7 @@ def addRecentProjectFile(self, projectFile) -> None: projectFile (str or QUrl): path to the project file to add to the list """ if not isinstance(projectFile, (QUrl, str)): - raise TypeError("Unexpected data type: {}".format(projectFile.__class__)) + raise TypeError(f"Unexpected data type: {projectFile.__class__}") if isinstance(projectFile, QUrl): projectFileNorm = projectFile.toLocalFile() if not projectFileNorm: @@ -488,7 +488,7 @@ def removeRecentProjectFile(self, projectFile) -> None: Otherwise, it is effectively removed and the QSettings are updated accordingly. """ if not isinstance(projectFile, (QUrl, str)): - raise TypeError("Unexpected data type: {}".format(projectFile.__class__)) + raise TypeError(f"Unexpected data type: {projectFile.__class__}") if isinstance(projectFile, QUrl): projectFileNorm = projectFile.toLocalFile() if not projectFileNorm: @@ -544,7 +544,7 @@ def addRecentImportedImagesFolder(self, imagesFolder): if not folderPath: folderPath = imagesFolder.toString() else: - raise TypeError("Unexpected data type: {}".format(imagesFolder.__class__)) + raise TypeError(f"Unexpected data type: {imagesFolder.__class__}") folders = self._recentImportedImagesFolders() @@ -579,7 +579,7 @@ def removeRecentImportedImagesFolder(self, imagesFolder): if not folderPath: folderPath = imagesFolder.toString() else: - raise TypeError("Unexpected data type: {}".format(imagesFolder.__class__)) + raise TypeError(f"Unexpected data type: {imagesFolder.__class__}") folders = self._recentImportedImagesFolders() @@ -626,9 +626,9 @@ def _systemInfo(self): import platform import sys return { - 'platform': '{} {}'.format(platform.system(), platform.release()), - 'python': 'Python {}'.format(sys.version.split(" ")[0]), - 'pyside': 'PySide6 {}'.format(PySideVersion) + 'platform': f'{platform.system()} {platform.release()}', + 'python': f"Python {sys.version.split(' ')[0]}", + 'pyside': f'PySide6 {PySideVersion}' } systemInfo = Property(QJsonValue, _systemInfo, constant=True) diff --git a/meshroom/ui/commands.py b/meshroom/ui/commands.py index 424fad1e09..dfd221e607 100755 --- a/meshroom/ui/commands.py +++ b/meshroom/ui/commands.py @@ -26,7 +26,7 @@ def redo(self): try: self.redoImpl() except Exception: - logging.error("Error while redoing command '{}': \n{}".format(self.text(), traceback.format_exc())) + logging.error(f"Error while redoing command '{self.text()}': \n{traceback.format_exc()}") def undo(self): if not self._enabled: @@ -34,7 +34,7 @@ def undo(self): try: self.undoImpl() except Exception: - logging.error("Error while undoing command '{}': \n{}".format(self.text(), traceback.format_exc())) + logging.error(f"Error while undoing command '{self.text()}': \n{traceback.format_exc()}") def redoImpl(self): # type: () -> bool @@ -64,7 +64,7 @@ def tryAndPush(self, command): try: res = command.redoImpl() except Exception as e: - logging.error("Error while trying command '{}': \n{}".format(command.text(), traceback.format_exc())) + logging.error(f"Error while trying command '{command.text()}': \n{traceback.format_exc()}") res = False if res is not False: command.setEnabled(False) @@ -144,7 +144,7 @@ def __init__(self, graph, nodeType, position, parent=None, **kwargs): def redoImpl(self): node = self.graph.addNewNode(self.nodeType, position=self.position, **self.kwargs) self.nodeName = node.name - self.setText("Add Node {}".format(self.nodeName)) + self.setText(f"Add Node {self.nodeName}") return node def undoImpl(self): @@ -156,7 +156,7 @@ def __init__(self, graph, node, parent=None): super(RemoveNodeCommand, self).__init__(graph, parent) self.nodeDict = node.toDict() self.nodeName = node.getName() - self.setText("Remove Node {}".format(self.nodeName)) + self.setText(f"Remove Node {self.nodeName}") self.outEdges = {} self.outListAttributes = {} # maps attribute's key with a tuple containing the name of the list it is connected to and its value @@ -221,7 +221,7 @@ def redoImpl(self): nodes = self.graph.importGraphContent(graph) self.nodeNames = [node.name for node in nodes] - self.setText("Paste Node{} ({})".format("s" if len(self.nodeNames) > 1 else "", ", ".join(self.nodeNames))) + self.setText(f"Paste Node{'s' if len(self.nodeNames) > 1 else ''} ({', '.join(self.nodeNames)})") return nodes def undoImpl(self): @@ -289,7 +289,7 @@ def __init__(self, graph, attribute, value, parent=None): self.attrName = attribute.getFullNameToNode() self.value = value self.oldValue = attribute.getExportValue() - self.setText("Set Attribute '{}'".format(attribute.getFullNameToNode())) + self.setText(f"Set Attribute '{attribute.getFullNameToNode()}'") def redoImpl(self): if self.value == self.oldValue: @@ -312,10 +312,10 @@ def __init__(self, graph, src, dst, parent=None): super(AddEdgeCommand, self).__init__(graph, parent) self.srcAttr = src.getFullNameToNode() self.dstAttr = dst.getFullNameToNode() - self.setText("Connect '{}'->'{}'".format(self.srcAttr, self.dstAttr)) + self.setText(f"Connect '{self.srcAttr}'->'{self.dstAttr}'") if src.baseType != dst.baseType: - raise ValueError("Attribute types are not compatible and cannot be connected: '{}'({})->'{}'({})".format(self.srcAttr, src.baseType, self.dstAttr, dst.baseType)) + raise ValueError(f"Attribute types are not compatible and cannot be connected: '{self.srcAttr}'({src.baseType})->'{self.dstAttr}'({dst.baseType})") def redoImpl(self): self.graph.addEdge(self.graph.attribute(self.srcAttr), self.graph.attribute(self.dstAttr)) @@ -330,7 +330,7 @@ def __init__(self, graph, edge, parent=None): super(RemoveEdgeCommand, self).__init__(graph, parent) self.srcAttr = edge.src.getFullNameToNode() self.dstAttr = edge.dst.getFullNameToNode() - self.setText("Disconnect '{}'->'{}'".format(self.srcAttr, self.dstAttr)) + self.setText(f"Disconnect '{self.srcAttr}'->'{self.dstAttr}'") def redoImpl(self): self.graph.removeEdge(self.graph.attribute(self.dstAttr)) @@ -349,7 +349,7 @@ def __init__(self, graph, listAttribute, value, parent=None): self.index = None self.count = 1 self.value = value if value else None - self.setText("Append to {}".format(self.attrName)) + self.setText(f"Append to {self.attrName}") def redoImpl(self): listAttribute = self.graph.attribute(self.attrName) @@ -374,7 +374,7 @@ def __init__(self, graph, attribute, parent=None): self.listAttrName = listAttribute.getFullNameToNode() self.index = listAttribute.index(attribute) self.value = attribute.getExportValue() - self.setText("Remove {}".format(attribute.getFullNameToNode())) + self.setText(f"Remove {attribute.getFullNameToNode()}") def redoImpl(self): listAttribute = self.graph.attribute(self.listAttrName) @@ -392,7 +392,7 @@ def __init__(self, graph, cameraInitNodes, parent=None): self.cameraInits = cameraInitNodes self.viewpoints = { cameraInit.name: cameraInit.attribute("viewpoints").getExportValue() for cameraInit in self.cameraInits } self.intrinsics = { cameraInit.name: cameraInit.attribute("intrinsics").getExportValue() for cameraInit in self.cameraInits } - self.title = "Remove{}Images".format(" " if len(self.cameraInits) == 1 else " All ") + self.title = f"Remove{' ' if len(self.cameraInits) == 1 else ' All '}Images" self.setText(self.title) def redoImpl(self): @@ -421,7 +421,7 @@ def __init__(self, graph, node, position, parent=None): self.nodeName = node.name self.oldPosition = node.position self.newPosition = position - self.setText("Move {}".format(self.nodeName)) + self.setText(f"Move {self.nodeName}") def redoImpl(self): self.graph.node(self.nodeName).position = self.newPosition @@ -440,7 +440,7 @@ def __init__(self, graph, node, parent=None): self.nodeDict = node.toDict() self.nodeName = node.getName() self.compatibilityIssue = None - self.setText("Upgrade Node {}".format(self.nodeName)) + self.setText(f"Upgrade Node {self.nodeName}") def redoImpl(self): if not (node := self.graph.node(self.nodeName)).canUpgrade: diff --git a/meshroom/ui/components/csvData.py b/meshroom/ui/components/csvData.py index f52cabe991..eae5faf6c4 100644 --- a/meshroom/ui/components/csvData.py +++ b/meshroom/ui/components/csvData.py @@ -77,7 +77,7 @@ def read(self): for idx, value in enumerate(elt): dataList[idx].appendValue(value) except Exception as e: - logging.error("CsvData: Failed to load file: {}\n{}".format(self._filepath, str(e))) + logging.error(f"CsvData: Failed to load file: {self._filepath}\n{str(e)}") return dataList diff --git a/meshroom/ui/components/filepath.py b/meshroom/ui/components/filepath.py index c46fe29ea0..bb30153195 100644 --- a/meshroom/ui/components/filepath.py +++ b/meshroom/ui/components/filepath.py @@ -28,7 +28,7 @@ def asStr(path): str: String representation of 'path' """ if not isinstance(path, (QUrl, str)): - raise TypeError("Unexpected data type: {}".format(path.__class__)) + raise TypeError(f"Unexpected data type: {path.__class__}") if isinstance(path, QUrl): path = path.toLocalFile() return path diff --git a/meshroom/ui/graph.py b/meshroom/ui/graph.py index 754faf3a03..23457125f8 100644 --- a/meshroom/ui/graph.py +++ b/meshroom/ui/graph.py @@ -849,14 +849,14 @@ def addEdge(self, src, dst): if isinstance(src, ListAttribute) and not isinstance(dst, ListAttribute): self._addEdge(src.at(0), dst) elif isinstance(dst, ListAttribute) and not isinstance(src, ListAttribute): - with self.groupedGraphModification("Insert and Add Edge on {}".format(dst.getFullNameToNode())): + with self.groupedGraphModification(f"Insert and Add Edge on {dst.getFullNameToNode()}"): self.appendAttribute(dst) self._addEdge(src, dst.at(-1)) else: self._addEdge(src, dst) def _addEdge(self, src, dst): - with self.groupedGraphModification("Connect '{}'->'{}'".format(src.getFullNameToNode(), dst.getFullNameToNode())): + with self.groupedGraphModification(f"Connect '{src.getFullNameToNode()}'->'{dst.getFullNameToNode()}'"): if dst in self._graph.edges.keys(): self.removeEdge(self._graph.edge(dst)) self.push(commands.AddEdgeCommand(self._graph, src, dst)) @@ -864,7 +864,7 @@ def _addEdge(self, src, dst): @Slot(Edge) def removeEdge(self, edge): if isinstance(edge.dst.root, ListAttribute): - with self.groupedGraphModification("Remove Edge and Delete {}".format(edge.dst.getFullNameToNode())): + with self.groupedGraphModification(f"Remove Edge and Delete {edge.dst.getFullNameToNode()}"): self.push(commands.RemoveEdgeCommand(self._graph, edge)) self.removeAttribute(edge.dst) else: @@ -872,7 +872,7 @@ def removeEdge(self, edge): @Slot(Edge, Attribute, Attribute, result=Edge) def replaceEdge(self, edge, newSrc, newDst): - with self.groupedGraphModification("Replace Edge '{}'->'{}' with '{}'->'{}'".format(edge.src.getFullNameToNode(), edge.dst.getFullNameToNode(), newSrc.getFullNameToNode(), newDst.getFullNameToNode())): + with self.groupedGraphModification(f"Replace Edge '{edge.src.getFullNameToNode()}'->'{edge.dst.getFullNameToNode()}' with '{newSrc.getFullNameToNode()}'->'{newDst.getFullNameToNode()}'"): self.removeEdge(edge) self.addEdge(newSrc, newDst) return self._graph.edge(newDst) @@ -888,7 +888,7 @@ def setAttribute(self, attribute, value): @Slot(Attribute) def resetAttribute(self, attribute): """ Reset 'attribute' to its default value """ - with self.groupedGraphModification("Reset Attribute '{}'".format(attribute.name)): + with self.groupedGraphModification(f"Reset Attribute '{attribute.name}'"): # if the attribute is a ListAttribute, remove all edges if isinstance(attribute, ListAttribute): for edge in self._graph.edges: diff --git a/meshroom/ui/qml/MaterialIcons/generate_material_icons.py b/meshroom/ui/qml/MaterialIcons/generate_material_icons.py index d5cf5ecf66..73293510ac 100644 --- a/meshroom/ui/qml/MaterialIcons/generate_material_icons.py +++ b/meshroom/ui/qml/MaterialIcons/generate_material_icons.py @@ -54,5 +54,5 @@ name = name + str(index) names.append(name) - qml_file.write(' readonly property string {}: "\\u{}"\n'.format(name, code)) + qml_file.write(f' readonly property string {name}: "\\u{code}\"\n') qml_file.write('}\n') diff --git a/meshroom/ui/reconstruction.py b/meshroom/ui/reconstruction.py index ae3053fb9b..b31489bd15 100755 --- a/meshroom/ui/reconstruction.py +++ b/meshroom/ui/reconstruction.py @@ -84,7 +84,7 @@ def start(self, folder, minImagesPerStep): """ # print('[LiveSfmManager] Watching {} for images'.format(folder)) if not os.path.isdir(folder): - raise RuntimeError("Invalid folder provided: {}".format(folder)) + raise RuntimeError(f"Invalid folder provided: {folder}") self._folder = folder self.folderChanged.emit() self.cameraInit = self.sfm = None @@ -231,7 +231,7 @@ def _updateInitialParams(self): # When the viewpoint attribute has already been deleted, metadata.value becomes a PySide property (whereas a string is expected) self._metadata = json.loads(self._viewpoint.metadata.value) if isinstance(self._viewpoint.metadata.value, str) and self._viewpoint.metadata.value else None except Exception as e: - logging.warning("Failed to parse Viewpoint metadata: '{}', '{}'".format(str(e), str(self._viewpoint.metadata.value))) + logging.warning(f"Failed to parse Viewpoint metadata: '{str(e)}', '{str(self._viewpoint.metadata.value)}'") self._metadata = {} if not self._metadata: self._metadata = {} @@ -587,22 +587,22 @@ def _loadWithErrorReport(self, loadFunction: Callable[[str], None], filepath: st self.error.emit( Message( "No Such File", - "Error While Loading '{}': No Such File.".format(os.path.basename(filepath)), + f"Error While Loading '{os.path.basename(filepath)}': No Such File.", "" ) ) - logging.error("Error while loading '{}': No Such File.".format(filepath)) + logging.error(f"Error while loading '{filepath}': No Such File.") except Exception: import traceback trace = traceback.format_exc() self.error.emit( Message( "Error While Loading Project File", - "An unexpected error has occurred while loading file: '{}'".format(os.path.basename(filepath)), + f"An unexpected error has occurred while loading file: '{os.path.basename(filepath)}'", trace ) ) - logging.error("Error while loading '{}'.".format(filepath)) + logging.error(f"Error while loading '{filepath}'.") logging.error(trace) return False @@ -825,9 +825,9 @@ def handleFilesUrl(self, filesByType, cameraInit=None, position=None): keyframeNode = self.addNewNode("KeyframeSelection", position=p) keyframeNode.inputPaths.value = filesByType["videos"] if len(filesByType["videos"]) == 1: - newVideoNodeMessage = "New node '{}' added for the input video.".format(keyframeNode.getLabel()) + newVideoNodeMessage = f"New node '{keyframeNode.getLabel()}' added for the input video." else: - newVideoNodeMessage = "New node '{}' added for a rig of {} synchronized cameras.".format(keyframeNode.getLabel(), len(filesByType["videos"])) + newVideoNodeMessage = f"New node '{keyframeNode.getLabel()}' added for a rig of {len(filesByType['videos'])} synchronized cameras." self.info.emit( Message( "Video Input", @@ -856,13 +856,13 @@ def handleFilesUrl(self, filesByType, cameraInit=None, position=None): Message( "Panorama XML", "XML file declared on PanoramaInit node", - "XML file '{}' set on node '{}'".format(','.join(filesByType["panoramaInfo"]), ','.join([n.getLabel() for n in panoramaInitNodes])), + f"XML file '{','.join(filesByType['panoramaInfo'])}' set on node '{','.join([n.getLabel() for n in panoramaInitNodes])}'", )) else: self.error.emit( Message( "No PanoramaInit Node", - "No PanoramaInit Node to set the Panorama file:\n'{}'.".format(','.join(filesByType["panoramaInfo"])), + f"No PanoramaInit Node to set the Panorama file:\n'{','.join(filesByType['panoramaInfo'])}'.", "", )) @@ -885,7 +885,7 @@ def handleFilesUrl(self, filesByType, cameraInit=None, position=None): self.error.emit( Message( "No Recognized Input File", - "No recognized input file in the {} dropped files".format(len(filesByType["other"])), + f"No recognized input file in the {len(filesByType['other'])} dropped files", "Unknown file extensions: " + ', '.join(extensions) ) ) @@ -994,7 +994,7 @@ def buildIntrinsics(self, cameraInit, additionalViews, rebuild=False): # Retrieve the list of updated viewpoints and intrinsics views, intrinsics = cameraInitCopy.nodeDesc.buildIntrinsics(cameraInitCopy, additionalViews) except Exception as e: - logging.error("Error while building intrinsics: {}".format(str(e))) + logging.error(f"Error while building intrinsics: {str(e)}") raise finally: # Delete the duplicate @@ -1028,7 +1028,7 @@ def onIntrinsicsAvailable(self, cameraInit, views, intrinsics, rebuild=False): commandTitle = "Augment Reconstruction ({} Images)" if rebuild: - commandTitle = "Rebuild '{}' Intrinsics".format(cameraInit.label) + commandTitle = f"Rebuild '{cameraInit.label}' Intrinsics" # No additional views: early return if not views: diff --git a/meshroom/ui/utils.py b/meshroom/ui/utils.py index 5e6339ec19..9bbfd2393d 100755 --- a/meshroom/ui/utils.py +++ b/meshroom/ui/utils.py @@ -102,7 +102,7 @@ def addFile(self, filename): # Make sure the file exists if not os.path.isfile(filename): - raise ValueError("addFile: file %s doesn't exist." % filename) + raise ValueError(f"addFile: file {filename} doesn't exist.") # Return if the file is already in our internal list if filename in self._watchedFiles: @@ -135,7 +135,7 @@ def addFilesFromDirectory(self, dirname, recursive=False): recursive -- if True, will search inside each subdirectories recursively. """ if not os.path.isdir(dirname): - raise RuntimeError("addFilesFromDirectory : %s is not a valid directory." % dirname) + raise RuntimeError(f"addFilesFromDirectory : {dirname} is not a valid directory.") if recursive: for dirpath, dirnames, filenames in os.walk(dirname): @@ -193,7 +193,7 @@ def onFileChanged(self, filepath): QTimer.singleShot(200, lambda: self.addFile(filepath)) def reload(self): - print("Reloading {}".format(self._sourceFile)) + print(f"Reloading {self._sourceFile}") self.load(self._sourceFile) From 22b2161ddde7d8bf472a33b49a9aa25f16d5b570 Mon Sep 17 00:00:00 2001 From: Fabien Castan Date: Mon, 14 Apr 2025 11:09:12 +0200 Subject: [PATCH 2/4] No need for explicit string conversion --- meshroom/core/__init__.py | 2 +- meshroom/core/graph.py | 2 +- meshroom/core/stats.py | 22 +++++++++++----------- meshroom/ui/components/csvData.py | 2 +- meshroom/ui/reconstruction.py | 4 ++-- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/meshroom/core/__init__.py b/meshroom/core/__init__.py index 4d948543e8..0178f34dad 100644 --- a/meshroom/core/__init__.py +++ b/meshroom/core/__init__.py @@ -111,7 +111,7 @@ def loadClasses(folder, packageName, classType): except Exception as e: tb = traceback.extract_tb(e.__traceback__) last_call = tb[-1] - errors.append(f' * {pluginName} ({type(e).__name__}): {str(e)}\n' + errors.append(f' * {pluginName} ({type(e).__name__}): {e}\n' # filename:lineNumber functionName f'{last_call.filename}:{last_call.lineno} {last_call.name}\n' # line of code with the error diff --git a/meshroom/core/graph.py b/meshroom/core/graph.py index 90440ea8a3..5384f5ae1b 100644 --- a/meshroom/core/graph.py +++ b/meshroom/core/graph.py @@ -751,7 +751,7 @@ def _recreateTargetListAttributeChildren(listAttrName: str, index: int, value: A try: self.addEdge(self.attribute(srcName), self.attribute(dstName)) except (KeyError, ValueError) as e: - logging.warning(f"Failed to restore edge {srcName} -> {dstName}: {str(e)}") + logging.warning(f"Failed to restore edge {srcName} -> {dstName}: {e}") def upgradeAllNodes(self): """ Upgrade all upgradable CompatibilityNode instances in the graph. """ diff --git a/meshroom/core/stats.py b/meshroom/core/stats.py index 1074cf64ee..a7d296426b 100644 --- a/meshroom/core/stats.py +++ b/meshroom/core/stats.py @@ -84,7 +84,7 @@ def update(self): self._addKV('ioCounters', psutil.disk_io_counters()) self.updateGpu() except Exception as e: - logging.debug(f'Failed to get statistics: "{str(e)}".') + logging.debug(f'Failed to get statistics: "{e}".') def updateGpu(self): if not self.nvidia_smi: @@ -99,38 +99,38 @@ def updateGpu(self): try: self.gpuName = gpuTree.find('product_name').text except Exception as e: - logging.debug(f'Failed to get gpuName: "{str(e)}".') + logging.debug(f'Failed to get gpuName: "{e}".') pass try: gpuMemoryUsed = gpuTree.find('fb_memory_usage').find('used').text.split(" ")[0] self._addKV('gpuMemoryUsed', gpuMemoryUsed) except Exception as e: - logging.debug(f'Failed to get gpuMemoryUsed: "{str(e)}".') + logging.debug(f'Failed to get gpuMemoryUsed: "{e}".') pass try: self.gpuMemoryTotal = gpuTree.find('fb_memory_usage').find('total').text.split(" ")[0] except Exception as e: - logging.debug(f'Failed to get gpuMemoryTotal: "{str(e)}".') + logging.debug(f'Failed to get gpuMemoryTotal: "{e}".') pass try: gpuUsed = gpuTree.find('utilization').find('gpu_util').text.split(" ")[0] self._addKV('gpuUsed', gpuUsed) except Exception as e: - logging.debug(f'Failed to get gpuUsed: "{str(e)}".') + logging.debug(f'Failed to get gpuUsed: "{e}".') pass try: gpuTemperature = gpuTree.find('temperature').find('gpu_temp').text.split(" ")[0] self._addKV('gpuTemperature', gpuTemperature) except Exception as e: - logging.debug(f'Failed to get gpuTemperature: "{str(e)}".') + logging.debug(f'Failed to get gpuTemperature: "{e}".') pass except subprocess.TimeoutExpired as e: - logging.debug(f'Timeout when retrieving information from nvidia_smi: "{str(e)}".') + logging.debug(f'Timeout when retrieving information from nvidia_smi: "{e}".') p.kill() outs, errs = p.communicate() return except Exception as e: - logging.debug(f'Failed to get information from nvidia_smi: "{str(e)}".') + logging.debug(f'Failed to get information from nvidia_smi: "{e}".') return def toDict(self): @@ -270,15 +270,15 @@ def fromDict(self, d): try: self.computer.fromDict(d.get('computer', {})) except Exception as e: - logging.debug(f'Failed while loading statistics: computer: "{str(e)}".') + logging.debug(f'Failed while loading statistics: computer: "{e}".') try: self.process.fromDict(d.get('process', {})) except Exception as e: - logging.debug(f'Failed while loading statistics: process: "{str(e)}".') + logging.debug(f'Failed while loading statistics: process: "{e}".') try: self.times = d.get('times', []) except Exception as e: - logging.debug(f'Failed while loading statistics: times: "{str(e)}".') + logging.debug(f'Failed while loading statistics: times: "{e}".') bytesPerGiga = 1024. * 1024. * 1024. diff --git a/meshroom/ui/components/csvData.py b/meshroom/ui/components/csvData.py index eae5faf6c4..9095cafe55 100644 --- a/meshroom/ui/components/csvData.py +++ b/meshroom/ui/components/csvData.py @@ -77,7 +77,7 @@ def read(self): for idx, value in enumerate(elt): dataList[idx].appendValue(value) except Exception as e: - logging.error(f"CsvData: Failed to load file: {self._filepath}\n{str(e)}") + logging.error(f"CsvData: Failed to load file: {self._filepath}\n{e}") return dataList diff --git a/meshroom/ui/reconstruction.py b/meshroom/ui/reconstruction.py index b31489bd15..6022993f21 100755 --- a/meshroom/ui/reconstruction.py +++ b/meshroom/ui/reconstruction.py @@ -231,7 +231,7 @@ def _updateInitialParams(self): # When the viewpoint attribute has already been deleted, metadata.value becomes a PySide property (whereas a string is expected) self._metadata = json.loads(self._viewpoint.metadata.value) if isinstance(self._viewpoint.metadata.value, str) and self._viewpoint.metadata.value else None except Exception as e: - logging.warning(f"Failed to parse Viewpoint metadata: '{str(e)}', '{str(self._viewpoint.metadata.value)}'") + logging.warning(f"Failed to parse Viewpoint metadata: '{e}', '{str(self._viewpoint.metadata.value)}'") self._metadata = {} if not self._metadata: self._metadata = {} @@ -994,7 +994,7 @@ def buildIntrinsics(self, cameraInit, additionalViews, rebuild=False): # Retrieve the list of updated viewpoints and intrinsics views, intrinsics = cameraInitCopy.nodeDesc.buildIntrinsics(cameraInitCopy, additionalViews) except Exception as e: - logging.error(f"Error while building intrinsics: {str(e)}") + logging.error(f"Error while building intrinsics: {e}") raise finally: # Delete the duplicate From 41738f7f405342a5cedf26cfc7d06d86fe1eb310 Mon Sep 17 00:00:00 2001 From: Fabien Castan Date: Wed, 30 Apr 2025 19:18:06 +0200 Subject: [PATCH 3/4] Modernize to python-3.9+ with pyupgrade (--py39-plus) --- bin/meshroom_batch | 16 +++---- bin/meshroom_newNodeType | 55 +++++++++++----------- bin/meshroom_statistics | 4 +- bin/meshroom_status | 8 ++-- meshroom/common/PySignal.py | 8 ++-- meshroom/common/core.py | 6 +-- meshroom/common/qt.py | 12 ++--- meshroom/core/__init__.py | 12 ++--- meshroom/core/attribute.py | 21 ++++----- meshroom/core/cgroup.py | 9 ++-- meshroom/core/exception.py | 5 +- meshroom/core/graph.py | 31 ++++++------ meshroom/core/graphIO.py | 4 +- meshroom/core/node.py | 25 +++++----- meshroom/core/nodeFactory.py | 3 +- meshroom/core/submitter.py | 3 +- meshroom/core/taskManager.py | 4 +- meshroom/core/test.py | 1 - meshroom/submitters/__init__.py | 1 - meshroom/submitters/simpleFarmSubmitter.py | 3 +- meshroom/ui/app.py | 4 +- meshroom/ui/commands.py | 34 ++++++------- meshroom/ui/graph.py | 12 ++--- meshroom/ui/palette.py | 2 +- meshroom/ui/reconstruction.py | 18 +++---- meshroom/ui/utils.py | 4 +- 26 files changed, 148 insertions(+), 157 deletions(-) diff --git a/bin/meshroom_batch b/bin/meshroom_batch index 02eed31ba9..4c5ef9e6c9 100755 --- a/bin/meshroom_batch +++ b/bin/meshroom_batch @@ -152,7 +152,7 @@ graph = meshroom.core.graph.Graph(name=args.pipeline) with meshroom.core.graph.GraphModification(graph): # initialize template pipeline - loweredPipelineTemplates = dict((k.lower(), v) for k, v in meshroom.core.pipelineTemplates.items()) + loweredPipelineTemplates = {k.lower(): v for k, v in meshroom.core.pipelineTemplates.items()} if args.pipeline.lower() in loweredPipelineTemplates: graph.initFromTemplate(loweredPipelineTemplates[args.pipeline.lower()], publishOutputs=True if args.output else False) else: @@ -232,7 +232,7 @@ with meshroom.core.graph.GraphModification(graph): raise RuntimeError("meshroom_batch requires a pipeline graph with at least one Publish node, none found.") if args.overrides: - with open(args.overrides, 'r', encoding='utf-8', errors='ignore') as f: + with open(args.overrides, encoding='utf-8', errors='ignore') as f: data = json.load(f) for nodeName, overrides in data.items(): for attrName, value in overrides.items(): @@ -240,7 +240,7 @@ with meshroom.core.graph.GraphModification(graph): if args.paramOverrides: print("\n") - reExtract = re.compile('(\w+)([:.])(\w[\w.]*)=(.*)') + reExtract = re.compile(r'(\w+)([:.])(\w[\w.]*)=(.*)') for p in args.paramOverrides: result = reExtract.match(p) if not result: @@ -249,12 +249,12 @@ with meshroom.core.graph.GraphModification(graph): if t == ':': nodesOfType = graph.nodesOfType(node) if not nodesOfType: - raise ValueError('No node with the type "{}" in the scene.'.format(node)) + raise ValueError(f'No node with the type "{node}" in the scene.') for n in nodesOfType: - print('Overrides {node}.{param}={value}'.format(node=node, param=param, value=value)) + print(f'Overrides {node}.{param}={value}') n.attribute(param).value = value elif t == '.': - print('Overrides {node}.{param}={value}'.format(node=node, param=param, value=value)) + print(f'Overrides {node}.{param}={value}') graph.findNode(node).attribute(param).value = value else: raise ValueError('Invalid param override: ' + str(p)) @@ -265,10 +265,10 @@ with meshroom.core.graph.GraphModification(graph): if args.save: graph.save(args.save, setupProjectFile=not bool(args.cache)) - print('File successfully saved: "{}"'.format(args.save)) + print(f'File successfully saved: "{args.save}"') if not args.output: - print('No output set, results will be available in the cache folder: "{}"'.format(graph.cacheDir)) + print(f'No output set, results will be available in the cache folder: "{graph.cacheDir}"') # find end nodes (None will compute all graph) toNodes = graph.findNodes(args.toNode) if args.toNode else None diff --git a/bin/meshroom_newNodeType b/bin/meshroom_newNodeType index 2cecabc352..c7fee57acd 100755 --- a/bin/meshroom_newNodeType +++ b/bin/meshroom_newNodeType @@ -1,5 +1,4 @@ #!/usr/bin/env python -from __future__ import print_function import argparse import os @@ -15,7 +14,7 @@ def trim(s): """ # regex to replace all space groups by a single space # use split() to remove trailing space at beginning/end - return re.sub('\s+', ' ', s).strip() + return re.sub(r'\s+', ' ', s).strip() def quotesForStrings(valueStr): @@ -30,9 +29,9 @@ def quotesForStrings(valueStr): float(valueStr) except ValueError: if "'" in valueStr: - v = "'''{}'''".format(valueStr) + v = f"'''{valueStr}'''" else: - v = "'{}'".format(valueStr) + v = f"'{valueStr}'" return v def convertToLabel(name): @@ -86,7 +85,7 @@ elif sys.stdin.isatty(): if not inputCmdLineDoc: print('No input documentation.') - print('Usage: YOUR_COMMAND --help | {cmd}'.format(cmd=os.path.splitext(__file__)[0])) + print(f'Usage: YOUR_COMMAND --help | {os.path.splitext(__file__)[0]}') sys.exit(-1) @@ -104,39 +103,39 @@ print(inputCmdLineDoc) args_re = None if args.parser == 'boost': args_re = re.compile( - '^\s+' # space(s) - '(?:-(?P\w+)\|?)?' # potential argument short name - '\s*\[?' # potential '[' - '\s*--(?P\w+)' # argument long name - '(?:\s*\])?' # potential ']' - '(?:\s+(?P\w+)?)?' # potential arg - '(?:\s+\(\=(?P.+)\))?' # potential default value - '\s+(?P.*?)\n' # end of the line - '(?P(?:\s+[^-\s].+?\n)*)' # next documentation lines + r'^\s+' # space(s) + r'(?:-(?P\w+)\|?)?' # potential argument short name + r'\s*\[?' # potential '[' + r'\s*--(?P\w+)' # argument long name + r'(?:\s*\])?' # potential ']' + r'(?:\s+(?P\w+)?)?' # potential arg + r'(?:\s+\(\=(?P.+)\))?' # potential default value + '\\s+(?P.*?)\n' # end of the line + '(?P(?:\\s+[^-\\s].+?\n)*)' # next documentation lines '', re.MULTILINE) elif args.parser == 'cmdLineLib': args_re = re.compile( '^' - '\[' # '[' - '-(?P\w+)' # argument short name - '\|' - '--(?P\w+)' # argument long name - '(?:\s+(?P\w+)?)?' # potential arg - '\]' # ']' + r'\[' # '[' + r'-(?P\w+)' # argument short name + r'\|' + r'--(?P\w+)' # argument long name + r'(?:\s+(?P\w+)?)?' # potential arg + r'\]' # ']' '()' # no default value '(?P.*?)?\n' # end of the line - '(?P(?:[^\[\w].+?\n)*)' # next documentation lines + '(?P(?:[^\\[\\w].+?\n)*)' # next documentation lines , re.MULTILINE) elif args.parser == 'basic': - args_re = re.compile('()--(?P\w+)()()()()') + args_re = re.compile(r'()--(?P\w+)()()()()') else: - print('Error: Unknown input parser "{}"'.format(args.parser)) + print(f'Error: Unknown input parser "{args.parser}"') sys.exit(-1) -choiceValues1_re = re.compile('\* (?P\w+):') -choiceValues2_re = re.compile('\((?P.+?)\)') -choiceValues3_re = re.compile('\{(?P.+?)\}') +choiceValues1_re = re.compile(r'\* (?P\w+):') +choiceValues2_re = re.compile(r'\((?P.+?)\)') +choiceValues3_re = re.compile(r'\{(?P.+?)\}') cmdLineArgs = args_re.findall(inputCmdLineDoc.decode('utf-8')) @@ -286,10 +285,10 @@ fileStr += """ outputFilepath = os.path.join(args.output, args.node + '.py') if not args.force and os.path.exists(outputFilepath): - print('Plugin "{}" already exists "{}".'.format(args.node, outputFilepath)) + print(f'Plugin "{args.node}" already exists "{outputFilepath}".') sys.exit(-1) with open(outputFilepath, 'w') as pluginFile: pluginFile.write(fileStr) -print('New node exported to: "{}"'.format(outputFilepath)) +print(f'New node exported to: "{outputFilepath}"') diff --git a/bin/meshroom_statistics b/bin/meshroom_statistics index 4c9592ee09..5f68188665 100755 --- a/bin/meshroom_statistics +++ b/bin/meshroom_statistics @@ -45,7 +45,7 @@ parser.add_argument("--verbose", help="Print full status information", args = parser.parse_args() if not os.path.exists(args.graphFile): - print('ERROR: No graph file "{}".'.format(args.graphFile)) + print(f'ERROR: No graph file "{args.graphFile}".') sys.exit(-1) graph = pg.loadGraph(args.graphFile) @@ -64,7 +64,7 @@ else: for node in nodes: for chunk in node.chunks: - print('{}: {}\n'.format(chunk.name, chunk.statistics.toDict())) + print(f'{chunk.name}: {chunk.statistics.toDict()}\n') if args.exportHtml: with open(args.exportHtml, 'w') as fileObj: diff --git a/bin/meshroom_status b/bin/meshroom_status index 68968a1332..b7bd8690d4 100755 --- a/bin/meshroom_status +++ b/bin/meshroom_status @@ -22,7 +22,7 @@ parser.add_argument("--verbose", help="Print full status information", args = parser.parse_args() if not os.path.exists(args.graphFile): - print('ERROR: No graph file "{}".'.format(args.node, args.graphFile)) + print(f'ERROR: No graph file "{args.node}".') sys.exit(-1) graph = meshroom.core.graph.loadGraph(args.graphFile) @@ -32,10 +32,10 @@ graph.update() if args.node: node = graph.node(args.node) if node is None: - print('ERROR: node "{}" does not exist in file "{}".'.format(args.node, args.graphFile)) + print(f'ERROR: node "{args.node}" does not exist in file "{args.graphFile}".') sys.exit(-1) for chunk in node.chunks: - print('{}: {}'.format(chunk.name, chunk.status.status.name)) + print(f'{chunk.name}: {chunk.status.status.name}') if args.verbose: print('statusFile: ', node.statusFile) pprint(node.status.toDict()) @@ -46,6 +46,6 @@ else: nodes, edges = graph.dfsOnFinish(startNodes=startNodes) for node in nodes: for chunk in node.chunks: - print('{}: {}'.format(chunk.name, chunk.status.status.name)) + print(f'{chunk.name}: {chunk.status.status.name}') if args.verbose: pprint([n.status.toDict() for n in nodes]) diff --git a/meshroom/common/PySignal.py b/meshroom/common/PySignal.py index a3ae844c0b..7d0ab40523 100644 --- a/meshroom/common/PySignal.py +++ b/meshroom/common/PySignal.py @@ -16,13 +16,13 @@ from weakref import WeakMethod -class Signal(object): +class Signal: """ The Signal is the core object that handles connection and emission . """ def __init__(self): - super(Signal, self).__init__() + super().__init__() self._block = False self._sender = None self._slots = [] @@ -151,7 +151,7 @@ def sender(self): return None -class ClassSignal(object): +class ClassSignal: """ The class signal allows a signal to be set on a class rather than an instance. This emulates the behavior of a PyQt signal @@ -234,7 +234,7 @@ def block(self, signals=None, isBlocked=True): self[signal].block(isBlocked) -class ClassSignalFactory(object): +class ClassSignalFactory: """ The class signal allows a signal factory to be set on a class rather than an instance. """ diff --git a/meshroom/common/core.py b/meshroom/common/core.py index 2f3ad487af..38271a088e 100644 --- a/meshroom/common/core.py +++ b/meshroom/common/core.py @@ -126,13 +126,13 @@ def func_wrapper(*f_args, **f_kwargs): class CoreProperty(property): def __init__(self, ptype, fget=None, fset=None, **kwargs): - super(CoreProperty, self).__init__(fget, fset) + super().__init__(fget, fset) -class CoreObject(object): +class CoreObject: def __init__(self, parent=None, *args, **kwargs): - super(CoreObject, self).__init__() + super().__init__() self._parent = parent # Note: we do not use ClassSignal, as it can not be used in __del__. self.destroyed = PySignal.Signal() diff --git a/meshroom/common/qt.py b/meshroom/common/qt.py index 7b6496dee1..f479ddfd2a 100644 --- a/meshroom/common/qt.py +++ b/meshroom/common/qt.py @@ -14,7 +14,7 @@ class QObjectListModel(QtCore.QAbstractListModel): def __init__(self, keyAttrName='', parent=None): """ Constructs an object list model with the given parent. """ - super(QObjectListModel, self).__init__(parent) + super().__init__(parent) self._objects = list() # Internal list of objects self._keyAttrName = keyAttrName @@ -322,7 +322,7 @@ class QTypedObjectListModel(QObjectListModel): # TODO: handle notify signal to emit dataChanged signal def __init__(self, keyAttrName="name", T=QtCore.QObject, parent=None): - super(QTypedObjectListModel, self).__init__(keyAttrName, parent) + super().__init__(keyAttrName, parent) self._T = T blacklist = ["id", "index", "class", "model", "modelData"] @@ -340,7 +340,7 @@ def __init__(self, keyAttrName="name", T=QtCore.QObject, parent=None): print("Reserved role name: " + prop.name()) def data(self, index, role): - obj = super(QTypedObjectListModel, self).data(index, self.ObjectRole) + obj = super().data(index, self.ObjectRole) if role == self.ObjectRole: return obj if obj: @@ -355,7 +355,7 @@ def _referenceItem(self, item): if item.staticMetaObject != self._metaObject: raise TypeError("Invalid object type: expected {}, got {}".format( self._metaObject.className(), item.staticMetaObject.className())) - super(QTypedObjectListModel, self)._referenceItem(item) + super()._referenceItem(item) class SortedModelByReference(QtCore.QSortFilterProxyModel): @@ -363,7 +363,7 @@ class SortedModelByReference(QtCore.QSortFilterProxyModel): This proxy is useful if the model needs to be sorted a certain way for a specific use. """ def __init__(self, parent): - super(SortedModelByReference, self).__init__(parent) + super().__init__(parent) self._reference = [] def setReference(self, iterable): @@ -385,7 +385,7 @@ def lessThan(self, left, right): def sort(self): """ Sort the proxy and call invalidate() """ - super(SortedModelByReference, self).sort(0, QtCore.Qt.AscendingOrder) + super().sort(0, QtCore.Qt.AscendingOrder) self.invalidate() diff --git a/meshroom/core/__init__.py b/meshroom/core/__init__.py index 0178f34dad..0300647799 100644 --- a/meshroom/core/__init__.py +++ b/meshroom/core/__init__.py @@ -161,7 +161,7 @@ def validateNodeDesc(nodeDesc): return errors -class Version(object): +class Version: """ Version provides convenient properties and methods to manipulate and compare versions. """ @@ -173,19 +173,19 @@ def __init__(self, *args): """ if len(args) == 0: self.components = tuple() - self.status = str() + self.status = '' elif len(args) == 1: versionName = args[0] if isinstance(versionName, str): self.components, self.status = Version.toComponents(versionName) elif isinstance(versionName, (list, tuple)): self.components = tuple([int(v) for v in versionName]) - self.status = str() + self.status = '' else: raise RuntimeError("Version: Unsupported input type.") else: self.components = tuple([int(v) for v in args]) - self.status = str() + self.status = '' def __repr__(self): return self.name @@ -245,9 +245,9 @@ def toComponents(versionName): tuple of int, string: split version numbers, status if any (or empty string) """ if not versionName: - return (), str() + return (), '' - status = str() + status = '' # If there is a status, it is placed after a "-" splitComponents = versionName.split("-", maxsplit=1) if (len(splitComponents) > 1): # If there is no status, splitComponents is equal to [versionName] diff --git a/meshroom/core/attribute.py b/meshroom/core/attribute.py index f3cc617b0a..b3ed89b9c7 100644 --- a/meshroom/core/attribute.py +++ b/meshroom/core/attribute.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# coding:utf-8 import copy import os import re @@ -57,7 +56,7 @@ def __init__(self, node, attributeDesc, isOutput, root=None, parent=None): root (Attribute): (optional) the root Attribute (List or Group) containing this one parent (BaseObject): (optional) the parent BaseObject """ - super(Attribute, self).__init__(parent) + super().__init__(parent) self._name = attributeDesc.name self._root = None if root is None else weakref.ref(root) self._node = weakref.ref(node) @@ -473,7 +472,7 @@ def wrapper(attr, *args, **kwargs): class PushButtonParam(Attribute): def __init__(self, node, attributeDesc, isOutput, root=None, parent=None): - super(PushButtonParam, self).__init__(node, attributeDesc, isOutput, root, parent) + super().__init__(node, attributeDesc, isOutput, root, parent) @Slot() def clicked(self): @@ -483,7 +482,7 @@ def clicked(self): class ChoiceParam(Attribute): def __init__(self, node, attributeDesc: desc.ChoiceParam, isOutput, root=None, parent=None): - super(ChoiceParam, self).__init__(node, attributeDesc, isOutput, root, parent) + super().__init__(node, attributeDesc, isOutput, root, parent) self._values = None def __len__(self): @@ -544,7 +543,7 @@ def getExportValue(self): class ListAttribute(Attribute): def __init__(self, node, attributeDesc, isOutput, root=None, parent=None): - super(ListAttribute, self).__init__(node, attributeDesc, isOutput, root, parent) + super().__init__(node, attributeDesc, isOutput, root, parent) def __len__(self): if self._value is None: @@ -650,13 +649,13 @@ def uid(self): if value.invalidate: uids.append(value.uid()) return hashValue(uids) - return super(ListAttribute, self).uid() + return super().uid() def _applyExpr(self): if not self.node.graph: return if isinstance(self._value, ListAttribute) or Attribute.isLinkExpression(self._value): - super(ListAttribute, self)._applyExpr() + super()._applyExpr() else: for value in self._value: value._applyExpr() @@ -689,7 +688,7 @@ def getValueStr(self, withQuotes=True): return v def updateInternals(self): - super(ListAttribute, self).updateInternals() + super().updateInternals() for attr in self._value: attr.updateInternals() @@ -711,11 +710,11 @@ def isLinkNested(self): class GroupAttribute(Attribute): def __init__(self, node, attributeDesc, isOutput, root=None, parent=None): - super(GroupAttribute, self).__init__(node, attributeDesc, isOutput, root, parent) + super().__init__(node, attributeDesc, isOutput, root, parent) def __getattr__(self, key): try: - return super(GroupAttribute, self).__getattr__(key) + return super().__getattr__(key) except AttributeError: try: return self._value.get(key) @@ -831,7 +830,7 @@ def getValueStr(self, withQuotes=True): return f'{strBegin}{s}{strEnd}' def updateInternals(self): - super(GroupAttribute, self).updateInternals() + super().updateInternals() for attr in self._value: attr.updateInternals() diff --git a/meshroom/core/cgroup.py b/meshroom/core/cgroup.py index 7ecde93016..7d78a8f895 100755 --- a/meshroom/core/cgroup.py +++ b/meshroom/core/cgroup.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# coding:utf-8 import os @@ -15,7 +14,7 @@ def getCgroupMemorySize(): cgroup = None try: - with open(filename, "r") as f: + with open(filename) as f: # cgroup file is a ':' separated table # lookup a line where the second field is "memory" @@ -35,7 +34,7 @@ def getCgroupMemorySize(): size = -1 filename = f"/sys/fs/cgroup/memory/{cgroup}/memory.limit_in_bytes" try: - with open(filename, "r") as f: + with open(filename) as f: value = f.read().rstrip("\r\n") if value.isnumeric(): size = int(value) @@ -72,7 +71,7 @@ def getCgroupCpuCount(): cgroup = None try: - with open(filename, "r") as f: + with open(filename) as f: # cgroup file is a ':' separated table # lookup a line where the second field is "memory" @@ -92,7 +91,7 @@ def getCgroupCpuCount(): size = -1 filename = f"/sys/fs/cgroup/cpuset/{cgroup}/cpuset.cpus" try: - with open(filename, "r") as f: + with open(filename) as f: value = f.read().rstrip("\r\n") nlist = parseNumericList(value) size = len(nlist) diff --git a/meshroom/core/exception.py b/meshroom/core/exception.py index fe8e834cd4..4443a8962f 100644 --- a/meshroom/core/exception.py +++ b/meshroom/core/exception.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# coding:utf-8 class MeshroomException(Exception): @@ -33,7 +32,7 @@ class UnknownNodeTypeError(GraphException): """ def __init__(self, nodeType, msg=None): msg = "Unknown Node Type: " + nodeType - super(UnknownNodeTypeError, self).__init__(msg) + super().__init__(msg) self.nodeType = nodeType @@ -42,7 +41,7 @@ def __init__(self, nodeName, details=None): msg = f"Failed to upgrade node {nodeName}" if details: msg += f": {details}" - super(NodeUpgradeError, self).__init__(msg) + super().__init__(msg) class GraphVisitMessage(GraphException): diff --git a/meshroom/core/graph.py b/meshroom/core/graph.py index 5384f5ae1b..4a0f9aae8a 100644 --- a/meshroom/core/graph.py +++ b/meshroom/core/graph.py @@ -1,10 +1,9 @@ -from __future__ import print_function - import json import logging import os import re -from typing import Any, Iterable, Optional +from typing import Any, Optional +from collections.abc import Iterable import weakref from collections import defaultdict, OrderedDict from contextlib import contextmanager @@ -63,7 +62,7 @@ def GraphModification(graph): class Edge(BaseObject): def __init__(self, src, dst, parent=None): - super(Edge, self).__init__(parent) + super().__init__(parent) self._src = weakref.ref(src) self._dst = weakref.ref(dst) self._repr = f" {self._src()} -> {self._dst()}" @@ -85,13 +84,13 @@ def dst(self): BLACK = 2 -class Visitor(object): +class Visitor: """ Base class for Graph Visitors that does nothing. Sub-classes can override any method to implement specific algorithms. """ def __init__(self, reverse, dependenciesOnly): - super(Visitor, self).__init__() + super().__init__() self.reverse = reverse self.dependenciesOnly = dependenciesOnly @@ -197,7 +196,7 @@ class Graph(BaseObject): """ def __init__(self, name: str = "", parent: BaseObject = None): - super(Graph, self).__init__(parent) + super().__init__(parent) self.name: str = name self._loading: bool = False self._saving: bool = False @@ -339,7 +338,7 @@ def _normalizeGraphContent(self, graphData: dict, fileVersion: Version) -> dict: uidOccurrences = uidPattern.findall(updatedFileData) for occ in uidOccurrences: uid = occ.split("\"")[-2] # UID is second to last element - newUidStr = r'"uid": "{}"'.format(uid) + newUidStr = fr'"uid": "{uid}"' updatedFileData = updatedFileData.replace(occ, newUidStr) graphContent = json.loads(updatedFileData) @@ -856,11 +855,11 @@ def edge(self, dstAttributeName): return self._edges.get(dstAttributeName) def getLeafNodes(self, dependenciesOnly): - nodesWithOutputLink = set([edge.src.node for edge in self.getEdges(dependenciesOnly)]) + nodesWithOutputLink = {edge.src.node for edge in self.getEdges(dependenciesOnly)} return set(self._nodes) - nodesWithOutputLink def getRootNodes(self, dependenciesOnly): - nodesWithInputLink = set([edge.dst.node for edge in self.getEdges(dependenciesOnly)]) + nodesWithInputLink = {edge.dst.node for edge in self.getEdges(dependenciesOnly)} return set(self._nodes) - nodesWithInputLink @changeTopology @@ -910,7 +909,7 @@ def getDepth(self, node, minimal=False): return minDepth if minimal else maxDepth def getInputEdges(self, node, dependenciesOnly): - return set([edge for edge in self.getEdges(dependenciesOnly=dependenciesOnly) if edge.dst.node is node]) + return {edge for edge in self.getEdges(dependenciesOnly=dependenciesOnly) if edge.dst.node is node} def _getInputEdgesPerNode(self, dependenciesOnly): nodeEdges = defaultdict(set) @@ -1167,7 +1166,7 @@ def dfsMaxEdgeLength(self, startNodes=None, dependenciesOnly=True): :return: """ nodesStack = [] - edgesScore = defaultdict(lambda: 0) + edgesScore = defaultdict(int) visitor = Visitor(reverse=False, dependenciesOnly=dependenciesOnly) def finishEdge(edge, graph): @@ -1223,7 +1222,7 @@ def getEdges(self, dependenciesOnly=False): def getInputNodes(self, node, recursive, dependenciesOnly): """ Return either the first level input nodes of a node or the whole chain. """ if not recursive: - return set([edge.src.node for edge in self.getEdges(dependenciesOnly) if edge.dst.node is node]) + return {edge.src.node for edge in self.getEdges(dependenciesOnly) if edge.dst.node is node} inputNodes, edges = self.dfsOnDiscover(startNodes=[node], filterTypes=None, reverse=False) return inputNodes[1:] # exclude current node @@ -1231,7 +1230,7 @@ def getInputNodes(self, node, recursive, dependenciesOnly): def getOutputNodes(self, node, recursive, dependenciesOnly): """ Return either the first level output nodes of a node or the whole chain. """ if not recursive: - return set([edge.dst.node for edge in self.getEdges(dependenciesOnly) if edge.src.node is node]) + return {edge.dst.node for edge in self.getEdges(dependenciesOnly) if edge.src.node is node} outputNodes, edges = self.dfsOnDiscover(startNodes=[node], filterTypes=None, reverse=True) return outputNodes[1:] # exclude current node @@ -1253,7 +1252,7 @@ def canSubmitOrCompute(self, startNode): class SCVisitor(Visitor): def __init__(self, reverse, dependenciesOnly): - super(SCVisitor, self).__init__(reverse, dependenciesOnly) + super().__init__(reverse, dependenciesOnly) canCompute = True canSubmit = True @@ -1611,7 +1610,7 @@ def executeGraph(graph, toNodes=None, forceCompute=False, forceStatus=False): chunksInConflict = getAlreadySubmittedChunks(nodes) if chunksInConflict: - chunksStatus = set([chunk.status.status.name for chunk in chunksInConflict]) + chunksStatus = {chunk.status.status.name for chunk in chunksInConflict} chunksName = [node.name for node in chunksInConflict] msg = 'WARNING: Some nodes are already submitted with status: {}\nNodes: {}'.format( ', '.join(chunksStatus), diff --git a/meshroom/core/graphIO.py b/meshroom/core/graphIO.py index c2cdd5085a..3e36b3eb05 100644 --- a/meshroom/core/graphIO.py +++ b/meshroom/core/graphIO.py @@ -15,7 +15,7 @@ class GraphIO: __version__ = "2.0" - class Keys(object): + class Keys: """File Keys.""" # Doesn't inherit enum to simplify usage (GraphIO.Keys.XX, without .value) @@ -98,7 +98,7 @@ def serializeHeader(self) -> dict: def _getNodeTypesVersions(self) -> dict[str, str]: """Get registered versions of each node types in `nodes`, excluding CompatibilityNode instances.""" - nodeTypes = set([node.nodeDesc.__class__ for node in self.nodes if isinstance(node, Node)]) + nodeTypes = {node.nodeDesc.__class__ for node in self.nodes if isinstance(node, Node)} nodeTypesVersions = { nodeType.__name__: version for nodeType in nodeTypes diff --git a/meshroom/core/node.py b/meshroom/core/node.py index be6141e923..392e3316aa 100644 --- a/meshroom/core/node.py +++ b/meshroom/core/node.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# coding:utf-8 import atexit import copy import datetime @@ -37,7 +36,7 @@ def renameWritingToFinalPath(writingFilepath: str, filepath: str) -> str: os.remove(filepath) # If remove is successful, we can stop the iterations break - except WindowsError: + except OSError: pass os.rename(writingFilepath, filepath) @@ -70,7 +69,7 @@ class StatusData(BaseObject): def __init__(self, nodeName='', nodeType='', packageName='', packageVersion='', mrNodeType: MrNodeType = MrNodeType.NONE, parent: BaseObject = None): - super(StatusData, self).__init__(parent) + super().__init__(parent) self.nodeName: str = nodeName self.nodeType: str = nodeType @@ -267,7 +266,7 @@ def makeProgressBar(self, end, message=''): f.close() - with open(self.chunk.logFile, 'r') as f: + with open(self.chunk.logFile) as f: content = f.read() self.progressBarPosition = content.rfind('\n') @@ -320,7 +319,7 @@ def clearProcessesStatus(): class NodeChunk(BaseObject): def __init__(self, node, range, parent=None): - super(NodeChunk, self).__init__(parent) + super().__init__(parent) self.node = node self.range = range self.logManager: LogManager = LogManager(self) @@ -368,7 +367,7 @@ def updateStatusFromCache(self): self._status.setNodeType(self.node) else: try: - with open(statusFile, 'r') as jsonFile: + with open(statusFile) as jsonFile: statusData = json.load(jsonFile) # logging.debug(f"updateStatusFromCache({self.node.name}): From status {self.status.status} to {statusData['status']}") self._status.fromDict(statusData) @@ -443,7 +442,7 @@ def updateStatisticsFromCache(self): statisticsFile = self.statisticsFile if not os.path.exists(statisticsFile): return - with open(statisticsFile, 'r') as jsonFile: + with open(statisticsFile) as jsonFile: statisticsData = json.load(jsonFile) self.statistics.fromDict(statisticsData) if oldTimes != self.statistics.times: @@ -635,7 +634,7 @@ def __init__(self, nodeType: str, position: Position = None, parent: BaseObject parent: this Node's parent **kwargs: attributes values """ - super(BaseNode, self).__init__(parent) + super().__init__(parent) self._nodeType: str = nodeType self.nodeDesc: desc.BaseNode = None @@ -1311,7 +1310,7 @@ def loadOutputAttr(self): return # logging.warning("load output attr: {}, value: {}".format(self.name, valuesFile)) - with open(valuesFile, 'r') as jsonFile: + with open(valuesFile) as jsonFile: data = json.load(jsonFile) # logging.warning(data) @@ -1513,8 +1512,8 @@ def updateDuplicates(self, nodesPerUid): # If number of elements in both lists are identical, # we must check if their content is the same if len(newList) == len(self._duplicates): - newListName = set([node.name for node in newList]) - oldListName = set([node.name for node in self._duplicates.values()]) + newListName = {node.name for node in newList} + oldListName = {node.name for node in self._duplicates.values()} # If strict equality between both sets, # there is no need to set the new list @@ -1689,7 +1688,7 @@ class Node(BaseNode): A standard Graph node based on a node type. """ def __init__(self, nodeType, position=None, parent=None, uid=None, **kwargs): - super(Node, self).__init__(nodeType, position, parent=parent, uid=uid, **kwargs) + super().__init__(nodeType, position, parent=parent, uid=uid, **kwargs) if not self.nodeDesc: raise UnknownNodeTypeError(nodeType) @@ -1834,7 +1833,7 @@ class CompatibilityNode(BaseNode): with all its inputs and precomputed outputs. """ def __init__(self, nodeType, nodeDict, position=None, issue=CompatibilityIssue.UnknownIssue, parent=None): - super(CompatibilityNode, self).__init__(nodeType, position, parent) + super().__init__(nodeType, position, parent) self.issue = issue # Make a deepcopy of nodeDict to handle CompatibilityNode duplication diff --git a/meshroom/core/nodeFactory.py b/meshroom/core/nodeFactory.py index a33cd3377c..7ca79fe53b 100644 --- a/meshroom/core/nodeFactory.py +++ b/meshroom/core/nodeFactory.py @@ -1,5 +1,6 @@ import logging -from typing import Any, Iterable, Optional, Union +from typing import Any, Optional, Union +from collections.abc import Iterable import meshroom.core from meshroom.core import Version, desc diff --git a/meshroom/core/submitter.py b/meshroom/core/submitter.py index 586484da61..ad5a820641 100644 --- a/meshroom/core/submitter.py +++ b/meshroom/core/submitter.py @@ -1,12 +1,11 @@ #!/usr/bin/env python -# coding:utf-8 from meshroom.common import BaseObject, Property class BaseSubmitter(BaseObject): def __init__(self, name, parent=None): - super(BaseSubmitter, self).__init__(parent) + super().__init__(parent) self._name = name def submit(self, nodes, edges, filepath, submitLabel="{projectName}"): diff --git a/meshroom/core/taskManager.py b/meshroom/core/taskManager.py index 8d2b64f6bb..8e4f7ab97d 100644 --- a/meshroom/core/taskManager.py +++ b/meshroom/core/taskManager.py @@ -98,7 +98,7 @@ class TaskManager(BaseObject): Manage graph - local and external - computation tasks. """ def __init__(self, parent: BaseObject = None): - super(TaskManager, self).__init__(parent) + super().__init__(parent) self._graph = None self._nodes = DictModel(keyAttrName='_name', parent=self) self._nodesToProcess = [] @@ -208,7 +208,7 @@ def compute(self, graph: Graph = None, toNodes: list[Node] = None, forceCompute: chunksInConflict = self.getAlreadySubmittedChunks(nodes) if chunksInConflict: - chunksStatus = set([chunk.status.status.name for chunk in chunksInConflict]) + chunksStatus = {chunk.status.status.name for chunk in chunksInConflict} chunksName = [node.name for node in chunksInConflict] # Warning: Syntax and terms are parsed on QML side to recognize the error # Syntax : [Context] ErrorType: ErrorMessage diff --git a/meshroom/core/test.py b/meshroom/core/test.py index cec7b774a7..728122fb9f 100644 --- a/meshroom/core/test.py +++ b/meshroom/core/test.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# coding:utf-8 from meshroom.core import unregisterNodeType, pipelineTemplates, Version from meshroom.core.node import CompatibilityIssue, CompatibilityNode diff --git a/meshroom/submitters/__init__.py b/meshroom/submitters/__init__.py index f512deae9d..e69de29bb2 100644 --- a/meshroom/submitters/__init__.py +++ b/meshroom/submitters/__init__.py @@ -1 +0,0 @@ -# coding:utf-8 diff --git a/meshroom/submitters/simpleFarmSubmitter.py b/meshroom/submitters/simpleFarmSubmitter.py index 04a6b6d954..017f0a1839 100644 --- a/meshroom/submitters/simpleFarmSubmitter.py +++ b/meshroom/submitters/simpleFarmSubmitter.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# coding:utf-8 import os import json @@ -24,7 +23,7 @@ class SimpleFarmSubmitter(BaseSubmitter): DEFAULT_TAGS = {'prod': ''} def __init__(self, parent=None): - super(SimpleFarmSubmitter, self).__init__(name='SimpleFarm', parent=parent) + super().__init__(name='SimpleFarm', parent=parent) self.engine = os.environ.get('MESHROOM_SIMPLEFARM_ENGINE', 'tractor') self.share = os.environ.get('MESHROOM_SIMPLEFARM_SHARE', 'vfx') self.prod = os.environ.get('PROD', 'mvg') diff --git a/meshroom/ui/app.py b/meshroom/ui/app.py index 3d5addd3d3..e83c90e52b 100644 --- a/meshroom/ui/app.py +++ b/meshroom/ui/app.py @@ -31,7 +31,7 @@ from meshroom.ui import commands -class MessageHandler(object): +class MessageHandler: """ MessageHandler that translates Qt logs to Python logging system. Also contains and filters a list of blacklisted QML warnings that end up in the @@ -211,7 +211,7 @@ def __init__(self, inputArgs): logging.getLogger().setLevel(meshroom.logStringToPython[args.verbose]) - super(MeshroomApp, self).__init__(inputArgs[:1] + qtArgs) + super().__init__(inputArgs[:1] + qtArgs) self.setOrganizationName('AliceVision') self.setApplicationName('Meshroom') diff --git a/meshroom/ui/commands.py b/meshroom/ui/commands.py index dfd221e607..dcbcac0f49 100755 --- a/meshroom/ui/commands.py +++ b/meshroom/ui/commands.py @@ -14,7 +14,7 @@ class UndoCommand(QUndoCommand): def __init__(self, parent=None): - super(UndoCommand, self).__init__(parent) + super().__init__(parent) self._enabled = True def setEnabled(self, enabled): @@ -47,7 +47,7 @@ def undoImpl(self): class UndoStack(QUndoStack): def __init__(self, parent=None): - super(UndoStack, self).__init__(parent) + super().__init__(parent) # connect QUndoStack signal to UndoStack's ones self.cleanChanged.connect(self._cleanChanged) self.canUndoChanged.connect(self._canUndoChanged) @@ -121,13 +121,13 @@ def unlock(self): class GraphCommand(UndoCommand): def __init__(self, graph, parent=None): - super(GraphCommand, self).__init__(parent) + super().__init__(parent) self.graph = graph class AddNodeCommand(GraphCommand): def __init__(self, graph, nodeType, position, parent=None, **kwargs): - super(AddNodeCommand, self).__init__(graph, parent) + super().__init__(graph, parent) self.nodeType = nodeType self.nodeName = None self.position = position @@ -153,7 +153,7 @@ def undoImpl(self): class RemoveNodeCommand(GraphCommand): def __init__(self, graph, node, parent=None): - super(RemoveNodeCommand, self).__init__(graph, parent) + super().__init__(graph, parent) self.nodeDict = node.toDict() self.nodeName = node.getName() self.setText(f"Remove Node {self.nodeName}") @@ -178,7 +178,7 @@ class DuplicateNodesCommand(GraphCommand): Handle node duplication in a Graph. """ def __init__(self, graph, srcNodes, parent=None): - super(DuplicateNodesCommand, self).__init__(graph, parent) + super().__init__(graph, parent) self.srcNodeNames = [ n.name for n in srcNodes ] self.setText("Duplicate Nodes") @@ -200,7 +200,7 @@ class PasteNodesCommand(GraphCommand): Handle node pasting in a Graph. """ def __init__(self, graph: "Graph", data: dict, position: Position, parent=None): - super(PasteNodesCommand, self).__init__(graph, parent) + super().__init__(graph, parent) self.data = data self.position = position self.nodeNames: list[str] = [] @@ -253,7 +253,7 @@ class ImportProjectCommand(GraphCommand): """ def __init__(self, graph: Graph, filepath: PathLike, position=None, yOffset=0, parent=None): - super(ImportProjectCommand, self).__init__(graph, parent) + super().__init__(graph, parent) self.filepath = filepath self.importedNames = [] self.position = position @@ -285,7 +285,7 @@ def undoImpl(self): class SetAttributeCommand(GraphCommand): def __init__(self, graph, attribute, value, parent=None): - super(SetAttributeCommand, self).__init__(graph, parent) + super().__init__(graph, parent) self.attrName = attribute.getFullNameToNode() self.value = value self.oldValue = attribute.getExportValue() @@ -309,7 +309,7 @@ def undoImpl(self): class AddEdgeCommand(GraphCommand): def __init__(self, graph, src, dst, parent=None): - super(AddEdgeCommand, self).__init__(graph, parent) + super().__init__(graph, parent) self.srcAttr = src.getFullNameToNode() self.dstAttr = dst.getFullNameToNode() self.setText(f"Connect '{self.srcAttr}'->'{self.dstAttr}'") @@ -327,7 +327,7 @@ def undoImpl(self): class RemoveEdgeCommand(GraphCommand): def __init__(self, graph, edge, parent=None): - super(RemoveEdgeCommand, self).__init__(graph, parent) + super().__init__(graph, parent) self.srcAttr = edge.src.getFullNameToNode() self.dstAttr = edge.dst.getFullNameToNode() self.setText(f"Disconnect '{self.srcAttr}'->'{self.dstAttr}'") @@ -343,7 +343,7 @@ def undoImpl(self): class ListAttributeAppendCommand(GraphCommand): def __init__(self, graph, listAttribute, value, parent=None): - super(ListAttributeAppendCommand, self).__init__(graph, parent) + super().__init__(graph, parent) assert isinstance(listAttribute, ListAttribute) self.attrName = listAttribute.getFullNameToNode() self.index = None @@ -368,7 +368,7 @@ def undoImpl(self): class ListAttributeRemoveCommand(GraphCommand): def __init__(self, graph, attribute, parent=None): - super(ListAttributeRemoveCommand, self).__init__(graph, parent) + super().__init__(graph, parent) listAttribute = attribute.root assert isinstance(listAttribute, ListAttribute) self.listAttrName = listAttribute.getFullNameToNode() @@ -388,7 +388,7 @@ def undoImpl(self): class RemoveImagesCommand(GraphCommand): def __init__(self, graph, cameraInitNodes, parent=None): - super(RemoveImagesCommand, self).__init__(graph, parent) + super().__init__(graph, parent) self.cameraInits = cameraInitNodes self.viewpoints = { cameraInit.name: cameraInit.attribute("viewpoints").getExportValue() for cameraInit in self.cameraInits } self.intrinsics = { cameraInit.name: cameraInit.attribute("intrinsics").getExportValue() for cameraInit in self.cameraInits } @@ -417,7 +417,7 @@ def undoImpl(self): class MoveNodeCommand(GraphCommand): """ Move a node to a given position. """ def __init__(self, graph, node, position, parent=None): - super(MoveNodeCommand, self).__init__(graph, parent) + super().__init__(graph, parent) self.nodeName = node.name self.oldPosition = node.position self.newPosition = position @@ -436,7 +436,7 @@ class UpgradeNodeCommand(GraphCommand): Perform node upgrade on a CompatibilityNode. """ def __init__(self, graph, node, parent=None): - super(UpgradeNodeCommand, self).__init__(graph, parent) + super().__init__(graph, parent) self.nodeDict = node.toDict() self.nodeName = node.getName() self.compatibilityIssue = None @@ -464,7 +464,7 @@ class EnableGraphUpdateCommand(GraphCommand): Should not be used directly, use GroupedGraphModification context manager instead. """ def __init__(self, graph, enabled, parent=None): - super(EnableGraphUpdateCommand, self).__init__(graph, parent) + super().__init__(graph, parent) self.enabled = enabled self.previousState = self.graph.updateEnabled diff --git a/meshroom/ui/graph.py b/meshroom/ui/graph.py index 23457125f8..4716ecbfae 100644 --- a/meshroom/ui/graph.py +++ b/meshroom/ui/graph.py @@ -1,5 +1,4 @@ #!/usr/bin/env python -# coding:utf-8 from collections.abc import Iterable import logging import os @@ -7,7 +6,8 @@ from enum import Enum from threading import Thread, Event, Lock from multiprocessing.pool import ThreadPool -from typing import Iterator, Optional, Union +from typing import Optional, Union +from collections.abc import Iterator from PySide6.QtCore import ( Slot, @@ -49,7 +49,7 @@ class FilesModTimePollerThread(QObject): timesAvailable = Signal(list) def __init__(self, parent=None): - super(FilesModTimePollerThread, self).__init__(parent) + super().__init__(parent) self._thread = None self._mutex = Lock() self._threadPool = ThreadPool(4) @@ -140,7 +140,7 @@ class ChunksMonitor(QObject): Thus, for genericity, monitoring is based on regular polling and not file system watching. """ def __init__(self, chunks=(), parent=None): - super(ChunksMonitor, self).__init__(parent) + super().__init__(parent) self.monitorableChunks = [] self.monitoredChunks = [] self._filesTimePoller = FilesModTimePollerThread(parent=self) @@ -254,7 +254,7 @@ class DepthMode(Enum): } def __init__(self, graph): - super(GraphLayout, self).__init__(graph) + super().__init__(graph) self.graph = graph self._depthMode = GraphLayout.DepthMode.MaxDepth self._nodeWidth = 160 # implicit node width @@ -365,7 +365,7 @@ class UIGraph(QObject): It also provides a monitoring of all its computation units (NodeChunks). """ def __init__(self, undoStack: commands.UndoStack, taskManager: TaskManager, parent: QObject = None): - super(UIGraph, self).__init__(parent) + super().__init__(parent) self._undoStack = undoStack self._taskManager = taskManager self._graph: Graph = Graph('', self) diff --git a/meshroom/ui/palette.py b/meshroom/ui/palette.py index 4d96870915..d0e1c16fed 100644 --- a/meshroom/ui/palette.py +++ b/meshroom/ui/palette.py @@ -8,7 +8,7 @@ class PaletteManager(QObject): Manages QApplication's palette and provides a toggle between a dark and a light theme. """ def __init__(self, qmlEngine, parent=None): - super(PaletteManager, self).__init__(parent) + super().__init__(parent) self.qmlEngine = qmlEngine darkPalette = QPalette() window = QColor(50, 52, 55) diff --git a/meshroom/ui/reconstruction.py b/meshroom/ui/reconstruction.py index 6022993f21..d398f2214d 100755 --- a/meshroom/ui/reconstruction.py +++ b/meshroom/ui/reconstruction.py @@ -29,7 +29,7 @@ class Message(QObject): """ Simple structure wrapping a high-level message. """ def __init__(self, title, text, detailedText="", parent=None): - super(Message, self).__init__(parent) + super().__init__(parent) self._title = title self._text = text self._detailedText = detailedText @@ -47,7 +47,7 @@ class LiveSfmManager(QObject): File watching is based on regular polling and not filesystem events to work on network mounts. """ def __init__(self, reconstruction): - super(LiveSfmManager, self).__init__(reconstruction) + super().__init__(reconstruction) self.reconstruction = reconstruction self._folder = '' self.timerId = -1 @@ -188,7 +188,7 @@ def __init__(self, viewpointAttribute, reconstruction): viewpointAttribute (GroupAttribute): viewpoint attribute reconstruction (Reconstruction): owner reconstruction of this Viewpoint """ - super(ViewpointWrapper, self).__init__(parent=reconstruction) + super().__init__(parent=reconstruction) self._viewpoint = viewpointAttribute self._reconstruction = reconstruction @@ -428,7 +428,7 @@ class ActiveNode(QObject): Hold one active node for a given NodeType. """ def __init__(self, nodeType, parent=None): - super(ActiveNode, self).__init__(parent) + super().__init__(parent) self.nodeType = nodeType self._node = None @@ -467,7 +467,7 @@ class Reconstruction(UIGraph): ] def __init__(self, undoStack: commands.UndoStack, taskManager: TaskManager, defaultPipeline: str="", parent: QObject=None): - super(Reconstruction, self).__init__(undoStack, taskManager, parent) + super().__init__(undoStack, taskManager, parent) # initialize member variables for key steps of the 3D reconstruction pipeline self._active = False @@ -515,7 +515,7 @@ def setActive(self, active): @Slot() def clear(self): self.clearActiveNodes() - super(Reconstruction, self).clear() + super().clear() self.setActive(False) def setDefaultPipeline(self, defaultPipeline): @@ -554,7 +554,7 @@ def new(self, pipeline=None): # Lower the input and the dictionary keys to make sure that all input types can be found: # - correct pipeline name but the case does not match (e.g. panoramaHDR instead of panoramaHdr) # - lowercase pipeline name given through the "New Pipeline" menu - loweredPipelineTemplates = dict((k.lower(), v) for k, v in meshroom.core.pipelineTemplates.items()) + loweredPipelineTemplates = {k.lower(): v for k, v in meshroom.core.pipelineTemplates.items()} filepath = loweredPipelineTemplates.get(p.lower(), p) return self._loadWithErrorReport(self.initFromTemplate, filepath) @@ -698,7 +698,7 @@ def getAutoFisheyeCircle(self, panoramaInit): if not os.path.exists(sfmFile): return QVector3D(0.0, 0.0, 0.0) # skip decoding errors to avoid potential exceptions due to non utf-8 characters in images metadata - with open(sfmFile, 'r', encoding='utf-8', errors='ignore') as f: + with open(sfmFile, encoding='utf-8', errors='ignore') as f: data = json.load(f) intrinsics = data.get('intrinsics', []) @@ -881,7 +881,7 @@ def handleFilesUrl(self, filesByType, cameraInit=None, position=None): if not filesByType["images"] and not filesByType["videos"] and not filesByType["panoramaInfo"] and not filesByType["meshroomScenes"]: if filesByType["other"]: - extensions = set([os.path.splitext(url)[1] for url in filesByType["other"]]) + extensions = {os.path.splitext(url)[1] for url in filesByType["other"]} self.error.emit( Message( "No Recognized Input File", diff --git a/meshroom/ui/utils.py b/meshroom/ui/utils.py index 9bbfd2393d..f8b7cec776 100755 --- a/meshroom/ui/utils.py +++ b/meshroom/ui/utils.py @@ -21,7 +21,7 @@ def __init__(self, sourceFile="", watching=True, verbose=False, parent=None): watching -- Defines whether the watcher is active (default: True) verbose -- if True, output log infos (default: False) """ - super(QmlInstantEngine, self).__init__(parent) + super().__init__(parent) self._fileWatcher = QFileSystemWatcher() # Internal Qt File Watcher self._sourceFile = "" @@ -51,7 +51,7 @@ def onObjectCreated(root, url): def load(self, sourceFile): self._sourceFile = sourceFile - super(QmlInstantEngine, self).load(sourceFile) + super().load(sourceFile) def setWatching(self, watchValue): """ From 6764862b4c6dd49a87c9b1c07f58edb38f89b7f2 Mon Sep 17 00:00:00 2001 From: Fabien Castan Date: Mon, 14 Apr 2025 14:30:38 +0200 Subject: [PATCH 4/4] [bin] Use raw strings for regex --- bin/meshroom_newNodeType | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/bin/meshroom_newNodeType b/bin/meshroom_newNodeType index c7fee57acd..e91ee9c5b5 100755 --- a/bin/meshroom_newNodeType +++ b/bin/meshroom_newNodeType @@ -110,10 +110,9 @@ if args.parser == 'boost': r'(?:\s*\])?' # potential ']' r'(?:\s+(?P\w+)?)?' # potential arg r'(?:\s+\(\=(?P.+)\))?' # potential default value - '\\s+(?P.*?)\n' # end of the line - '(?P(?:\\s+[^-\\s].+?\n)*)' # next documentation lines - '', - re.MULTILINE) + r'\s+(?P.*?)\n' # end of the line + r'(?P(?:\s+[^-\s].+?\n)*)' # next documentation lines + , re.MULTILINE) elif args.parser == 'cmdLineLib': args_re = re.compile( '^' @@ -123,9 +122,9 @@ elif args.parser == 'cmdLineLib': r'--(?P\w+)' # argument long name r'(?:\s+(?P\w+)?)?' # potential arg r'\]' # ']' - '()' # no default value - '(?P.*?)?\n' # end of the line - '(?P(?:[^\\[\\w].+?\n)*)' # next documentation lines + r'()' # no default value + r'(?P.*?)?\n' # end of the line + r'(?P(?:[^\[\w].+?\n)*)' # next documentation lines , re.MULTILINE) elif args.parser == 'basic': args_re = re.compile(r'()--(?P\w+)()()()()')