--- a/eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py Fri Oct 04 14:26:47 2019 +0200 +++ b/eric6/Plugins/CheckerPlugins/CodeStyleChecker/MiscellaneousChecker.py Fri Oct 04 17:31:14 2019 +0200 @@ -15,6 +15,8 @@ from collections import defaultdict import tokenize +import AstUtilities + def composeCallPath(node): """ @@ -467,10 +469,13 @@ node.module == '__future__'): imports |= {name.name for name in node.names} elif isinstance(node, ast.Expr): - if not isinstance(node.value, ast.Str): + if not AstUtilities.isString(node.value): hasCode = True break - elif not isinstance(node, (ast.Module, ast.Str)): + elif not ( + AstUtilities.isString(node) or + isinstance(node, ast.Module) + ): hasCode = True break @@ -879,7 +884,7 @@ @return flag indicating to check the node @rtype bool """ - if not all(isinstance(key, ast.Str) for key in node.keys): + if not all(AstUtilities.isString(key) for key in node.keys): return False if ( @@ -1008,20 +1013,6 @@ node.is_docstring = False self.nodes.append(node) - def __isBaseString(self, node): - """ - Private method to determine, if a node is a base string node. - - @param node reference to the node to check - @type ast.AST - @return flag indicating a base string - @rtype bool - """ - typ = (ast.Str,) - if sys.version_info[0] > 2: - typ += (ast.Bytes,) - return isinstance(node, typ) - def visit_Str(self, node): """ Public method to record a string node. @@ -1039,6 +1030,21 @@ @type ast.Bytes """ self.__addNode(node) + + def visit_Constant(self, node): + """ + Public method to handle constant nodes. + + @param node reference to the bytes node + @type ast.Constant + """ + if sys.version_info >= (3, 8, 0): + if AstUtilities.isBaseString(node): + self.__addNode(node) + else: + super(TextVisitor, self).generic_visit(node) + else: + super(TextVisitor, self).generic_visit(node) def __visitDefinition(self, node): """ @@ -1065,8 +1071,11 @@ @param node reference to the node to traverse @type ast.AST """ - if (node.body and isinstance(node.body[0], ast.Expr) and - self.__isBaseString(node.body[0].value)): + if ( + node.body and + isinstance(node.body[0], ast.Expr) and + AstUtilities.isBaseString(node.body[0].value) + ): node.body[0].value.is_docstring = True for subnode in node.body: @@ -1118,13 +1127,18 @@ @param node reference to the node to handle @type ast.Call """ - if (isinstance(node.func, ast.Attribute) and - node.func.attr == 'format'): - if self.__isBaseString(node.func.value): + if ( + isinstance(node.func, ast.Attribute) and + node.func.attr == 'format' + ): + if AstUtilities.isBaseString(node.func.value): self.calls[node.func.value] = (node, False) - elif (isinstance(node.func.value, ast.Name) and - node.func.value.id == 'str' and node.args and - self.__isBaseString(node.args[0])): + elif ( + isinstance(node.func.value, ast.Name) and + node.func.value.id == 'str' and + node.args and + AstUtilities.isBaseString(node.args[0]) + ): self.calls[node.args[0]] = (node, True) super(TextVisitor, self).generic_visit(node) @@ -1406,13 +1420,13 @@ if ( node.func.id == "getattr" and len(node.args) == 2 and - isinstance(node.args[1], ast.Str) + AstUtilities.isString(node.args[1]) ): self.violations.append((node, "M512")) elif ( node.func.id == "setattr" and len(node.args) == 3 and - isinstance(node.args[1], ast.Str) + AstUtilities.isString(node.args[1]) ): self.violations.append((node, "M513")) except (AttributeError, IndexError): @@ -1487,8 +1501,8 @@ @type ast.Assert """ if ( - isinstance(node.test, ast.NameConstant) and - node.test.value is False + AstUtilities.isNameConstant(node.test) and + AstUtilities.getValue(node.test) is False ): self.violations.append((node, "M503")) @@ -1518,10 +1532,10 @@ if node.func.attr not in ("lstrip", "rstrip", "strip"): return # method name doesn't match - if len(node.args) != 1 or not isinstance(node.args[0], ast.Str): + if len(node.args) != 1 or not AstUtilities.isString(node.args[0]): return # used arguments don't match the builtin strip - s = node.args[0].s + s = AstUtilities.getValue(node.args[0]) if len(s) == 1: return # stripping just one character @@ -1764,10 +1778,12 @@ @type ast.AST @return flag indicating the node contains a None value """ - try: - return isinstance(node, ast.NameConstant) and node.value is None - except AttributeError: - # try Py2 + if sys.version_info[0] > 2: + return ( + AstUtilities.isNameConstant(node) and + AstUtilities.getValue(node) is None + ) + else: return isinstance(node, ast.Name) and node.id == "None" def __resultExists(self): @@ -1953,32 +1969,46 @@ if node.func.attr == 'datetime': # datetime.datetime(2000, 1, 1, 0, 0, 0, 0, # datetime.timezone.utc) - isCase1 = (len(node.args) >= 8 and - not (isinstance(node.args[7], ast.NameConstant) and - node.args[7].value is None)) + isCase1 = ( + len(node.args) >= 8 and + not ( + AstUtilities.isNameConstant(node.args[7]) and + AstUtilities.getValue(node.args[7]) is None + ) + ) # datetime.datetime(2000, 1, 1, tzinfo=datetime.timezone.utc) tzinfoKeyword = self.__getFromKeywords(node.keywords, 'tzinfo') - isCase2 = (tzinfoKeyword is not None and - not (isinstance(tzinfoKeyword.value, - ast.NameConstant) and - tzinfoKeyword.value.value is None)) + isCase2 = ( + tzinfoKeyword is not None and + not ( + AstUtilities.isNameConstant(tzinfoKeyword.value) and + AstUtilities.getValue(tzinfoKeyword.value) is None + ) + ) if not (isCase1 or isCase2): self.violations.append((node, "M301")) elif node.func.attr == 'time': # time(12, 10, 45, 0, datetime.timezone.utc) - isCase1 = (len(node.args) >= 5 and - not (isinstance(node.args[4], ast.NameConstant) and - node.args[4].value is None)) + isCase1 = ( + len(node.args) >= 5 and + not ( + AstUtilities.isNameConstant(node.args[4]) and + AstUtilities.getValue(node.args[4]) is None + ) + ) # datetime.time(12, 10, 45, tzinfo=datetime.timezone.utc) tzinfoKeyword = self.__getFromKeywords(node.keywords, 'tzinfo') - isCase2 = (tzinfoKeyword is not None and - not (isinstance(tzinfoKeyword.value, - ast.NameConstant) and - tzinfoKeyword.value.value is None)) + isCase2 = ( + tzinfoKeyword is not None and + not ( + AstUtilities.isNameConstant(tzinfoKeyword.value) and + AstUtilities.getValue(tzinfoKeyword.value) is None + ) + ) if not (isCase1 or isCase2): self.violations.append((node, "M321")) @@ -1998,34 +2028,48 @@ elif node.func.attr in 'now': # datetime.now(UTC) - isCase1 = (len(node.args) == 1 and - len(node.keywords) == 0 and - not (isinstance(node.args[0], ast.NameConstant) and - node.args[0].value is None)) + isCase1 = ( + len(node.args) == 1 and + len(node.keywords) == 0 and + not ( + AstUtilities.isNameConstant(node.args[0]) and + AstUtilities.getValue(node.args[0]) is None + ) + ) # datetime.now(tz=UTC) tzKeyword = self.__getFromKeywords(node.keywords, 'tz') - isCase2 = (tzKeyword is not None and - not (isinstance(tzKeyword.value, - ast.NameConstant) and - tzKeyword.value.value is None)) + isCase2 = ( + tzKeyword is not None and + not ( + AstUtilities.isNameConstant(tzKeyword.value) and + AstUtilities.getValue(tzKeyword.value) is None + ) + ) if not (isCase1 or isCase2): self.violations.append((node, "M305")) elif node.func.attr == 'fromtimestamp': # datetime.fromtimestamp(1234, UTC) - isCase1 = (len(node.args) == 2 and - len(node.keywords) == 0 and - not (isinstance(node.args[1], ast.NameConstant) and - node.args[1].value is None)) + isCase1 = ( + len(node.args) == 2 and + len(node.keywords) == 0 and + not ( + AstUtilities.isNameConstant(node.args[1]) and + AstUtilities.getValue(node.args[1]) is None + ) + ) # datetime.fromtimestamp(1234, tz=UTC) tzKeyword = self.__getFromKeywords(node.keywords, 'tz') - isCase2 = (tzKeyword is not None and - not (isinstance(tzKeyword.value, - ast.NameConstant) and - tzKeyword.value.value is None)) + isCase2 = ( + tzKeyword is not None and + not ( + AstUtilities.isNameConstant(tzKeyword.value) and + AstUtilities.getValue(tzKeyword.value) is None + ) + ) if not (isCase1 or isCase2): self.violations.append((node, "M306")) @@ -2042,10 +2086,14 @@ else: tzinfoKeyword = self.__getFromKeywords(pparent.keywords, 'tzinfo') - isCase1 = (tzinfoKeyword is not None and - not (isinstance(tzinfoKeyword.value, - ast.NameConstant) and - tzinfoKeyword.value.value is None)) + isCase1 = ( + tzinfoKeyword is not None and + not ( + AstUtilities.isNameConstant( + tzinfoKeyword.value) and + AstUtilities.getValue(tzinfoKeyword.value) is None + ) + ) if not isCase1: self.violations.append((node, "M307")) @@ -2153,8 +2201,8 @@ self.__isSys("version", node.value) and isinstance(node.slice, ast.Slice) and node.slice.lower is None and - isinstance(node.slice.upper, ast.Num) and - node.slice.upper.n == n and + AstUtilities.isNumber(node.slice.upper) and + AstUtilities.getValue(node.slice.upper) == n and node.slice.step is None ) @@ -2172,15 +2220,15 @@ elif ( self.__isSys('version', node.value) and isinstance(node.slice, ast.Index) and - isinstance(node.slice.value, ast.Num) and - node.slice.value.n == 2 + AstUtilities.isNumber(node.slice.value) and + AstUtilities.getValue(node.slice.value) == 2 ): self.violations.append((node.value, "M402")) elif ( self.__isSys('version', node.value) and isinstance(node.slice, ast.Index) and - isinstance(node.slice.value, ast.Num) and - node.slice.value.n == 0 + AstUtilities.isNumber(node.slice.value) and + AstUtilities.getValue(node.slice.value) == 0 ): self.violations.append((node.value, "M421")) @@ -2197,21 +2245,21 @@ isinstance(node.left, ast.Subscript) and self.__isSys('version_info', node.left.value) and isinstance(node.left.slice, ast.Index) and - isinstance(node.left.slice.value, ast.Num) and - node.left.slice.value.n == 0 and + AstUtilities.isNumber(node.left.slice.value) and + AstUtilities.getValue(node.left.slice.value) == 0 and len(node.ops) == 1 and isinstance(node.ops[0], ast.Eq) and - isinstance(node.comparators[0], ast.Num) and - node.comparators[0].n == 3 + AstUtilities.isNumber(node.comparators[0]) and + AstUtilities.getValue(node.comparators[0]) == 3 ): self.violations.append((node.left, "M411")) elif ( self.__isSys('version', node.left) and len(node.ops) == 1 and isinstance(node.ops[0], (ast.Lt, ast.LtE, ast.Gt, ast.GtE)) and - isinstance(node.comparators[0], ast.Str) + AstUtilities.isString(node.comparators[0]) ): - if len(node.comparators[0].s) == 1: + if len(AstUtilities.getValue(node.comparators[0])) == 1: errorCode = "M422" else: errorCode = "M403" @@ -2220,11 +2268,11 @@ isinstance(node.left, ast.Subscript) and self.__isSys('version_info', node.left.value) and isinstance(node.left.slice, ast.Index) and - isinstance(node.left.slice.value, ast.Num) and - node.left.slice.value.n == 1 and + AstUtilities.isNumber(node.left.slice.value) and + AstUtilities.getValue(node.left.slice.value) == 1 and len(node.ops) == 1 and isinstance(node.ops[0], (ast.Lt, ast.LtE, ast.Gt, ast.GtE)) and - isinstance(node.comparators[0], ast.Num) + AstUtilities.isNumber(node.comparators[0]) ): self.violations.append((node, "M413")) elif ( @@ -2233,7 +2281,7 @@ node.left.attr == 'minor' and len(node.ops) == 1 and isinstance(node.ops[0], (ast.Lt, ast.LtE, ast.Gt, ast.GtE)) and - isinstance(node.comparators[0], ast.Num) + AstUtilities.isNumber(node.comparators[0]) ): self.violations.append((node, "M414"))