Modernize to python-3.9+ with pyupgrade (--py39-plus)

This commit is contained in:
Fabien Castan 2025-04-30 19:18:06 +02:00
parent 22b2161ddd
commit 41738f7f40
26 changed files with 148 additions and 157 deletions

View file

@ -152,7 +152,7 @@ graph = meshroom.core.graph.Graph(name=args.pipeline)
with meshroom.core.graph.GraphModification(graph): with meshroom.core.graph.GraphModification(graph):
# initialize template pipeline # 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: if args.pipeline.lower() in loweredPipelineTemplates:
graph.initFromTemplate(loweredPipelineTemplates[args.pipeline.lower()], publishOutputs=True if args.output else False) graph.initFromTemplate(loweredPipelineTemplates[args.pipeline.lower()], publishOutputs=True if args.output else False)
else: 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.") raise RuntimeError("meshroom_batch requires a pipeline graph with at least one Publish node, none found.")
if args.overrides: 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) data = json.load(f)
for nodeName, overrides in data.items(): for nodeName, overrides in data.items():
for attrName, value in overrides.items(): for attrName, value in overrides.items():
@ -240,7 +240,7 @@ with meshroom.core.graph.GraphModification(graph):
if args.paramOverrides: if args.paramOverrides:
print("\n") print("\n")
reExtract = re.compile('(\w+)([:.])(\w[\w.]*)=(.*)') reExtract = re.compile(r'(\w+)([:.])(\w[\w.]*)=(.*)')
for p in args.paramOverrides: for p in args.paramOverrides:
result = reExtract.match(p) result = reExtract.match(p)
if not result: if not result:
@ -249,12 +249,12 @@ with meshroom.core.graph.GraphModification(graph):
if t == ':': if t == ':':
nodesOfType = graph.nodesOfType(node) nodesOfType = graph.nodesOfType(node)
if not nodesOfType: 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: 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 n.attribute(param).value = value
elif t == '.': 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 graph.findNode(node).attribute(param).value = value
else: else:
raise ValueError('Invalid param override: ' + str(p)) raise ValueError('Invalid param override: ' + str(p))
@ -265,10 +265,10 @@ with meshroom.core.graph.GraphModification(graph):
if args.save: if args.save:
graph.save(args.save, setupProjectFile=not bool(args.cache)) 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: 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) # find end nodes (None will compute all graph)
toNodes = graph.findNodes(args.toNode) if args.toNode else None toNodes = graph.findNodes(args.toNode) if args.toNode else None

View file

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
from __future__ import print_function
import argparse import argparse
import os import os
@ -15,7 +14,7 @@ def trim(s):
""" """
# regex to replace all space groups by a single space # regex to replace all space groups by a single space
# use split() to remove trailing space at beginning/end # 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): def quotesForStrings(valueStr):
@ -30,9 +29,9 @@ def quotesForStrings(valueStr):
float(valueStr) float(valueStr)
except ValueError: except ValueError:
if "'" in valueStr: if "'" in valueStr:
v = "'''{}'''".format(valueStr) v = f"'''{valueStr}'''"
else: else:
v = "'{}'".format(valueStr) v = f"'{valueStr}'"
return v return v
def convertToLabel(name): def convertToLabel(name):
@ -86,7 +85,7 @@ elif sys.stdin.isatty():
if not inputCmdLineDoc: if not inputCmdLineDoc:
print('No input documentation.') 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) sys.exit(-1)
@ -104,39 +103,39 @@ print(inputCmdLineDoc)
args_re = None args_re = None
if args.parser == 'boost': if args.parser == 'boost':
args_re = re.compile( args_re = re.compile(
'^\s+' # space(s) r'^\s+' # space(s)
'(?:-(?P<argShortName>\w+)\|?)?' # potential argument short name r'(?:-(?P<argShortName>\w+)\|?)?' # potential argument short name
'\s*\[?' # potential '[' r'\s*\[?' # potential '['
'\s*--(?P<argLongName>\w+)' # argument long name r'\s*--(?P<argLongName>\w+)' # argument long name
'(?:\s*\])?' # potential ']' r'(?:\s*\])?' # potential ']'
'(?:\s+(?P<arg>\w+)?)?' # potential arg r'(?:\s+(?P<arg>\w+)?)?' # potential arg
'(?:\s+\(\=(?P<defaultValue>.+)\))?' # potential default value r'(?:\s+\(\=(?P<defaultValue>.+)\))?' # potential default value
'\s+(?P<descriptionFirst>.*?)\n' # end of the line '\\s+(?P<descriptionFirst>.*?)\n' # end of the line
'(?P<descriptionNext>(?:\s+[^-\s].+?\n)*)' # next documentation lines '(?P<descriptionNext>(?:\\s+[^-\\s].+?\n)*)' # next documentation lines
'', '',
re.MULTILINE) re.MULTILINE)
elif args.parser == 'cmdLineLib': elif args.parser == 'cmdLineLib':
args_re = re.compile( args_re = re.compile(
'^' '^'
'\[' # '[' r'\[' # '['
'-(?P<argShortName>\w+)' # argument short name r'-(?P<argShortName>\w+)' # argument short name
'\|' r'\|'
'--(?P<argLongName>\w+)' # argument long name r'--(?P<argLongName>\w+)' # argument long name
'(?:\s+(?P<arg>\w+)?)?' # potential arg r'(?:\s+(?P<arg>\w+)?)?' # potential arg
'\]' # ']' r'\]' # ']'
'()' # no default value '()' # no default value
'(?P<descriptionFirst>.*?)?\n' # end of the line '(?P<descriptionFirst>.*?)?\n' # end of the line
'(?P<descriptionNext>(?:[^\[\w].+?\n)*)' # next documentation lines '(?P<descriptionNext>(?:[^\\[\\w].+?\n)*)' # next documentation lines
, re.MULTILINE) , re.MULTILINE)
elif args.parser == 'basic': elif args.parser == 'basic':
args_re = re.compile('()--(?P<argLongName>\w+)()()()()') args_re = re.compile(r'()--(?P<argLongName>\w+)()()()()')
else: else:
print('Error: Unknown input parser "{}"'.format(args.parser)) print(f'Error: Unknown input parser "{args.parser}"')
sys.exit(-1) sys.exit(-1)
choiceValues1_re = re.compile('\* (?P<value>\w+):') choiceValues1_re = re.compile(r'\* (?P<value>\w+):')
choiceValues2_re = re.compile('\((?P<value>.+?)\)') choiceValues2_re = re.compile(r'\((?P<value>.+?)\)')
choiceValues3_re = re.compile('\{(?P<value>.+?)\}') choiceValues3_re = re.compile(r'\{(?P<value>.+?)\}')
cmdLineArgs = args_re.findall(inputCmdLineDoc.decode('utf-8')) cmdLineArgs = args_re.findall(inputCmdLineDoc.decode('utf-8'))
@ -286,10 +285,10 @@ fileStr += """
outputFilepath = os.path.join(args.output, args.node + '.py') outputFilepath = os.path.join(args.output, args.node + '.py')
if not args.force and os.path.exists(outputFilepath): 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) sys.exit(-1)
with open(outputFilepath, 'w') as pluginFile: with open(outputFilepath, 'w') as pluginFile:
pluginFile.write(fileStr) pluginFile.write(fileStr)
print('New node exported to: "{}"'.format(outputFilepath)) print(f'New node exported to: "{outputFilepath}"')

View file

@ -45,7 +45,7 @@ parser.add_argument("--verbose", help="Print full status information",
args = parser.parse_args() args = parser.parse_args()
if not os.path.exists(args.graphFile): 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) sys.exit(-1)
graph = pg.loadGraph(args.graphFile) graph = pg.loadGraph(args.graphFile)
@ -64,7 +64,7 @@ else:
for node in nodes: for node in nodes:
for chunk in node.chunks: for chunk in node.chunks:
print('{}: {}\n'.format(chunk.name, chunk.statistics.toDict())) print(f'{chunk.name}: {chunk.statistics.toDict()}\n')
if args.exportHtml: if args.exportHtml:
with open(args.exportHtml, 'w') as fileObj: with open(args.exportHtml, 'w') as fileObj:

View file

@ -22,7 +22,7 @@ parser.add_argument("--verbose", help="Print full status information",
args = parser.parse_args() args = parser.parse_args()
if not os.path.exists(args.graphFile): 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) sys.exit(-1)
graph = meshroom.core.graph.loadGraph(args.graphFile) graph = meshroom.core.graph.loadGraph(args.graphFile)
@ -32,10 +32,10 @@ graph.update()
if args.node: if args.node:
node = graph.node(args.node) node = graph.node(args.node)
if node is None: 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) sys.exit(-1)
for chunk in node.chunks: for chunk in node.chunks:
print('{}: {}'.format(chunk.name, chunk.status.status.name)) print(f'{chunk.name}: {chunk.status.status.name}')
if args.verbose: if args.verbose:
print('statusFile: ', node.statusFile) print('statusFile: ', node.statusFile)
pprint(node.status.toDict()) pprint(node.status.toDict())
@ -46,6 +46,6 @@ else:
nodes, edges = graph.dfsOnFinish(startNodes=startNodes) nodes, edges = graph.dfsOnFinish(startNodes=startNodes)
for node in nodes: for node in nodes:
for chunk in node.chunks: for chunk in node.chunks:
print('{}: {}'.format(chunk.name, chunk.status.status.name)) print(f'{chunk.name}: {chunk.status.status.name}')
if args.verbose: if args.verbose:
pprint([n.status.toDict() for n in nodes]) pprint([n.status.toDict() for n in nodes])

View file

@ -16,13 +16,13 @@ from functools import partial
from weakref import WeakMethod from weakref import WeakMethod
class Signal(object): class Signal:
""" """
The Signal is the core object that handles connection and emission . The Signal is the core object that handles connection and emission .
""" """
def __init__(self): def __init__(self):
super(Signal, self).__init__() super().__init__()
self._block = False self._block = False
self._sender = None self._sender = None
self._slots = [] self._slots = []
@ -151,7 +151,7 @@ class Signal(object):
return None return None
class ClassSignal(object): class ClassSignal:
""" """
The class signal allows a signal to be set on a class rather than an instance. The class signal allows a signal to be set on a class rather than an instance.
This emulates the behavior of a PyQt signal This emulates the behavior of a PyQt signal
@ -234,7 +234,7 @@ class SignalFactory(dict):
self[signal].block(isBlocked) 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. The class signal allows a signal factory to be set on a class rather than an instance.
""" """

View file

@ -126,13 +126,13 @@ def CoreSlot(*args, **kwargs):
class CoreProperty(property): class CoreProperty(property):
def __init__(self, ptype, fget=None, fset=None, **kwargs): 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): def __init__(self, parent=None, *args, **kwargs):
super(CoreObject, self).__init__() super().__init__()
self._parent = parent self._parent = parent
# Note: we do not use ClassSignal, as it can not be used in __del__. # Note: we do not use ClassSignal, as it can not be used in __del__.
self.destroyed = PySignal.Signal() self.destroyed = PySignal.Signal()

View file

@ -14,7 +14,7 @@ class QObjectListModel(QtCore.QAbstractListModel):
def __init__(self, keyAttrName='', parent=None): def __init__(self, keyAttrName='', parent=None):
""" Constructs an object list model with the given parent. """ """ 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._objects = list() # Internal list of objects
self._keyAttrName = keyAttrName self._keyAttrName = keyAttrName
@ -322,7 +322,7 @@ class QTypedObjectListModel(QObjectListModel):
# TODO: handle notify signal to emit dataChanged signal # TODO: handle notify signal to emit dataChanged signal
def __init__(self, keyAttrName="name", T=QtCore.QObject, parent=None): def __init__(self, keyAttrName="name", T=QtCore.QObject, parent=None):
super(QTypedObjectListModel, self).__init__(keyAttrName, parent) super().__init__(keyAttrName, parent)
self._T = T self._T = T
blacklist = ["id", "index", "class", "model", "modelData"] blacklist = ["id", "index", "class", "model", "modelData"]
@ -340,7 +340,7 @@ class QTypedObjectListModel(QObjectListModel):
print("Reserved role name: " + prop.name()) print("Reserved role name: " + prop.name())
def data(self, index, role): def data(self, index, role):
obj = super(QTypedObjectListModel, self).data(index, self.ObjectRole) obj = super().data(index, self.ObjectRole)
if role == self.ObjectRole: if role == self.ObjectRole:
return obj return obj
if obj: if obj:
@ -355,7 +355,7 @@ class QTypedObjectListModel(QObjectListModel):
if item.staticMetaObject != self._metaObject: if item.staticMetaObject != self._metaObject:
raise TypeError("Invalid object type: expected {}, got {}".format( raise TypeError("Invalid object type: expected {}, got {}".format(
self._metaObject.className(), item.staticMetaObject.className())) self._metaObject.className(), item.staticMetaObject.className()))
super(QTypedObjectListModel, self)._referenceItem(item) super()._referenceItem(item)
class SortedModelByReference(QtCore.QSortFilterProxyModel): 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. This proxy is useful if the model needs to be sorted a certain way for a specific use.
""" """
def __init__(self, parent): def __init__(self, parent):
super(SortedModelByReference, self).__init__(parent) super().__init__(parent)
self._reference = [] self._reference = []
def setReference(self, iterable): def setReference(self, iterable):
@ -385,7 +385,7 @@ class SortedModelByReference(QtCore.QSortFilterProxyModel):
def sort(self): def sort(self):
""" Sort the proxy and call invalidate() """ """ Sort the proxy and call invalidate() """
super(SortedModelByReference, self).sort(0, QtCore.Qt.AscendingOrder) super().sort(0, QtCore.Qt.AscendingOrder)
self.invalidate() self.invalidate()

View file

@ -161,7 +161,7 @@ def validateNodeDesc(nodeDesc):
return errors return errors
class Version(object): class Version:
""" """
Version provides convenient properties and methods to manipulate and compare versions. Version provides convenient properties and methods to manipulate and compare versions.
""" """
@ -173,19 +173,19 @@ class Version(object):
""" """
if len(args) == 0: if len(args) == 0:
self.components = tuple() self.components = tuple()
self.status = str() self.status = ''
elif len(args) == 1: elif len(args) == 1:
versionName = args[0] versionName = args[0]
if isinstance(versionName, str): if isinstance(versionName, str):
self.components, self.status = Version.toComponents(versionName) self.components, self.status = Version.toComponents(versionName)
elif isinstance(versionName, (list, tuple)): elif isinstance(versionName, (list, tuple)):
self.components = tuple([int(v) for v in versionName]) self.components = tuple([int(v) for v in versionName])
self.status = str() self.status = ''
else: else:
raise RuntimeError("Version: Unsupported input type.") raise RuntimeError("Version: Unsupported input type.")
else: else:
self.components = tuple([int(v) for v in args]) self.components = tuple([int(v) for v in args])
self.status = str() self.status = ''
def __repr__(self): def __repr__(self):
return self.name return self.name
@ -245,9 +245,9 @@ class Version(object):
tuple of int, string: split version numbers, status if any (or empty string) tuple of int, string: split version numbers, status if any (or empty string)
""" """
if not versionName: if not versionName:
return (), str() return (), ''
status = str() status = ''
# If there is a status, it is placed after a "-" # If there is a status, it is placed after a "-"
splitComponents = versionName.split("-", maxsplit=1) splitComponents = versionName.split("-", maxsplit=1)
if (len(splitComponents) > 1): # If there is no status, splitComponents is equal to [versionName] if (len(splitComponents) > 1): # If there is no status, splitComponents is equal to [versionName]

View file

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# coding:utf-8
import copy import copy
import os import os
import re import re
@ -57,7 +56,7 @@ class Attribute(BaseObject):
root (Attribute): (optional) the root Attribute (List or Group) containing this one root (Attribute): (optional) the root Attribute (List or Group) containing this one
parent (BaseObject): (optional) the parent BaseObject parent (BaseObject): (optional) the parent BaseObject
""" """
super(Attribute, self).__init__(parent) super().__init__(parent)
self._name = attributeDesc.name self._name = attributeDesc.name
self._root = None if root is None else weakref.ref(root) self._root = None if root is None else weakref.ref(root)
self._node = weakref.ref(node) self._node = weakref.ref(node)
@ -473,7 +472,7 @@ def raiseIfLink(func):
class PushButtonParam(Attribute): class PushButtonParam(Attribute):
def __init__(self, node, attributeDesc, isOutput, root=None, parent=None): 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() @Slot()
def clicked(self): def clicked(self):
@ -483,7 +482,7 @@ class PushButtonParam(Attribute):
class ChoiceParam(Attribute): class ChoiceParam(Attribute):
def __init__(self, node, attributeDesc: desc.ChoiceParam, isOutput, root=None, parent=None): 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 self._values = None
def __len__(self): def __len__(self):
@ -544,7 +543,7 @@ class ChoiceParam(Attribute):
class ListAttribute(Attribute): class ListAttribute(Attribute):
def __init__(self, node, attributeDesc, isOutput, root=None, parent=None): 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): def __len__(self):
if self._value is None: if self._value is None:
@ -650,13 +649,13 @@ class ListAttribute(Attribute):
if value.invalidate: if value.invalidate:
uids.append(value.uid()) uids.append(value.uid())
return hashValue(uids) return hashValue(uids)
return super(ListAttribute, self).uid() return super().uid()
def _applyExpr(self): def _applyExpr(self):
if not self.node.graph: if not self.node.graph:
return return
if isinstance(self._value, ListAttribute) or Attribute.isLinkExpression(self._value): if isinstance(self._value, ListAttribute) or Attribute.isLinkExpression(self._value):
super(ListAttribute, self)._applyExpr() super()._applyExpr()
else: else:
for value in self._value: for value in self._value:
value._applyExpr() value._applyExpr()
@ -689,7 +688,7 @@ class ListAttribute(Attribute):
return v return v
def updateInternals(self): def updateInternals(self):
super(ListAttribute, self).updateInternals() super().updateInternals()
for attr in self._value: for attr in self._value:
attr.updateInternals() attr.updateInternals()
@ -711,11 +710,11 @@ class ListAttribute(Attribute):
class GroupAttribute(Attribute): class GroupAttribute(Attribute):
def __init__(self, node, attributeDesc, isOutput, root=None, parent=None): 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): def __getattr__(self, key):
try: try:
return super(GroupAttribute, self).__getattr__(key) return super().__getattr__(key)
except AttributeError: except AttributeError:
try: try:
return self._value.get(key) return self._value.get(key)
@ -831,7 +830,7 @@ class GroupAttribute(Attribute):
return f'{strBegin}{s}{strEnd}' return f'{strBegin}{s}{strEnd}'
def updateInternals(self): def updateInternals(self):
super(GroupAttribute, self).updateInternals() super().updateInternals()
for attr in self._value: for attr in self._value:
attr.updateInternals() attr.updateInternals()

View file

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# coding:utf-8
import os import os
@ -15,7 +14,7 @@ def getCgroupMemorySize():
cgroup = None cgroup = None
try: try:
with open(filename, "r") as f: with open(filename) as f:
# cgroup file is a ':' separated table # cgroup file is a ':' separated table
# lookup a line where the second field is "memory" # lookup a line where the second field is "memory"
@ -35,7 +34,7 @@ def getCgroupMemorySize():
size = -1 size = -1
filename = f"/sys/fs/cgroup/memory/{cgroup}/memory.limit_in_bytes" filename = f"/sys/fs/cgroup/memory/{cgroup}/memory.limit_in_bytes"
try: try:
with open(filename, "r") as f: with open(filename) as f:
value = f.read().rstrip("\r\n") value = f.read().rstrip("\r\n")
if value.isnumeric(): if value.isnumeric():
size = int(value) size = int(value)
@ -72,7 +71,7 @@ def getCgroupCpuCount():
cgroup = None cgroup = None
try: try:
with open(filename, "r") as f: with open(filename) as f:
# cgroup file is a ':' separated table # cgroup file is a ':' separated table
# lookup a line where the second field is "memory" # lookup a line where the second field is "memory"
@ -92,7 +91,7 @@ def getCgroupCpuCount():
size = -1 size = -1
filename = f"/sys/fs/cgroup/cpuset/{cgroup}/cpuset.cpus" filename = f"/sys/fs/cgroup/cpuset/{cgroup}/cpuset.cpus"
try: try:
with open(filename, "r") as f: with open(filename) as f:
value = f.read().rstrip("\r\n") value = f.read().rstrip("\r\n")
nlist = parseNumericList(value) nlist = parseNumericList(value)
size = len(nlist) size = len(nlist)

View file

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# coding:utf-8
class MeshroomException(Exception): class MeshroomException(Exception):
@ -33,7 +32,7 @@ class UnknownNodeTypeError(GraphException):
""" """
def __init__(self, nodeType, msg=None): def __init__(self, nodeType, msg=None):
msg = "Unknown Node Type: " + nodeType msg = "Unknown Node Type: " + nodeType
super(UnknownNodeTypeError, self).__init__(msg) super().__init__(msg)
self.nodeType = nodeType self.nodeType = nodeType
@ -42,7 +41,7 @@ class NodeUpgradeError(GraphException):
msg = f"Failed to upgrade node {nodeName}" msg = f"Failed to upgrade node {nodeName}"
if details: if details:
msg += f": {details}" msg += f": {details}"
super(NodeUpgradeError, self).__init__(msg) super().__init__(msg)
class GraphVisitMessage(GraphException): class GraphVisitMessage(GraphException):

View file

@ -1,10 +1,9 @@
from __future__ import print_function
import json import json
import logging import logging
import os import os
import re import re
from typing import Any, Iterable, Optional from typing import Any, Optional
from collections.abc import Iterable
import weakref import weakref
from collections import defaultdict, OrderedDict from collections import defaultdict, OrderedDict
from contextlib import contextmanager from contextlib import contextmanager
@ -63,7 +62,7 @@ def GraphModification(graph):
class Edge(BaseObject): class Edge(BaseObject):
def __init__(self, src, dst, parent=None): def __init__(self, src, dst, parent=None):
super(Edge, self).__init__(parent) super().__init__(parent)
self._src = weakref.ref(src) self._src = weakref.ref(src)
self._dst = weakref.ref(dst) self._dst = weakref.ref(dst)
self._repr = f"<Edge> {self._src()} -> {self._dst()}" self._repr = f"<Edge> {self._src()} -> {self._dst()}"
@ -85,13 +84,13 @@ GRAY = 1
BLACK = 2 BLACK = 2
class Visitor(object): class Visitor:
""" """
Base class for Graph Visitors that does nothing. Base class for Graph Visitors that does nothing.
Sub-classes can override any method to implement specific algorithms. Sub-classes can override any method to implement specific algorithms.
""" """
def __init__(self, reverse, dependenciesOnly): def __init__(self, reverse, dependenciesOnly):
super(Visitor, self).__init__() super().__init__()
self.reverse = reverse self.reverse = reverse
self.dependenciesOnly = dependenciesOnly self.dependenciesOnly = dependenciesOnly
@ -197,7 +196,7 @@ class Graph(BaseObject):
""" """
def __init__(self, name: str = "", parent: BaseObject = None): def __init__(self, name: str = "", parent: BaseObject = None):
super(Graph, self).__init__(parent) super().__init__(parent)
self.name: str = name self.name: str = name
self._loading: bool = False self._loading: bool = False
self._saving: bool = False self._saving: bool = False
@ -339,7 +338,7 @@ class Graph(BaseObject):
uidOccurrences = uidPattern.findall(updatedFileData) uidOccurrences = uidPattern.findall(updatedFileData)
for occ in uidOccurrences: for occ in uidOccurrences:
uid = occ.split("\"")[-2] # UID is second to last element uid = occ.split("\"")[-2] # UID is second to last element
newUidStr = r'"uid": "{}"'.format(uid) newUidStr = fr'"uid": "{uid}"'
updatedFileData = updatedFileData.replace(occ, newUidStr) updatedFileData = updatedFileData.replace(occ, newUidStr)
graphContent = json.loads(updatedFileData) graphContent = json.loads(updatedFileData)
@ -856,11 +855,11 @@ class Graph(BaseObject):
return self._edges.get(dstAttributeName) return self._edges.get(dstAttributeName)
def getLeafNodes(self, dependenciesOnly): 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 return set(self._nodes) - nodesWithOutputLink
def getRootNodes(self, dependenciesOnly): 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 return set(self._nodes) - nodesWithInputLink
@changeTopology @changeTopology
@ -910,7 +909,7 @@ class Graph(BaseObject):
return minDepth if minimal else maxDepth return minDepth if minimal else maxDepth
def getInputEdges(self, node, dependenciesOnly): 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): def _getInputEdgesPerNode(self, dependenciesOnly):
nodeEdges = defaultdict(set) nodeEdges = defaultdict(set)
@ -1167,7 +1166,7 @@ class Graph(BaseObject):
:return: :return:
""" """
nodesStack = [] nodesStack = []
edgesScore = defaultdict(lambda: 0) edgesScore = defaultdict(int)
visitor = Visitor(reverse=False, dependenciesOnly=dependenciesOnly) visitor = Visitor(reverse=False, dependenciesOnly=dependenciesOnly)
def finishEdge(edge, graph): def finishEdge(edge, graph):
@ -1223,7 +1222,7 @@ class Graph(BaseObject):
def getInputNodes(self, node, recursive, dependenciesOnly): def getInputNodes(self, node, recursive, dependenciesOnly):
""" Return either the first level input nodes of a node or the whole chain. """ """ Return either the first level input nodes of a node or the whole chain. """
if not recursive: 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) inputNodes, edges = self.dfsOnDiscover(startNodes=[node], filterTypes=None, reverse=False)
return inputNodes[1:] # exclude current node return inputNodes[1:] # exclude current node
@ -1231,7 +1230,7 @@ class Graph(BaseObject):
def getOutputNodes(self, node, recursive, dependenciesOnly): def getOutputNodes(self, node, recursive, dependenciesOnly):
""" Return either the first level output nodes of a node or the whole chain. """ """ Return either the first level output nodes of a node or the whole chain. """
if not recursive: 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) outputNodes, edges = self.dfsOnDiscover(startNodes=[node], filterTypes=None, reverse=True)
return outputNodes[1:] # exclude current node return outputNodes[1:] # exclude current node
@ -1253,7 +1252,7 @@ class Graph(BaseObject):
class SCVisitor(Visitor): class SCVisitor(Visitor):
def __init__(self, reverse, dependenciesOnly): def __init__(self, reverse, dependenciesOnly):
super(SCVisitor, self).__init__(reverse, dependenciesOnly) super().__init__(reverse, dependenciesOnly)
canCompute = True canCompute = True
canSubmit = True canSubmit = True
@ -1611,7 +1610,7 @@ def executeGraph(graph, toNodes=None, forceCompute=False, forceStatus=False):
chunksInConflict = getAlreadySubmittedChunks(nodes) chunksInConflict = getAlreadySubmittedChunks(nodes)
if chunksInConflict: 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] chunksName = [node.name for node in chunksInConflict]
msg = 'WARNING: Some nodes are already submitted with status: {}\nNodes: {}'.format( msg = 'WARNING: Some nodes are already submitted with status: {}\nNodes: {}'.format(
', '.join(chunksStatus), ', '.join(chunksStatus),

View file

@ -15,7 +15,7 @@ class GraphIO:
__version__ = "2.0" __version__ = "2.0"
class Keys(object): class Keys:
"""File Keys.""" """File Keys."""
# Doesn't inherit enum to simplify usage (GraphIO.Keys.XX, without .value) # Doesn't inherit enum to simplify usage (GraphIO.Keys.XX, without .value)
@ -98,7 +98,7 @@ class GraphSerializer:
def _getNodeTypesVersions(self) -> dict[str, str]: def _getNodeTypesVersions(self) -> dict[str, str]:
"""Get registered versions of each node types in `nodes`, excluding CompatibilityNode instances.""" """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 = { nodeTypesVersions = {
nodeType.__name__: version nodeType.__name__: version
for nodeType in nodeTypes for nodeType in nodeTypes

View file

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# coding:utf-8
import atexit import atexit
import copy import copy
import datetime import datetime
@ -37,7 +36,7 @@ def renameWritingToFinalPath(writingFilepath: str, filepath: str) -> str:
os.remove(filepath) os.remove(filepath)
# If remove is successful, we can stop the iterations # If remove is successful, we can stop the iterations
break break
except WindowsError: except OSError:
pass pass
os.rename(writingFilepath, filepath) os.rename(writingFilepath, filepath)
@ -70,7 +69,7 @@ class StatusData(BaseObject):
def __init__(self, nodeName='', nodeType='', packageName='', packageVersion='', def __init__(self, nodeName='', nodeType='', packageName='', packageVersion='',
mrNodeType: MrNodeType = MrNodeType.NONE, parent: BaseObject = None): mrNodeType: MrNodeType = MrNodeType.NONE, parent: BaseObject = None):
super(StatusData, self).__init__(parent) super().__init__(parent)
self.nodeName: str = nodeName self.nodeName: str = nodeName
self.nodeType: str = nodeType self.nodeType: str = nodeType
@ -267,7 +266,7 @@ class LogManager:
f.close() f.close()
with open(self.chunk.logFile, 'r') as f: with open(self.chunk.logFile) as f:
content = f.read() content = f.read()
self.progressBarPosition = content.rfind('\n') self.progressBarPosition = content.rfind('\n')
@ -320,7 +319,7 @@ def clearProcessesStatus():
class NodeChunk(BaseObject): class NodeChunk(BaseObject):
def __init__(self, node, range, parent=None): def __init__(self, node, range, parent=None):
super(NodeChunk, self).__init__(parent) super().__init__(parent)
self.node = node self.node = node
self.range = range self.range = range
self.logManager: LogManager = LogManager(self) self.logManager: LogManager = LogManager(self)
@ -368,7 +367,7 @@ class NodeChunk(BaseObject):
self._status.setNodeType(self.node) self._status.setNodeType(self.node)
else: else:
try: try:
with open(statusFile, 'r') as jsonFile: with open(statusFile) as jsonFile:
statusData = json.load(jsonFile) statusData = json.load(jsonFile)
# logging.debug(f"updateStatusFromCache({self.node.name}): From status {self.status.status} to {statusData['status']}") # logging.debug(f"updateStatusFromCache({self.node.name}): From status {self.status.status} to {statusData['status']}")
self._status.fromDict(statusData) self._status.fromDict(statusData)
@ -443,7 +442,7 @@ class NodeChunk(BaseObject):
statisticsFile = self.statisticsFile statisticsFile = self.statisticsFile
if not os.path.exists(statisticsFile): if not os.path.exists(statisticsFile):
return return
with open(statisticsFile, 'r') as jsonFile: with open(statisticsFile) as jsonFile:
statisticsData = json.load(jsonFile) statisticsData = json.load(jsonFile)
self.statistics.fromDict(statisticsData) self.statistics.fromDict(statisticsData)
if oldTimes != self.statistics.times: if oldTimes != self.statistics.times:
@ -635,7 +634,7 @@ class BaseNode(BaseObject):
parent: this Node's parent parent: this Node's parent
**kwargs: attributes values **kwargs: attributes values
""" """
super(BaseNode, self).__init__(parent) super().__init__(parent)
self._nodeType: str = nodeType self._nodeType: str = nodeType
self.nodeDesc: desc.BaseNode = None self.nodeDesc: desc.BaseNode = None
@ -1311,7 +1310,7 @@ class BaseNode(BaseObject):
return return
# logging.warning("load output attr: {}, value: {}".format(self.name, valuesFile)) # 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) data = json.load(jsonFile)
# logging.warning(data) # logging.warning(data)
@ -1513,8 +1512,8 @@ class BaseNode(BaseObject):
# If number of elements in both lists are identical, # If number of elements in both lists are identical,
# we must check if their content is the same # we must check if their content is the same
if len(newList) == len(self._duplicates): if len(newList) == len(self._duplicates):
newListName = set([node.name for node in newList]) newListName = {node.name for node in newList}
oldListName = set([node.name for node in self._duplicates.values()]) oldListName = {node.name for node in self._duplicates.values()}
# If strict equality between both sets, # If strict equality between both sets,
# there is no need to set the new list # 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. A standard Graph node based on a node type.
""" """
def __init__(self, nodeType, position=None, parent=None, uid=None, **kwargs): 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: if not self.nodeDesc:
raise UnknownNodeTypeError(nodeType) raise UnknownNodeTypeError(nodeType)
@ -1834,7 +1833,7 @@ class CompatibilityNode(BaseNode):
with all its inputs and precomputed outputs. with all its inputs and precomputed outputs.
""" """
def __init__(self, nodeType, nodeDict, position=None, issue=CompatibilityIssue.UnknownIssue, parent=None): 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 self.issue = issue
# Make a deepcopy of nodeDict to handle CompatibilityNode duplication # Make a deepcopy of nodeDict to handle CompatibilityNode duplication

View file

@ -1,5 +1,6 @@
import logging import logging
from typing import Any, Iterable, Optional, Union from typing import Any, Optional, Union
from collections.abc import Iterable
import meshroom.core import meshroom.core
from meshroom.core import Version, desc from meshroom.core import Version, desc

View file

@ -1,12 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
# coding:utf-8
from meshroom.common import BaseObject, Property from meshroom.common import BaseObject, Property
class BaseSubmitter(BaseObject): class BaseSubmitter(BaseObject):
def __init__(self, name, parent=None): def __init__(self, name, parent=None):
super(BaseSubmitter, self).__init__(parent) super().__init__(parent)
self._name = name self._name = name
def submit(self, nodes, edges, filepath, submitLabel="{projectName}"): def submit(self, nodes, edges, filepath, submitLabel="{projectName}"):

View file

@ -98,7 +98,7 @@ class TaskManager(BaseObject):
Manage graph - local and external - computation tasks. Manage graph - local and external - computation tasks.
""" """
def __init__(self, parent: BaseObject = None): def __init__(self, parent: BaseObject = None):
super(TaskManager, self).__init__(parent) super().__init__(parent)
self._graph = None self._graph = None
self._nodes = DictModel(keyAttrName='_name', parent=self) self._nodes = DictModel(keyAttrName='_name', parent=self)
self._nodesToProcess = [] self._nodesToProcess = []
@ -208,7 +208,7 @@ class TaskManager(BaseObject):
chunksInConflict = self.getAlreadySubmittedChunks(nodes) chunksInConflict = self.getAlreadySubmittedChunks(nodes)
if chunksInConflict: 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] chunksName = [node.name for node in chunksInConflict]
# Warning: Syntax and terms are parsed on QML side to recognize the error # Warning: Syntax and terms are parsed on QML side to recognize the error
# Syntax : [Context] ErrorType: ErrorMessage # Syntax : [Context] ErrorType: ErrorMessage

View file

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# coding:utf-8
from meshroom.core import unregisterNodeType, pipelineTemplates, Version from meshroom.core import unregisterNodeType, pipelineTemplates, Version
from meshroom.core.node import CompatibilityIssue, CompatibilityNode from meshroom.core.node import CompatibilityIssue, CompatibilityNode

View file

@ -1 +0,0 @@
# coding:utf-8

View file

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# coding:utf-8
import os import os
import json import json
@ -24,7 +23,7 @@ class SimpleFarmSubmitter(BaseSubmitter):
DEFAULT_TAGS = {'prod': ''} DEFAULT_TAGS = {'prod': ''}
def __init__(self, parent=None): 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.engine = os.environ.get('MESHROOM_SIMPLEFARM_ENGINE', 'tractor')
self.share = os.environ.get('MESHROOM_SIMPLEFARM_SHARE', 'vfx') self.share = os.environ.get('MESHROOM_SIMPLEFARM_SHARE', 'vfx')
self.prod = os.environ.get('PROD', 'mvg') self.prod = os.environ.get('PROD', 'mvg')

View file

@ -31,7 +31,7 @@ from meshroom.ui.utils import QmlInstantEngine
from meshroom.ui import commands from meshroom.ui import commands
class MessageHandler(object): class MessageHandler:
""" """
MessageHandler that translates Qt logs to Python logging system. MessageHandler that translates Qt logs to Python logging system.
Also contains and filters a list of blacklisted QML warnings that end up in the Also contains and filters a list of blacklisted QML warnings that end up in the
@ -211,7 +211,7 @@ class MeshroomApp(QApplication):
logging.getLogger().setLevel(meshroom.logStringToPython[args.verbose]) logging.getLogger().setLevel(meshroom.logStringToPython[args.verbose])
super(MeshroomApp, self).__init__(inputArgs[:1] + qtArgs) super().__init__(inputArgs[:1] + qtArgs)
self.setOrganizationName('AliceVision') self.setOrganizationName('AliceVision')
self.setApplicationName('Meshroom') self.setApplicationName('Meshroom')

View file

@ -14,7 +14,7 @@ from meshroom.core.mtyping import PathLike
class UndoCommand(QUndoCommand): class UndoCommand(QUndoCommand):
def __init__(self, parent=None): def __init__(self, parent=None):
super(UndoCommand, self).__init__(parent) super().__init__(parent)
self._enabled = True self._enabled = True
def setEnabled(self, enabled): def setEnabled(self, enabled):
@ -47,7 +47,7 @@ class UndoCommand(QUndoCommand):
class UndoStack(QUndoStack): class UndoStack(QUndoStack):
def __init__(self, parent=None): def __init__(self, parent=None):
super(UndoStack, self).__init__(parent) super().__init__(parent)
# connect QUndoStack signal to UndoStack's ones # connect QUndoStack signal to UndoStack's ones
self.cleanChanged.connect(self._cleanChanged) self.cleanChanged.connect(self._cleanChanged)
self.canUndoChanged.connect(self._canUndoChanged) self.canUndoChanged.connect(self._canUndoChanged)
@ -121,13 +121,13 @@ class UndoStack(QUndoStack):
class GraphCommand(UndoCommand): class GraphCommand(UndoCommand):
def __init__(self, graph, parent=None): def __init__(self, graph, parent=None):
super(GraphCommand, self).__init__(parent) super().__init__(parent)
self.graph = graph self.graph = graph
class AddNodeCommand(GraphCommand): class AddNodeCommand(GraphCommand):
def __init__(self, graph, nodeType, position, parent=None, **kwargs): def __init__(self, graph, nodeType, position, parent=None, **kwargs):
super(AddNodeCommand, self).__init__(graph, parent) super().__init__(graph, parent)
self.nodeType = nodeType self.nodeType = nodeType
self.nodeName = None self.nodeName = None
self.position = position self.position = position
@ -153,7 +153,7 @@ class AddNodeCommand(GraphCommand):
class RemoveNodeCommand(GraphCommand): class RemoveNodeCommand(GraphCommand):
def __init__(self, graph, node, parent=None): def __init__(self, graph, node, parent=None):
super(RemoveNodeCommand, self).__init__(graph, parent) super().__init__(graph, parent)
self.nodeDict = node.toDict() self.nodeDict = node.toDict()
self.nodeName = node.getName() self.nodeName = node.getName()
self.setText(f"Remove Node {self.nodeName}") self.setText(f"Remove Node {self.nodeName}")
@ -178,7 +178,7 @@ class DuplicateNodesCommand(GraphCommand):
Handle node duplication in a Graph. Handle node duplication in a Graph.
""" """
def __init__(self, graph, srcNodes, parent=None): 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.srcNodeNames = [ n.name for n in srcNodes ]
self.setText("Duplicate Nodes") self.setText("Duplicate Nodes")
@ -200,7 +200,7 @@ class PasteNodesCommand(GraphCommand):
Handle node pasting in a Graph. Handle node pasting in a Graph.
""" """
def __init__(self, graph: "Graph", data: dict, position: Position, parent=None): 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.data = data
self.position = position self.position = position
self.nodeNames: list[str] = [] self.nodeNames: list[str] = []
@ -253,7 +253,7 @@ class ImportProjectCommand(GraphCommand):
""" """
def __init__(self, graph: Graph, filepath: PathLike, position=None, yOffset=0, parent=None): 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.filepath = filepath
self.importedNames = [] self.importedNames = []
self.position = position self.position = position
@ -285,7 +285,7 @@ class ImportProjectCommand(GraphCommand):
class SetAttributeCommand(GraphCommand): class SetAttributeCommand(GraphCommand):
def __init__(self, graph, attribute, value, parent=None): def __init__(self, graph, attribute, value, parent=None):
super(SetAttributeCommand, self).__init__(graph, parent) super().__init__(graph, parent)
self.attrName = attribute.getFullNameToNode() self.attrName = attribute.getFullNameToNode()
self.value = value self.value = value
self.oldValue = attribute.getExportValue() self.oldValue = attribute.getExportValue()
@ -309,7 +309,7 @@ class SetAttributeCommand(GraphCommand):
class AddEdgeCommand(GraphCommand): class AddEdgeCommand(GraphCommand):
def __init__(self, graph, src, dst, parent=None): def __init__(self, graph, src, dst, parent=None):
super(AddEdgeCommand, self).__init__(graph, parent) super().__init__(graph, parent)
self.srcAttr = src.getFullNameToNode() self.srcAttr = src.getFullNameToNode()
self.dstAttr = dst.getFullNameToNode() self.dstAttr = dst.getFullNameToNode()
self.setText(f"Connect '{self.srcAttr}'->'{self.dstAttr}'") self.setText(f"Connect '{self.srcAttr}'->'{self.dstAttr}'")
@ -327,7 +327,7 @@ class AddEdgeCommand(GraphCommand):
class RemoveEdgeCommand(GraphCommand): class RemoveEdgeCommand(GraphCommand):
def __init__(self, graph, edge, parent=None): def __init__(self, graph, edge, parent=None):
super(RemoveEdgeCommand, self).__init__(graph, parent) super().__init__(graph, parent)
self.srcAttr = edge.src.getFullNameToNode() self.srcAttr = edge.src.getFullNameToNode()
self.dstAttr = edge.dst.getFullNameToNode() self.dstAttr = edge.dst.getFullNameToNode()
self.setText(f"Disconnect '{self.srcAttr}'->'{self.dstAttr}'") self.setText(f"Disconnect '{self.srcAttr}'->'{self.dstAttr}'")
@ -343,7 +343,7 @@ class RemoveEdgeCommand(GraphCommand):
class ListAttributeAppendCommand(GraphCommand): class ListAttributeAppendCommand(GraphCommand):
def __init__(self, graph, listAttribute, value, parent=None): def __init__(self, graph, listAttribute, value, parent=None):
super(ListAttributeAppendCommand, self).__init__(graph, parent) super().__init__(graph, parent)
assert isinstance(listAttribute, ListAttribute) assert isinstance(listAttribute, ListAttribute)
self.attrName = listAttribute.getFullNameToNode() self.attrName = listAttribute.getFullNameToNode()
self.index = None self.index = None
@ -368,7 +368,7 @@ class ListAttributeAppendCommand(GraphCommand):
class ListAttributeRemoveCommand(GraphCommand): class ListAttributeRemoveCommand(GraphCommand):
def __init__(self, graph, attribute, parent=None): def __init__(self, graph, attribute, parent=None):
super(ListAttributeRemoveCommand, self).__init__(graph, parent) super().__init__(graph, parent)
listAttribute = attribute.root listAttribute = attribute.root
assert isinstance(listAttribute, ListAttribute) assert isinstance(listAttribute, ListAttribute)
self.listAttrName = listAttribute.getFullNameToNode() self.listAttrName = listAttribute.getFullNameToNode()
@ -388,7 +388,7 @@ class ListAttributeRemoveCommand(GraphCommand):
class RemoveImagesCommand(GraphCommand): class RemoveImagesCommand(GraphCommand):
def __init__(self, graph, cameraInitNodes, parent=None): def __init__(self, graph, cameraInitNodes, parent=None):
super(RemoveImagesCommand, self).__init__(graph, parent) super().__init__(graph, parent)
self.cameraInits = cameraInitNodes self.cameraInits = cameraInitNodes
self.viewpoints = { cameraInit.name: cameraInit.attribute("viewpoints").getExportValue() for cameraInit in self.cameraInits } 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.intrinsics = { cameraInit.name: cameraInit.attribute("intrinsics").getExportValue() for cameraInit in self.cameraInits }
@ -417,7 +417,7 @@ class RemoveImagesCommand(GraphCommand):
class MoveNodeCommand(GraphCommand): class MoveNodeCommand(GraphCommand):
""" Move a node to a given position. """ """ Move a node to a given position. """
def __init__(self, graph, node, position, parent=None): def __init__(self, graph, node, position, parent=None):
super(MoveNodeCommand, self).__init__(graph, parent) super().__init__(graph, parent)
self.nodeName = node.name self.nodeName = node.name
self.oldPosition = node.position self.oldPosition = node.position
self.newPosition = position self.newPosition = position
@ -436,7 +436,7 @@ class UpgradeNodeCommand(GraphCommand):
Perform node upgrade on a CompatibilityNode. Perform node upgrade on a CompatibilityNode.
""" """
def __init__(self, graph, node, parent=None): def __init__(self, graph, node, parent=None):
super(UpgradeNodeCommand, self).__init__(graph, parent) super().__init__(graph, parent)
self.nodeDict = node.toDict() self.nodeDict = node.toDict()
self.nodeName = node.getName() self.nodeName = node.getName()
self.compatibilityIssue = None self.compatibilityIssue = None
@ -464,7 +464,7 @@ class EnableGraphUpdateCommand(GraphCommand):
Should not be used directly, use GroupedGraphModification context manager instead. Should not be used directly, use GroupedGraphModification context manager instead.
""" """
def __init__(self, graph, enabled, parent=None): def __init__(self, graph, enabled, parent=None):
super(EnableGraphUpdateCommand, self).__init__(graph, parent) super().__init__(graph, parent)
self.enabled = enabled self.enabled = enabled
self.previousState = self.graph.updateEnabled self.previousState = self.graph.updateEnabled

View file

@ -1,5 +1,4 @@
#!/usr/bin/env python #!/usr/bin/env python
# coding:utf-8
from collections.abc import Iterable from collections.abc import Iterable
import logging import logging
import os import os
@ -7,7 +6,8 @@ import json
from enum import Enum from enum import Enum
from threading import Thread, Event, Lock from threading import Thread, Event, Lock
from multiprocessing.pool import ThreadPool 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 ( from PySide6.QtCore import (
Slot, Slot,
@ -49,7 +49,7 @@ class FilesModTimePollerThread(QObject):
timesAvailable = Signal(list) timesAvailable = Signal(list)
def __init__(self, parent=None): def __init__(self, parent=None):
super(FilesModTimePollerThread, self).__init__(parent) super().__init__(parent)
self._thread = None self._thread = None
self._mutex = Lock() self._mutex = Lock()
self._threadPool = ThreadPool(4) 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. Thus, for genericity, monitoring is based on regular polling and not file system watching.
""" """
def __init__(self, chunks=(), parent=None): def __init__(self, chunks=(), parent=None):
super(ChunksMonitor, self).__init__(parent) super().__init__(parent)
self.monitorableChunks = [] self.monitorableChunks = []
self.monitoredChunks = [] self.monitoredChunks = []
self._filesTimePoller = FilesModTimePollerThread(parent=self) self._filesTimePoller = FilesModTimePollerThread(parent=self)
@ -254,7 +254,7 @@ class GraphLayout(QObject):
} }
def __init__(self, graph): def __init__(self, graph):
super(GraphLayout, self).__init__(graph) super().__init__(graph)
self.graph = graph self.graph = graph
self._depthMode = GraphLayout.DepthMode.MaxDepth self._depthMode = GraphLayout.DepthMode.MaxDepth
self._nodeWidth = 160 # implicit node width self._nodeWidth = 160 # implicit node width
@ -365,7 +365,7 @@ class UIGraph(QObject):
It also provides a monitoring of all its computation units (NodeChunks). It also provides a monitoring of all its computation units (NodeChunks).
""" """
def __init__(self, undoStack: commands.UndoStack, taskManager: TaskManager, parent: QObject = None): def __init__(self, undoStack: commands.UndoStack, taskManager: TaskManager, parent: QObject = None):
super(UIGraph, self).__init__(parent) super().__init__(parent)
self._undoStack = undoStack self._undoStack = undoStack
self._taskManager = taskManager self._taskManager = taskManager
self._graph: Graph = Graph('', self) self._graph: Graph = Graph('', self)

View file

@ -8,7 +8,7 @@ class PaletteManager(QObject):
Manages QApplication's palette and provides a toggle between a dark and a light theme. Manages QApplication's palette and provides a toggle between a dark and a light theme.
""" """
def __init__(self, qmlEngine, parent=None): def __init__(self, qmlEngine, parent=None):
super(PaletteManager, self).__init__(parent) super().__init__(parent)
self.qmlEngine = qmlEngine self.qmlEngine = qmlEngine
darkPalette = QPalette() darkPalette = QPalette()
window = QColor(50, 52, 55) window = QColor(50, 52, 55)

View file

@ -29,7 +29,7 @@ class Message(QObject):
""" Simple structure wrapping a high-level message. """ """ Simple structure wrapping a high-level message. """
def __init__(self, title, text, detailedText="", parent=None): def __init__(self, title, text, detailedText="", parent=None):
super(Message, self).__init__(parent) super().__init__(parent)
self._title = title self._title = title
self._text = text self._text = text
self._detailedText = detailedText 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. File watching is based on regular polling and not filesystem events to work on network mounts.
""" """
def __init__(self, reconstruction): def __init__(self, reconstruction):
super(LiveSfmManager, self).__init__(reconstruction) super().__init__(reconstruction)
self.reconstruction = reconstruction self.reconstruction = reconstruction
self._folder = '' self._folder = ''
self.timerId = -1 self.timerId = -1
@ -188,7 +188,7 @@ class ViewpointWrapper(QObject):
viewpointAttribute (GroupAttribute): viewpoint attribute viewpointAttribute (GroupAttribute): viewpoint attribute
reconstruction (Reconstruction): owner reconstruction of this Viewpoint reconstruction (Reconstruction): owner reconstruction of this Viewpoint
""" """
super(ViewpointWrapper, self).__init__(parent=reconstruction) super().__init__(parent=reconstruction)
self._viewpoint = viewpointAttribute self._viewpoint = viewpointAttribute
self._reconstruction = reconstruction self._reconstruction = reconstruction
@ -428,7 +428,7 @@ class ActiveNode(QObject):
Hold one active node for a given NodeType. Hold one active node for a given NodeType.
""" """
def __init__(self, nodeType, parent=None): def __init__(self, nodeType, parent=None):
super(ActiveNode, self).__init__(parent) super().__init__(parent)
self.nodeType = nodeType self.nodeType = nodeType
self._node = None self._node = None
@ -467,7 +467,7 @@ class Reconstruction(UIGraph):
] ]
def __init__(self, undoStack: commands.UndoStack, taskManager: TaskManager, defaultPipeline: str="", parent: QObject=None): 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 # initialize member variables for key steps of the 3D reconstruction pipeline
self._active = False self._active = False
@ -515,7 +515,7 @@ class Reconstruction(UIGraph):
@Slot() @Slot()
def clear(self): def clear(self):
self.clearActiveNodes() self.clearActiveNodes()
super(Reconstruction, self).clear() super().clear()
self.setActive(False) self.setActive(False)
def setDefaultPipeline(self, defaultPipeline): def setDefaultPipeline(self, defaultPipeline):
@ -554,7 +554,7 @@ class Reconstruction(UIGraph):
# Lower the input and the dictionary keys to make sure that all input types can be found: # 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) # - correct pipeline name but the case does not match (e.g. panoramaHDR instead of panoramaHdr)
# - lowercase pipeline name given through the "New Pipeline" menu # - 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) filepath = loweredPipelineTemplates.get(p.lower(), p)
return self._loadWithErrorReport(self.initFromTemplate, filepath) return self._loadWithErrorReport(self.initFromTemplate, filepath)
@ -698,7 +698,7 @@ class Reconstruction(UIGraph):
if not os.path.exists(sfmFile): if not os.path.exists(sfmFile):
return QVector3D(0.0, 0.0, 0.0) return QVector3D(0.0, 0.0, 0.0)
# skip decoding errors to avoid potential exceptions due to non utf-8 characters in images metadata # 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) data = json.load(f)
intrinsics = data.get('intrinsics', []) intrinsics = data.get('intrinsics', [])
@ -881,7 +881,7 @@ class Reconstruction(UIGraph):
if not filesByType["images"] and not filesByType["videos"] and not filesByType["panoramaInfo"] and not filesByType["meshroomScenes"]: if not filesByType["images"] and not filesByType["videos"] and not filesByType["panoramaInfo"] and not filesByType["meshroomScenes"]:
if filesByType["other"]: 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( self.error.emit(
Message( Message(
"No Recognized Input File", "No Recognized Input File",

View file

@ -21,7 +21,7 @@ class QmlInstantEngine(QQmlApplicationEngine):
watching -- Defines whether the watcher is active (default: True) watching -- Defines whether the watcher is active (default: True)
verbose -- if True, output log infos (default: False) verbose -- if True, output log infos (default: False)
""" """
super(QmlInstantEngine, self).__init__(parent) super().__init__(parent)
self._fileWatcher = QFileSystemWatcher() # Internal Qt File Watcher self._fileWatcher = QFileSystemWatcher() # Internal Qt File Watcher
self._sourceFile = "" self._sourceFile = ""
@ -51,7 +51,7 @@ class QmlInstantEngine(QQmlApplicationEngine):
def load(self, sourceFile): def load(self, sourceFile):
self._sourceFile = sourceFile self._sourceFile = sourceFile
super(QmlInstantEngine, self).load(sourceFile) super().load(sourceFile)
def setWatching(self, watchValue): def setWatching(self, watchValue):
""" """