Merged with changes of Tobias.

Sat, 11 Feb 2017 18:19:56 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 11 Feb 2017 18:19:56 +0100
changeset 5511
54632671aa3b
parent 5508
30626def80dc (current diff)
parent 5510
cdcd0cd34e79 (diff)
child 5512
f148796813d4

Merged with changes of Tobias.

--- a/Plugins/CheckerPlugins/CodeStyleChecker/pycodestyle.py	Sat Feb 11 17:50:07 2017 +0100
+++ b/Plugins/CheckerPlugins/CodeStyleChecker/pycodestyle.py	Sat Feb 11 18:19:56 2017 +0100
@@ -79,7 +79,7 @@
 except ImportError:
     from ConfigParser import RawConfigParser            # __IGNORE_WARNING__
 
-__version__ = '2.2.0-eric'
+__version__ = '2.3.1-eric'
 
 DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox'
 DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503'
@@ -134,6 +134,20 @@
 OPERATOR_REGEX = re.compile(r'(?:[^,\s])(\s*)(?:[-+*/|!<=>%&^]+)(\s*)')
 LAMBDA_REGEX = re.compile(r'\blambda\b')
 HUNK_REGEX = re.compile(r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$')
+STARTSWITH_DEF_REGEX = re.compile(r'^(async\s+def|def)')
+STARTSWITH_TOP_LEVEL_REGEX = re.compile(r'^(async\s+def\s+|def\s+|class\s+|@)')
+STARTSWITH_INDENT_STATEMENT_REGEX = re.compile(
+    r'^\s*({0})'.format('|'.join(s.replace(' ', '\s+') for s in (
+        'def', 'async def',
+        'for', 'async for',
+        'if', 'elif', 'else',
+        'try', 'except', 'finally',
+        'with', 'async with',
+        'class',
+        'while',
+    )))
+)
+DUNDER_REGEX = re.compile(r'^__([^\s]+)__ = ')
 
 # Work around Python < 2.6 behaviour, which does not generate NL after
 # a comment which is on a line by itself.
@@ -278,6 +292,7 @@
     E303: def a():\n\n\n\n    pass
     E304: @decorator\n\ndef a():\n    pass
     E305: def a():\n    pass\na()
+    E306: def a():\n    def b():\n        pass\n    def c():\n        pass
     """
     if line_number < 3 and not previous_logical:
         return  # Don't expect blank lines before the first line
@@ -286,7 +301,7 @@
             yield 0, "E304 blank lines found after function decorator"
     elif blank_lines > 2 or (indent_level and blank_lines == 2):
         yield 0, "E303 too many blank lines (%d)", blank_lines
-    elif logical_line.startswith(('def ', 'async def ', 'class ', '@')):
+    elif STARTSWITH_TOP_LEVEL_REGEX.match(logical_line):
         if indent_level:
             if not (blank_before or previous_indent_level < indent_level or
                     DOCSTRING_REGEX.match(previous_logical)):
@@ -827,7 +842,7 @@
     no_space = False
     prev_end = None
     annotated_func_arg = False
-    in_def = logical_line.startswith(('def', 'async def'))
+    in_def = bool(STARTSWITH_DEF_REGEX.match(logical_line))
     message = "E251 unexpected spaces around keyword / parameter equals"
     for token_type, text, start, end, line in tokens:
         if token_type == tokenize.NL:
@@ -956,6 +971,8 @@
     if line.startswith('import ') or line.startswith('from '):
         if checker_state.get('seen_non_imports', False):
             yield 0, "E402 module level import not at top of file"
+    elif re.match(DUNDER_REGEX, line):
+        return
     elif any(line.startswith(kw) for kw in allowed_try_keywords):
         # Allow try, except, else, finally keywords intermixed with imports in
         # order to support conditional importing
@@ -996,7 +1013,6 @@
     E702: do_one(); do_two(); do_three()
     E703: do_four();  # useless semicolon
     E704: def f(x): return 2*x
-    E705: async def f(x): return 2*x
     E731: f = lambda x: 2*x
     """
     line = logical_line
@@ -1016,11 +1032,9 @@
                     yield 0, ("E731 do not assign a lambda expression, use a "
                               "def")
                 break
-            if line.startswith('def '):
+            if STARTSWITH_DEF_REGEX.match(line):
                 yield 0, "E704 multiple statements on one line (def)"
-            elif line.startswith('async def '):
-                yield 0, "E705 multiple statements on one line (async def)"
-            else:
+            elif STARTSWITH_INDENT_STATEMENT_REGEX.match(line):
                 yield found, "E701 multiple statements on one line (colon)"
         prev_found = found
         found = line.find(':', found + 1)
--- a/Plugins/CheckerPlugins/CodeStyleChecker/translations.py	Sat Feb 11 17:50:07 2017 +0100
+++ b/Plugins/CheckerPlugins/CodeStyleChecker/translations.py	Sat Feb 11 18:19:56 2017 +0100
@@ -219,9 +219,6 @@
     "E704": QCoreApplication.translate(
         "pycodestyle",
         "multiple statements on one line (def)"),
-    "E705": QCoreApplication.translate(
-        "pycodestyle",
-        "multiple statements on one line (async def)"),
     "E711": QCoreApplication.translate(
         "pycodestyle",
         "comparison to {0} should be {1}"),
--- a/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/__init__.py	Sat Feb 11 17:50:07 2017 +0100
+++ b/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/__init__.py	Sat Feb 11 18:19:56 2017 +0100
@@ -32,6 +32,19 @@
 """
 
 """ Changes
+1.5.0 (2017-01-09)
+  - Enable support for PEP 526 annotated assignments
+
+1.4.0 (2016-12-30):
+  - Change formatting of ImportStarMessage to be consistent with other errors
+  - Support PEP 498 "f-strings"
+
+1.3.0 (2016-09-01):
+  - Fix PyPy2 Windows IntegrationTests
+  - Check for duplicate dictionary keys
+  - Fix TestMain tests on Windows
+  - Fix "continue" and "break" checks ignoring py3.5's "async for" loop
+
 1.2.3 (2016-05-12):
   - Fix TypeError when processing relative imports
 
--- a/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py	Sat Feb 11 17:50:07 2017 +0100
+++ b/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/checker.py	Sat Feb 11 18:19:56 2017 +0100
@@ -311,7 +311,7 @@
 
 
 class StarImportation(Importation):
-    """A binding created by an 'from x import *' statement."""
+    """A binding created by a 'from x import *' statement."""
 
     def __init__(self, name, source):
         super(StarImportation, self).__init__('*', source)
@@ -806,7 +806,7 @@
             return
 
         if on_conditional_branch():
-            # We can not predict if this conditional branch is going to
+            # We cannot predict if this conditional branch is going to
             # be executed.
             return
 
@@ -944,7 +944,7 @@
         MATMULT = ignore
 
     # additional node types
-    COMPREHENSION = KEYWORD = FORMATTEDVALUE = handleChildren
+    COMPREHENSION = KEYWORD = FORMATTEDVALUE = JOINEDSTR = handleChildren
 
     def DICT(self, node):
         # Complain if there are duplicate keys with different values
@@ -1328,7 +1328,7 @@
         self.handleNodeStore(node)
         self.handleChildren(node)
         if not is_name_previously_defined:
-            # See discussion on https://github.com/pyflakes/pyflakes/pull/59.
+            # See discussion on https://github.com/PyCQA/pyflakes/pull/59
 
             # We're removing the local name since it's being unbound
             # after leaving the except: block and it's always unbound
@@ -1343,5 +1343,24 @@
             except KeyError:
                 pass
 
+    def ANNASSIGN(self, node):
+        """
+        Annotated assignments don't have annotations evaluated on function
+        scope, hence the custom implementation.
+
+        See: PEP 526.
+        """
+        if node.value:
+            # Only bind the *targets* if the assignment has a value.
+            # Otherwise it's not really ast.Store and shouldn't silence
+            # UndefinedLocal warnings.
+            self.handleNode(node.target, node)
+        if not isinstance(self.scope, FunctionScope):
+            self.handleNode(node.annotation, node)
+        if node.value:
+            # If the assignment has value, handle the *value* now.
+            self.handleNode(node.value, node)
+
+
 #
 # eflag: noqa = M702
--- a/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/messages.py	Sat Feb 11 17:50:07 2017 +0100
+++ b/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/messages.py	Sat Feb 11 18:19:56 2017 +0100
@@ -173,7 +173,7 @@
     Class defining the "Import Star Usage" message.
     """
     message_id = 'F17'
-    message = "%s may be undefined, or defined from star imports: %s"
+    message = "%r may be undefined, or defined from star imports: %s"
 
     def __init__(self, filename, loc, name, from_list):
         """
--- a/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/translations.py	Sat Feb 11 17:50:07 2017 +0100
+++ b/Plugins/CheckerPlugins/SyntaxChecker/pyflakes/translations.py	Sat Feb 11 18:19:56 2017 +0100
@@ -65,7 +65,7 @@
         "'from {0} import *' only allowed at module level"),
     'F17': QCoreApplication.translate(
         'pyFlakes',
-        "{0} may be undefined, or defined from star imports: {1}"),
+        "{0!r} may be undefined, or defined from star imports: {1}"),
     'F18': QCoreApplication.translate(
         'pyFlakes',
         "Dictionary key {0!r} repeated with different values"),
--- a/changelog	Sat Feb 11 17:50:07 2017 +0100
+++ b/changelog	Sat Feb 11 18:19:56 2017 +0100
@@ -1,5 +1,11 @@
 Change Log
 ----------
+Version 17.xx:
+- bug fixes
+- Checkers
+  -- upgraded pycodestyle to version 2.3.1
+  -- upgraded pyflakes to version 1.5.0
+  
 Version 17.02.1:
 - bug fixes
 

eric ide

mercurial