diff --git a/meshroom/core/__init__.py b/meshroom/core/__init__.py index 425806c6..b57e5871 100644 --- a/meshroom/core/__init__.py +++ b/meshroom/core/__init__.py @@ -23,7 +23,6 @@ except: from meshroom.core.submitter import BaseSubmitter from . import desc -from . import pyCompatibility # Setup logging logging.basicConfig(format='[%(asctime)s][%(levelname)s] %(message)s', level=logging.INFO) @@ -150,7 +149,7 @@ class Version(object): self.components = tuple() elif len(args) == 1: versionName = args[0] - if isinstance(versionName, pyCompatibility.basestring): + if isinstance(versionName, str): self.components = Version.toComponents(versionName) elif isinstance(versionName, (list, tuple)): self.components = tuple([int(v) for v in versionName]) diff --git a/meshroom/core/attribute.py b/meshroom/core/attribute.py index eccffd64..e0d71cd3 100644 --- a/meshroom/core/attribute.py +++ b/meshroom/core/attribute.py @@ -7,9 +7,10 @@ import weakref import types import logging +from collections.abc import Sequence from string import Template from meshroom.common import BaseObject, Property, Variant, Signal, ListModel, DictModel, Slot -from meshroom.core import desc, pyCompatibility, hashValue +from meshroom.core import desc, hashValue def attributeFactory(description, value, isOutput, node, root=None, parent=None): @@ -213,7 +214,7 @@ class Attribute(BaseObject): Return whether the given argument is a link expression. A link expression is a string matching the {nodeName.attrName} pattern. """ - return isinstance(value, pyCompatibility.basestring) and Attribute.stringIsLinkRe.match(value) + return isinstance(value, str) and Attribute.stringIsLinkRe.match(value) def getLinkParam(self, recursive=False): if not self.isLink: @@ -264,13 +265,13 @@ class Attribute(BaseObject): return self._value def getEvalValue(self): - if isinstance(self.value, pyCompatibility.basestring): + if isinstance(self.value, str): return Template(self.value).safe_substitute(os.environ) return self.value def getValueStr(self): if isinstance(self.attributeDesc, desc.ChoiceParam) and not self.attributeDesc.exclusive: - assert(isinstance(self.value, pyCompatibility.Sequence) and not isinstance(self.value, pyCompatibility.basestring)) + assert(isinstance(self.value, Sequence) and not isinstance(self.value, str)) return self.attributeDesc.joinChar.join(self.getEvalValue()) if isinstance(self.attributeDesc, (desc.StringParam, desc.File)): return '"{}"'.format(self.getEvalValue()) diff --git a/meshroom/core/desc.py b/meshroom/core/desc.py index 53e08ab8..20cc816f 100644 --- a/meshroom/core/desc.py +++ b/meshroom/core/desc.py @@ -1,6 +1,6 @@ from meshroom.common import BaseObject, Property, Variant, VariantList, JSValue -from meshroom.core import pyCompatibility +from collections.abc import Iterable from enum import Enum # available by default in python3. For python2: "pip install enum34" import math import os @@ -85,7 +85,7 @@ class ListAttribute(Attribute): if JSValue is not None and isinstance(value, JSValue): # Note: we could use isArray(), property("length").toInt() to retrieve all values raise ValueError("ListAttribute.validateValue: cannot recognize QJSValue. Please, use JSON.stringify(value) in QML.") - if isinstance(value, pyCompatibility.basestring): + if isinstance(value, str): # Alternative solution to set values from QML is to convert values to JSON string # In this case, it works with all data types value = ast.literal_eval(value) @@ -124,7 +124,7 @@ class GroupAttribute(Attribute): if JSValue is not None and isinstance(value, JSValue): # Note: we could use isArray(), property("length").toInt() to retrieve all values raise ValueError("GroupAttribute.validateValue: cannot recognize QJSValue. Please, use JSON.stringify(value) in QML.") - if isinstance(value, pyCompatibility.basestring): + if isinstance(value, str): # Alternative solution to set values from QML is to convert values to JSON string # In this case, it works with all data types value = ast.literal_eval(value) @@ -211,14 +211,14 @@ class File(Attribute): super(File, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, semantic=semantic, enabled=enabled) def validateValue(self, value): - if not isinstance(value, pyCompatibility.basestring): + if not isinstance(value, str): raise ValueError('File only supports string input (param:{}, value:{}, type:{})'.format(self.name, value, type(value))) return os.path.normpath(value).replace('\\', '/') if value else '' def checkValueTypes(self): # Some File values are functions generating a string: check whether the value is a string or if it # is a function (but there is no way to check that the function's output is indeed a string) - if not isinstance(self.value, pyCompatibility.basestring) and not callable(self.value): + if not isinstance(self.value, str) and not callable(self.value): return self.name return "" @@ -231,7 +231,7 @@ class BoolParam(Param): def validateValue(self, value): try: - if isinstance(value, pyCompatibility.basestring): + if isinstance(value, str): # use distutils.util.strtobool to handle (1/0, true/false, on/off, y/n) return bool(distutils.util.strtobool(value)) return bool(value) @@ -311,10 +311,10 @@ class ChoiceParam(Param): if self.exclusive: return self.conformValue(value) - if isinstance(value, pyCompatibility.basestring): + if isinstance(value, str): value = value.split(',') - if not isinstance(value, pyCompatibility.Iterable): + if not isinstance(value, Iterable): raise ValueError('Non exclusive ChoiceParam value should be iterable (param:{}, value:{}, type:{})'.format(self.name, value, type(value))) return [self.conformValue(v) for v in value] @@ -334,12 +334,12 @@ class StringParam(Param): super(StringParam, self).__init__(name=name, label=label, description=description, value=value, uid=uid, group=group, advanced=advanced, semantic=semantic, enabled=enabled) def validateValue(self, value): - if not isinstance(value, pyCompatibility.basestring): + if not isinstance(value, str): raise ValueError('StringParam value should be a string (param:{}, value:{}, type:{})'.format(self.name, value, type(value))) return value def checkValueTypes(self): - if not isinstance(self.value, pyCompatibility.basestring): + if not isinstance(self.value, str): return self.name return "" diff --git a/meshroom/core/graph.py b/meshroom/core/graph.py index c444b454..8acd9295 100644 --- a/meshroom/core/graph.py +++ b/meshroom/core/graph.py @@ -13,7 +13,7 @@ from enum import Enum import meshroom import meshroom.core from meshroom.common import BaseObject, DictModel, Slot, Signal, Property -from meshroom.core import Version, pyCompatibility +from meshroom.core import Version from meshroom.core.attribute import Attribute, ListAttribute from meshroom.core.exception import StopGraphVisit, StopBranchVisit from meshroom.core.node import nodeFactory, Status, Node, CompatibilityNode @@ -195,7 +195,7 @@ class Graph(BaseObject): Returns: tuple of Graph.IO.Features: the list of supported features """ - if isinstance(fileVersion, pyCompatibility.basestring): + if isinstance(fileVersion, str): fileVersion = Version(fileVersion) features = [Graph.IO.Features.Graph] @@ -382,11 +382,11 @@ class Graph(BaseObject): """ for key, val in attributes.items(): for corr in nameCorrespondences.keys(): - if isinstance(val, pyCompatibility.basestring) and corr in val: + if isinstance(val, str) and corr in val: attributes[key] = val.replace(corr, nameCorrespondences[corr]) elif isinstance(val, list): for v in val: - if isinstance(v, pyCompatibility.basestring): + if isinstance(v, str): if corr in v: val[val.index(v)] = v.replace(corr, nameCorrespondences[corr]) else: # the list does not contain strings, so there cannot be links to update @@ -419,7 +419,7 @@ class Graph(BaseObject): defaultValue = desc.value break - if isinstance(val, pyCompatibility.basestring): + if isinstance(val, str): if Attribute.isLinkExpression(val) and not any(name in val for name in newNames): if defaultValue is not None: # prevents from not entering condition if defaultValue = '' attributes[key] = defaultValue @@ -428,8 +428,7 @@ class Graph(BaseObject): removedCnt = len(val) # counter to know whether all the list entries will be deemed invalid tmpVal = list(val) # deep copy to ensure we iterate over the entire list (even if elements are removed) for v in tmpVal: - if isinstance(v, pyCompatibility.basestring) and Attribute.isLinkExpression(v) and not any( - name in v for name in newNames): + if isinstance(v, str) and Attribute.isLinkExpression(v) and not any(name in v for name in newNames): val.remove(v) removedCnt -= 1 if removedCnt == 0 and defaultValue is not None: # if all links were wrong, reset the attribute diff --git a/meshroom/core/node.py b/meshroom/core/node.py index dd992e04..15a30a7d 100644 --- a/meshroom/core/node.py +++ b/meshroom/core/node.py @@ -17,7 +17,7 @@ from enum import Enum import meshroom from meshroom.common import Signal, Variant, Property, BaseObject, Slot, ListModel, DictModel -from meshroom.core import desc, stats, hashValue, pyCompatibility, nodeVersion, Version +from meshroom.core import desc, stats, hashValue, nodeVersion, Version from meshroom.core.attribute import attributeFactory, ListAttribute, GroupAttribute, Attribute from meshroom.core.exception import NodeUpgradeError, UnknownNodeTypeError @@ -1264,7 +1264,7 @@ class CompatibilityNode(BaseNode): return desc.IntParam(range=None, **params) elif isinstance(value, float): return desc.FloatParam(range=None, **params) - elif isinstance(value, pyCompatibility.basestring): + elif isinstance(value, str): if isOutput or os.path.isabs(value) or Attribute.isLinkExpression(value): return desc.File(**params) else: diff --git a/meshroom/core/pyCompatibility.py b/meshroom/core/pyCompatibility.py deleted file mode 100644 index 50e90271..00000000 --- a/meshroom/core/pyCompatibility.py +++ /dev/null @@ -1,22 +0,0 @@ - -try: - unicode = unicode -except NameError: - # 'unicode' is undefined, must be Python 3 - str = str - unicode = str - bytes = bytes - basestring = (str, bytes) -else: - # 'unicode' exists, must be Python 2 - str = str - unicode = unicode - bytes = str - basestring = basestring - -try: - # Import ABC from collections.abc in Python 3.4+ - from collections.abc import Sequence, Iterable -except ImportError: - # Import ABC from collections in Python 2 support - from collections import Sequence, Iterable diff --git a/meshroom/nodes/aliceVision/Texturing.py b/meshroom/nodes/aliceVision/Texturing.py index 83d46d90..d7eb6f7c 100644 --- a/meshroom/nodes/aliceVision/Texturing.py +++ b/meshroom/nodes/aliceVision/Texturing.py @@ -1,6 +1,6 @@ __version__ = "6.0" -from meshroom.core import desc, Version, pyCompatibility +from meshroom.core import desc, Version import logging @@ -355,7 +355,7 @@ Many cameras are contributing to the low frequencies and only the best ones cont def upgradeAttributeValues(self, attrValues, fromVersion): if fromVersion < Version(6, 0): outputTextureFileType = attrValues['outputTextureFileType'] - if isinstance(outputTextureFileType, pyCompatibility.basestring): + if isinstance(outputTextureFileType, str): attrValues['colorMapping'] = {} attrValues['colorMapping']['colorMappingFileType'] = outputTextureFileType return attrValues diff --git a/meshroom/ui/app.py b/meshroom/ui/app.py index dc436c18..36f7472c 100644 --- a/meshroom/ui/app.py +++ b/meshroom/ui/app.py @@ -9,7 +9,6 @@ from PySide2.QtWidgets import QApplication import meshroom from meshroom.core import nodesDesc -from meshroom.core import pyCompatibility from meshroom.core.taskManager import TaskManager from meshroom.ui import components @@ -225,7 +224,7 @@ class MeshroomApp(QApplication): @Slot(str) @Slot(QUrl) def addRecentProjectFile(self, projectFile): - if not isinstance(projectFile, (QUrl, pyCompatibility.basestring)): + if not isinstance(projectFile, (QUrl, str)): raise TypeError("Unexpected data type: {}".format(projectFile.__class__)) if isinstance(projectFile, QUrl): projectFileNorm = projectFile.toLocalFile() @@ -265,7 +264,7 @@ class MeshroomApp(QApplication): @Slot(str) @Slot(QUrl) def removeRecentProjectFile(self, projectFile): - if not isinstance(projectFile, (QUrl, pyCompatibility.basestring)): + if not isinstance(projectFile, (QUrl, str)): raise TypeError("Unexpected data type: {}".format(projectFile.__class__)) if isinstance(projectFile, QUrl): projectFileNorm = projectFile.toLocalFile() diff --git a/meshroom/ui/components/filepath.py b/meshroom/ui/components/filepath.py index 6c19e87f..233a67f5 100644 --- a/meshroom/ui/components/filepath.py +++ b/meshroom/ui/components/filepath.py @@ -1,7 +1,5 @@ #!/usr/bin/env python # coding:utf-8 -from meshroom.core import pyCompatibility - from PySide2.QtCore import QUrl, QFileInfo from PySide2.QtCore import QObject, Slot @@ -27,7 +25,7 @@ class FilepathHelper(QObject): Returns: str: String representation of 'path' """ - if not isinstance(path, (QUrl, pyCompatibility.basestring)): + if not isinstance(path, (QUrl, str)): raise TypeError("Unexpected data type: {}".format(path.__class__)) if isinstance(path, QUrl): path = path.toLocalFile() diff --git a/meshroom/ui/reconstruction.py b/meshroom/ui/reconstruction.py index 27d4ef94..56d1b5cc 100755 --- a/meshroom/ui/reconstruction.py +++ b/meshroom/ui/reconstruction.py @@ -2,6 +2,7 @@ import json import logging import math import os +from collections.abc import Iterable from threading import Thread from PySide2.QtCore import QObject, Slot, Property, Signal, QUrl, QSizeF @@ -13,7 +14,6 @@ from meshroom import multiview from meshroom.common.qt import QObjectListModel from meshroom.core import Version from meshroom.core.node import Node, CompatibilityNode, Status, Position -from meshroom.core.pyCompatibility import Iterable from meshroom.ui.graph import UIGraph from meshroom.ui.utils import makeProperty