Mon, 21 Sep 2015 19:13:30 +0200
Prepared eric for Python 3.5 to support the new 'async def' function definition.
--- a/Plugins/CheckerPlugins/CodeStyleChecker/DocStyleChecker.py Sat Sep 19 12:12:19 2015 +0200 +++ b/Plugins/CheckerPlugins/CodeStyleChecker/DocStyleChecker.py Mon Sep 21 19:13:30 2015 +0200 @@ -22,6 +22,11 @@ import ast import sys +try: + ast.AsyncFunctionDef # __IGNORE_EXCEPTION__ +except AttributeError: + ast.AsyncFunctionDef = ast.FunctionDef + class DocStyleContext(object): """ @@ -1071,7 +1076,8 @@ except (SyntaxError, TypeError): return if (isinstance(tree, ast.Module) and len(tree.body) == 1 and - isinstance(tree.body[0], ast.FunctionDef)): + isinstance(tree.body[0], + (ast.FunctionDef, ast.AsyncFunctionDef))): functionDef = tree.body[0] argNames, kwNames = self.__getArgNames(functionDef) if "self" in argNames:
--- a/Plugins/CheckerPlugins/CodeStyleChecker/NamingStyleChecker.py Sat Sep 19 12:12:19 2015 +0200 +++ b/Plugins/CheckerPlugins/CodeStyleChecker/NamingStyleChecker.py Mon Sep 21 19:13:30 2015 +0200 @@ -13,6 +13,11 @@ import os import sys +try: + ast.AsyncFunctionDef # __IGNORE_EXCEPTION__ +except AttributeError: + ast.AsyncFunctionDef = ast.FunctionDef + class NamingStyleChecker(object): """ @@ -110,7 +115,7 @@ """ if isinstance(node, ast.ClassDef): self.__tagClassFunctions(node) - elif isinstance(node, ast.FunctionDef): + elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): self.__findGlobalDefs(node) checkerName = node.__class__.__name__.lower() @@ -142,7 +147,7 @@ # iterate over all functions and tag them for node in ast.iter_child_nodes(classNode): - if not isinstance(node, ast.FunctionDef): + if not isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): continue node.function_type = 'method' @@ -171,7 +176,8 @@ if isinstance(node, ast.Global): globalNames.update(node.names) - if not isinstance(node, (ast.FunctionDef, ast.ClassDef)): + if not isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, + ast.ClassDef)): nodesToCheck.extend(ast.iter_child_nodes(node)) functionNode.global_names = globalNames @@ -222,7 +228,7 @@ if isinstance(node, ast.ClassDef): lineno += len(node.decorator_list) offset += 6 - elif isinstance(node, ast.FunctionDef): + elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): lineno += len(node.decorator_list) offset += 4 return (lineno, offset, code) @@ -245,13 +251,14 @@ @return tuple giving line number, offset within line and error code (integer, integer, string) """ - if isinstance(node, (ast.ClassDef, ast.FunctionDef)): + if isinstance(node, (ast.ClassDef, ast.FunctionDef, + ast.AsyncFunctionDef)): name = node.name if self.__isNameToBeAvoided(name): yield self.__error(node, "N831") return - if isinstance(node, ast.FunctionDef): + if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)): argNames = self.__getArgNames(node) for arg in argNames: if self.__isNameToBeAvoided(arg): @@ -376,7 +383,7 @@ for parentFunc in reversed(parents): if isinstance(parentFunc, ast.ClassDef): return - if isinstance(parentFunc, ast.FunctionDef): + if isinstance(parentFunc, (ast.FunctionDef, ast.AsyncFunctionDef)): break else: return
--- a/Plugins/CheckerPlugins/CodeStyleChecker/mccabe.py Sat Sep 19 12:12:19 2015 +0200 +++ b/Plugins/CheckerPlugins/CodeStyleChecker/mccabe.py Mon Sep 21 19:13:30 2015 +0200 @@ -127,6 +127,8 @@ self.graphs["%s%s" % (self.classname, node.name)] = self.graph self.reset() + visitAsyncFunctionDef = visitFunctionDef + def visitClassDef(self, node): old_classname = self.classname self.classname += node.name + "." @@ -158,7 +160,7 @@ name = "Loop %d" % node.lineno self._subgraph(node, name) - visitFor = visitWhile = visitLoop + visitFor = visitAsyncFor = visitWhile = visitLoop def visitIf(self, node): name = "If %d" % node.lineno @@ -209,3 +211,5 @@ name = "With %d" % node.lineno self.appendPathNode(name) self.dispatch_list(node.body) + + visitAsyncWith = visitWith
--- a/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py Sat Sep 19 12:12:19 2015 +0200 +++ b/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py Mon Sep 21 19:13:30 2015 +0200 @@ -637,8 +637,9 @@ pass # "stmt" type nodes - DELETE = PRINT = FOR = WHILE = IF = WITH = WITHITEM = RAISE = \ - TRYFINALLY = ASSERT = EXEC = EXPR = ASSIGN = handleChildren + DELETE = PRINT = FOR = ASYNCFOR = WHILE = IF = WITH = WITHITEM = \ + ASYNCWITH = RAISE = TRYFINALLY = ASSERT = EXEC = EXPR = \ + ASSIGN = handleChildren CONTINUE = BREAK = PASS = ignore @@ -722,6 +723,8 @@ if self.withDoctest: self.deferFunction(lambda: self.handleDoctests(node)) + ASYNCFUNCTIONDEF = FUNCTIONDEF + def LAMBDA(self, node): args = [] annotations = []
--- a/Utilities/ClassBrowsers/pyclbr.py Sat Sep 19 12:12:19 2015 +0200 +++ b/Utilities/ClassBrowsers/pyclbr.py Mon Sep 21 19:13:30 2015 +0200 @@ -28,7 +28,6 @@ SUPPORTED_TYPES = [ClassBrowsers.PY_SOURCE, ClassBrowsers.PTL_SOURCE] -# TODO: Add support for the new Python 3.5 async def _getnext = re.compile( r""" (?P<String> @@ -65,7 +64,7 @@ | (?P<Method> ^ (?P<MethodIndent> [ \t]* ) - def [ \t]+ + (?: async [ \t]+ )? def [ \t]+ (?P<MethodName> \w+ ) (?: [ \t]* \[ (?: plain | html ) \] )? [ \t]* \( @@ -103,7 +102,8 @@ | (?P<ConditionalDefine> ^ (?P<ConditionalDefineIndent> [ \t]* ) - (?: (?: if | elif ) [ \t]+ [^:]* | else [ \t]* ) : (?= \s* def) + (?: (?: if | elif ) [ \t]+ [^:]* | else [ \t]* ) : + (?= \s* (?: async [ \t]+ )? def) ) | (?P<Import>
--- a/Utilities/ModuleParser.py Sat Sep 19 12:12:19 2015 +0200 +++ b/Utilities/ModuleParser.py Mon Sep 21 19:13:30 2015 +0200 @@ -58,7 +58,6 @@ return -1 -# TODO: Add support for the new Python 3.5 async def _py_getnext = re.compile( r""" (?P<String> @@ -135,7 +134,7 @@ )? ^ (?P<MethodIndent> [ \t]* ) - def [ \t]+ + (?: async [ \t]+ )? def [ \t]+ (?P<MethodName> \w+ ) (?: [ \t]* \[ (?: plain | html ) \] )? [ \t]* \( @@ -194,7 +193,8 @@ | (?P<ConditionalDefine> ^ (?P<ConditionalDefineIndent> [ \t]* ) - (?: (?: if | elif ) [ \t]+ [^:]* | else [ \t]* ) : (?= \s* def) + (?: (?: if | elif ) [ \t]+ [^:]* | else [ \t]* ) : + (?= \s* (?: async [ \t]+ )? def) )""", re.VERBOSE | re.DOTALL | re.MULTILINE).search