Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-pyflakes for openSUSE:Factory 
checked in at 2022-12-16 17:51:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pyflakes (Old)
 and      /work/SRC/openSUSE:Factory/.python-pyflakes.new.1835 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pyflakes"

Fri Dec 16 17:51:42 2022 rev:34 rq:1043220 version:3.0.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pyflakes/python-pyflakes.changes  
2022-12-15 20:16:31.177315362 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-pyflakes.new.1835/python-pyflakes.changes    
    2022-12-16 17:51:50.036077840 +0100
@@ -1,0 +2,9 @@
+Thu Dec 15 20:50:51 UTC 2022 - Dirk Müller <dmuel...@suse.com>
+
+- update to 3.0.1 (bsc#1206225):
+  * Detect undefined name in variable defined by an annotated assignment
+  * Add a new error for names which are annotated but unused
+  * Remove handling of python 2.x ``# type:`` comments.  Use annotations
+    instead
+
+-------------------------------------------------------------------

Old:
----
  pyflakes-2.5.0.tar.gz

New:
----
  pyflakes-3.0.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pyflakes.spec ++++++
--- /var/tmp/diff_new_pack.hQkdwI/_old  2022-12-16 17:51:51.124083829 +0100
+++ /var/tmp/diff_new_pack.hQkdwI/_new  2022-12-16 17:51:51.128083851 +0100
@@ -18,13 +18,14 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-pyflakes
-Version:        2.5.0
+Version:        3.0.1
 Release:        0
 Summary:        Passive checker of Python programs
 License:        MIT
 Group:          Development/Languages/Python
 URL:            https://github.com/PyCQA/pyflakes
 Source:         
https://files.pythonhosted.org/packages/source/p/pyflakes/pyflakes-%{version}.tar.gz
+BuildRequires:  %{python_module base >= 3.8}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros

++++++ pyflakes-2.5.0.tar.gz -> pyflakes-3.0.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/NEWS.rst new/pyflakes-3.0.1/NEWS.rst
--- old/pyflakes-2.5.0/NEWS.rst 2022-07-30 19:27:25.000000000 +0200
+++ new/pyflakes-3.0.1/NEWS.rst 2022-11-24 17:52:19.000000000 +0100
@@ -1,3 +1,13 @@
+3.0.1 (2022-11-24)
+
+- Fix crash on augmented assign to ``print`` builtin
+
+3.0.0 (2022-11-23)
+
+- Detect undefined name in variable defined by an annotated assignment
+- Add a new error for names which are annotated but unused
+- Remove handling of python 2.x ``# type:`` comments.  Use annotations instead
+
 2.5.0 (2022-07-30)
 
 - Drop support for EOL python 2.7 / 3.4 / 3.5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/PKG-INFO new/pyflakes-3.0.1/PKG-INFO
--- old/pyflakes-2.5.0/PKG-INFO 2022-07-30 19:28:49.971378000 +0200
+++ new/pyflakes-3.0.1/PKG-INFO 2022-11-24 17:53:21.689930700 +0100
@@ -1,12 +1,11 @@
 Metadata-Version: 2.1
 Name: pyflakes
-Version: 2.5.0
+Version: 3.0.1
 Summary: passive checker of Python programs
 Home-page: https://github.com/PyCQA/pyflakes
 Author: A lot of people
 Author-email: code-qual...@python.org
 License: MIT
-Platform: UNKNOWN
 Classifier: Development Status :: 6 - Mature
 Classifier: Environment :: Console
 Classifier: Intended Audience :: Developers
@@ -52,11 +51,11 @@
 Useful tips:
 
 * Be sure to install it for a version of Python which is compatible
-  with your codebase: for Python 2, ``pip2 install pyflakes`` and for
-  Python3, ``pip3 install pyflakes``.
+  with your codebase: ``python#.# -m pip install pyflakes`` (for example,
+  ``python3.10 -m pip install pyflakes``)
 
-* You can also invoke Pyflakes with ``python3 -m pyflakes .`` or
-  ``python2 -m pyflakes .`` if you have it installed for both versions.
+* You can also invoke Pyflakes with ``python#.# -m pyflakes .`` if you want
+  to run it for a specific python version.
 
 * If you require more options and more flexibility, you could give a
   look to Flake8_ too.
@@ -92,7 +91,7 @@
 
 Patches may be submitted via a `GitHub pull request`_ or via the mailing list
 if you prefer. If you are comfortable doing so, please `rebase your changes`_
-so they may be applied to master with a fast-forward merge, and each commit is
+so they may be applied to main with a fast-forward merge, and each commit is
 a coherent unit of work with a well-written log message.  If you are not
 comfortable with this rebase workflow, the project maintainers will be happy to
 rebase your commits for you.
@@ -112,6 +111,4 @@
 Changelog
 ---------
 
-Please see `NEWS.rst 
<https://github.com/PyCQA/pyflakes/blob/master/NEWS.rst>`_.
-
-
+Please see `NEWS.rst <https://github.com/PyCQA/pyflakes/blob/main/NEWS.rst>`_.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/README.rst 
new/pyflakes-3.0.1/README.rst
--- old/pyflakes-2.5.0/README.rst       2022-07-30 19:03:28.000000000 +0200
+++ new/pyflakes-3.0.1/README.rst       2022-11-24 17:02:51.000000000 +0100
@@ -24,11 +24,11 @@
 Useful tips:
 
 * Be sure to install it for a version of Python which is compatible
-  with your codebase: for Python 2, ``pip2 install pyflakes`` and for
-  Python3, ``pip3 install pyflakes``.
+  with your codebase: ``python#.# -m pip install pyflakes`` (for example,
+  ``python3.10 -m pip install pyflakes``)
 
-* You can also invoke Pyflakes with ``python3 -m pyflakes .`` or
-  ``python2 -m pyflakes .`` if you have it installed for both versions.
+* You can also invoke Pyflakes with ``python#.# -m pyflakes .`` if you want
+  to run it for a specific python version.
 
 * If you require more options and more flexibility, you could give a
   look to Flake8_ too.
@@ -64,7 +64,7 @@
 
 Patches may be submitted via a `GitHub pull request`_ or via the mailing list
 if you prefer. If you are comfortable doing so, please `rebase your changes`_
-so they may be applied to master with a fast-forward merge, and each commit is
+so they may be applied to main with a fast-forward merge, and each commit is
 a coherent unit of work with a well-written log message.  If you are not
 comfortable with this rebase workflow, the project maintainers will be happy to
 rebase your commits for you.
@@ -84,4 +84,4 @@
 Changelog
 ---------
 
-Please see `NEWS.rst 
<https://github.com/PyCQA/pyflakes/blob/master/NEWS.rst>`_.
+Please see `NEWS.rst <https://github.com/PyCQA/pyflakes/blob/main/NEWS.rst>`_.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/pyflakes/__init__.py 
new/pyflakes-3.0.1/pyflakes/__init__.py
--- old/pyflakes-2.5.0/pyflakes/__init__.py     2022-07-30 19:27:25.000000000 
+0200
+++ new/pyflakes-3.0.1/pyflakes/__init__.py     2022-11-24 17:52:30.000000000 
+0100
@@ -1 +1 @@
-__version__ = '2.5.0'
+__version__ = '3.0.1'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/pyflakes/api.py 
new/pyflakes-3.0.1/pyflakes/api.py
--- old/pyflakes-2.5.0/pyflakes/api.py  2022-07-30 19:03:28.000000000 +0200
+++ new/pyflakes-3.0.1/pyflakes/api.py  2022-11-24 17:02:51.000000000 +0100
@@ -44,8 +44,7 @@
         reporter.unexpectedError(filename, 'problem decoding source')
         return 1
     # Okay, it's syntactically valid.  Now check it.
-    file_tokens = checker.make_tokens(codeString)
-    w = checker.Checker(tree, file_tokens=file_tokens, filename=filename)
+    w = checker.Checker(tree, filename=filename)
     w.messages.sort(key=lambda m: m.lineno)
     for warning in w.messages:
         reporter.flake(warning)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/pyflakes/checker.py 
new/pyflakes-3.0.1/pyflakes/checker.py
--- old/pyflakes-2.5.0/pyflakes/checker.py      2022-07-30 19:03:28.000000000 
+0200
+++ new/pyflakes-3.0.1/pyflakes/checker.py      2022-11-24 17:51:58.000000000 
+0100
@@ -7,8 +7,6 @@
 import __future__
 import builtins
 import ast
-import bisect
-import collections
 import contextlib
 import doctest
 import functools
@@ -16,7 +14,7 @@
 import re
 import string
 import sys
-import tokenize
+import warnings
 
 from pyflakes import messages
 
@@ -78,16 +76,6 @@
     )
 
 
-# 
https://github.com/python/typed_ast/blob/1.4.0/ast27/Parser/tokenizer.c#L102-L104
-TYPE_COMMENT_RE = re.compile(r'^#\s*type:\s*')
-# 
https://github.com/python/typed_ast/blob/1.4.0/ast27/Parser/tokenizer.c#L1408-L1413
-ASCII_NON_ALNUM = ''.join([chr(i) for i in range(128) if not chr(i).isalnum()])
-TYPE_IGNORE_RE = re.compile(
-    TYPE_COMMENT_RE.pattern + fr'ignore([{ASCII_NON_ALNUM}]|$)')
-# https://github.com/python/typed_ast/blob/1.4.0/ast27/Grammar/Grammar#L147
-TYPE_FUNC_RE = re.compile(r'^(\(.*?\))\s*->\s*(.*)$')
-
-
 MAPPING_KEY_RE = re.compile(r'\(([^()]*)\)')
 CONVERSION_FLAG_RE = re.compile('[#0+ -]*')
 WIDTH_RE = re.compile(r'(?:\*|\d*)')
@@ -586,9 +574,8 @@
         # Simplify: manage the special locals as globals
         self.globals = self.alwaysUsed.copy()
         self.returnValue = None     # First non-empty return
-        self.isGenerator = False    # Detect a generator
 
-    def unusedAssignments(self):
+    def unused_assignments(self):
         """
         Return a generator for the assignments which have not been used.
         """
@@ -600,6 +587,14 @@
                     isinstance(binding, Assignment)):
                 yield name, binding
 
+    def unused_annotations(self):
+        """
+        Return a generator for the annotations which have not been used.
+        """
+        for name, binding in self.items():
+            if not binding.used and isinstance(binding, Annotation):
+                yield name, binding
+
 
 class GeneratorScope(Scope):
     pass
@@ -615,13 +610,6 @@
     """Scope for a doctest."""
 
 
-class DummyNode:
-    """Used in place of an `ast.AST` to set error message positions"""
-    def __init__(self, lineno, col_offset):
-        self.lineno = lineno
-        self.col_offset = col_offset
-
-
 class DetectClassScopedMagic:
     names = dir()
 
@@ -741,63 +729,6 @@
     return in_annotation_func
 
 
-def make_tokens(code):
-    # PY3: tokenize.tokenize requires readline of bytes
-    if not isinstance(code, bytes):
-        code = code.encode('UTF-8')
-    lines = iter(code.splitlines(True))
-    # next(lines, b'') is to prevent an error in pypy3
-    return tuple(tokenize.tokenize(lambda: next(lines, b'')))
-
-
-class _TypeableVisitor(ast.NodeVisitor):
-    """Collect the line number and nodes which are deemed typeable by
-    PEP 484
-
-    https://www.python.org/dev/peps/pep-0484/#type-comments
-    """
-    def __init__(self):
-        self.typeable_lines = []
-        self.typeable_nodes = {}
-
-    def _typeable(self, node):
-        # if there is more than one typeable thing on a line last one wins
-        self.typeable_lines.append(node.lineno)
-        self.typeable_nodes[node.lineno] = node
-
-        self.generic_visit(node)
-
-    visit_Assign = visit_For = visit_FunctionDef = visit_With = _typeable
-    visit_AsyncFor = visit_AsyncFunctionDef = visit_AsyncWith = _typeable
-
-
-def _collect_type_comments(tree, tokens):
-    visitor = _TypeableVisitor()
-    visitor.visit(tree)
-
-    type_comments = collections.defaultdict(list)
-    for tp, text, start, _, _ in tokens:
-        if (
-                tp != tokenize.COMMENT or  # skip non comments
-                not TYPE_COMMENT_RE.match(text) or  # skip non-type comments
-                TYPE_IGNORE_RE.match(text)  # skip ignores
-        ):
-            continue
-
-        # search for the typeable node at or before the line number of the
-        # type comment.
-        # if the bisection insertion point is before any nodes this is an
-        # invalid type comment which is ignored.
-        lineno, _ = start
-        idx = bisect.bisect_right(visitor.typeable_lines, lineno)
-        if idx == 0:
-            continue
-        node = visitor.typeable_nodes[visitor.typeable_lines[idx - 1]]
-        type_comments[node].append((start, text))
-
-    return type_comments
-
-
 class Checker:
     """
     I check the cleanliness and sanity of Python code.
@@ -834,9 +765,6 @@
         builtIns.update(_customBuiltIns.split(','))
     del _customBuiltIns
 
-    # TODO: file_tokens= is required to perform checks on type comments,
-    #       eventually make this a required positional argument.  For now it
-    #       is defaulted to `()` for api compatibility.
     def __init__(self, tree, filename='(none)', builtins=None,
                  withDoctest='PYFLAKES_DOCTEST' in os.environ, file_tokens=()):
         self._nodeHandlers = {}
@@ -854,7 +782,6 @@
             raise RuntimeError('No scope implemented for the node %r' % tree)
         self.exceptHandlers = [()]
         self.root = tree
-        self._type_comments = _collect_type_comments(tree, file_tokens)
         for builtin in self.builtIns:
             self.addBinding(None, Builtin(builtin))
         self.handleChildren(tree)
@@ -871,6 +798,12 @@
         self.popScope()
         self.checkDeadScopes()
 
+        if file_tokens:
+            warnings.warn(
+                '`file_tokens` will be removed in a future version',
+                stacklevel=2,
+            )
+
     def deferFunction(self, callable):
         """
         Schedule a function handler to be called just before completion.
@@ -1135,7 +1068,7 @@
         )
         return handler
 
-    def handleNodeLoad(self, node):
+    def handleNodeLoad(self, node, parent):
         name = getNodeName(node)
         if not name:
             return
@@ -1156,10 +1089,10 @@
 
             binding = scope.get(name, None)
             if isinstance(binding, Annotation) and not 
self._in_postponed_annotation:
+                scope[name].used = True
                 continue
 
             if name == 'print' and isinstance(binding, Builtin):
-                parent = self.getParent(node)
                 if (isinstance(parent, ast.BinOp) and
                         isinstance(parent.op, ast.RShift)):
                     self.report(messages.InvalidPrintSyntax, node)
@@ -1299,27 +1232,7 @@
             self.annotationsFutureEnabled
         )
 
-    def _handle_type_comments(self, node):
-        for (lineno, col_offset), comment in self._type_comments.get(node, ()):
-            comment = comment.split(':', 1)[1].strip()
-            func_match = TYPE_FUNC_RE.match(comment)
-            if func_match:
-                parts = (
-                    func_match.group(1).replace('*', ''),
-                    func_match.group(2).strip(),
-                )
-            else:
-                parts = (comment,)
-
-            for part in parts:
-                self.deferFunction(functools.partial(
-                    self.handleStringAnnotation,
-                    part, DummyNode(lineno, col_offset), lineno, col_offset,
-                    messages.CommentAnnotationSyntaxError,
-                ))
-
     def handleChildren(self, tree, omit=None):
-        self._handle_type_comments(tree)
         for node in iter_child_nodes(tree, omit=omit):
             self.handleNode(node, tree)
 
@@ -1966,7 +1879,7 @@
         """
         # Locate the name in locals / function / globals scopes.
         if isinstance(node.ctx, ast.Load):
-            self.handleNodeLoad(node)
+            self.handleNodeLoad(node, self.getParent(node))
             if (node.id == 'locals' and isinstance(self.scope, FunctionScope) 
and
                     isinstance(node._pyflakes_parent, ast.Call)):
                 # we are doing locals() call in current scope
@@ -2022,7 +1935,6 @@
             self.report(messages.YieldOutsideFunction, node)
             return
 
-        self.scope.isGenerator = True
         self.handleNode(node.value, node)
 
     AWAIT = YIELDFROM = YIELD
@@ -2084,13 +1996,22 @@
 
             self.handleChildren(node, omit=['decorator_list', 'returns'])
 
-            def checkUnusedAssignments():
+            def check_unused_assignments():
                 """
                 Check to see if any assignments have not been used.
                 """
-                for name, binding in self.scope.unusedAssignments():
+                for name, binding in self.scope.unused_assignments():
                     self.report(messages.UnusedVariable, binding.source, name)
-            self.deferAssignment(checkUnusedAssignments)
+
+            def check_unused_annotations():
+                """
+                Check to see if any annotations have not been used.
+                """
+                for name, binding in self.scope.unused_annotations():
+                    self.report(messages.UnusedAnnotation, binding.source, 
name)
+
+            self.deferAssignment(check_unused_assignments)
+            self.deferAssignment(check_unused_annotations)
 
             self.popScope()
 
@@ -2127,7 +2048,7 @@
         self.addBinding(node, ClassDefinition(node.name, node))
 
     def AUGASSIGN(self, node):
-        self.handleNodeLoad(node.target)
+        self.handleNodeLoad(node.target, node)
         self.handleNode(node.value, node)
         self.handleNode(node.target, node)
 
@@ -2265,7 +2186,6 @@
             self.scope[node.name] = prev_definition
 
     def ANNASSIGN(self, node):
-        self.handleNode(node.target, node)
         self.handleAnnotation(node.annotation, node)
         # If the assignment has value, handle the *value* now.
         if node.value:
@@ -2274,6 +2194,7 @@
                 self.handleAnnotation(node.value, node)
             else:
                 self.handleNode(node.value, node)
+        self.handleNode(node.target, node)
 
     def COMPARE(self, node):
         left = node.left
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/pyflakes/messages.py 
new/pyflakes-3.0.1/pyflakes/messages.py
--- old/pyflakes-2.5.0/pyflakes/messages.py     2022-07-30 19:03:28.000000000 
+0200
+++ new/pyflakes-3.0.1/pyflakes/messages.py     2022-11-24 17:02:51.000000000 
+0100
@@ -134,10 +134,6 @@
 class LateFutureImport(Message):
     message = 'from __future__ imports must occur at the beginning of the file'
 
-    def __init__(self, filename, loc):
-        Message.__init__(self, filename, loc)
-        self.message_args = ()
-
 
 class FutureFeatureNotDefined(Message):
     """An undefined __future__ feature name was imported."""
@@ -160,6 +156,18 @@
         self.message_args = (names,)
 
 
+class UnusedAnnotation(Message):
+    """
+    Indicates that a variable has been explicitly annotated to but not actually
+    used.
+    """
+    message = 'local variable %r is annotated but never used'
+
+    def __init__(self, filename, loc, names):
+        Message.__init__(self, filename, loc)
+        self.message_args = (names,)
+
+
 class ReturnOutsideFunction(Message):
     """
     Indicates a return statement outside of a function/method.
@@ -237,14 +245,6 @@
 
     def __init__(self, filename, loc, annotation):
         Message.__init__(self, filename, loc)
-        self.message_args = (annotation,)
-
-
-class CommentAnnotationSyntaxError(Message):
-    message = 'syntax error in type comment %r'
-
-    def __init__(self, filename, loc, annotation):
-        Message.__init__(self, filename, loc)
         self.message_args = (annotation,)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/pyflakes/test/harness.py 
new/pyflakes-3.0.1/pyflakes/test/harness.py
--- old/pyflakes-2.5.0/pyflakes/test/harness.py 2022-07-30 19:03:28.000000000 
+0200
+++ new/pyflakes-3.0.1/pyflakes/test/harness.py 2022-11-24 17:02:51.000000000 
+0100
@@ -16,13 +16,10 @@
 
     def flakes(self, input, *expectedOutputs, **kw):
         tree = ast.parse(textwrap.dedent(input))
-        file_tokens = checker.make_tokens(textwrap.dedent(input))
         if kw.get('is_segment'):
             tree = tree.body[0]
             kw.pop('is_segment')
-        w = checker.Checker(
-            tree, file_tokens=file_tokens, withDoctest=self.withDoctest, **kw
-        )
+        w = checker.Checker(tree, withDoctest=self.withDoctest, **kw)
         outputs = [type(o) for o in w.messages]
         expectedOutputs = list(expectedOutputs)
         outputs.sort(key=lambda t: t.__name__)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/pyflakes/test/test_checker.py 
new/pyflakes-3.0.1/pyflakes/test/test_checker.py
--- old/pyflakes-2.5.0/pyflakes/test/test_checker.py    2022-07-30 
19:03:28.000000000 +0200
+++ new/pyflakes-3.0.1/pyflakes/test/test_checker.py    1970-01-01 
01:00:00.000000000 +0100
@@ -1,184 +0,0 @@
-import ast
-
-from pyflakes import checker
-from pyflakes.test.harness import TestCase
-
-
-class TypeableVisitorTests(TestCase):
-    """
-    Tests of L{_TypeableVisitor}
-    """
-
-    @staticmethod
-    def _run_visitor(s):
-        """
-        Run L{_TypeableVisitor} on the parsed source and return the visitor.
-        """
-        tree = ast.parse(s)
-        visitor = checker._TypeableVisitor()
-        visitor.visit(tree)
-        return visitor
-
-    def test_node_types(self):
-        """
-        Test that the typeable node types are collected
-        """
-        visitor = self._run_visitor(
-            """\
-x = 1  # assignment
-for x in range(1): pass  # for loop
-def f(): pass  # function definition
-with a as b: pass  # with statement
-"""
-        )
-        self.assertEqual(visitor.typeable_lines, [1, 2, 3, 4])
-        self.assertIsInstance(visitor.typeable_nodes[1], ast.Assign)
-        self.assertIsInstance(visitor.typeable_nodes[2], ast.For)
-        self.assertIsInstance(visitor.typeable_nodes[3], ast.FunctionDef)
-        self.assertIsInstance(visitor.typeable_nodes[4], ast.With)
-
-    def test_visitor_recurses(self):
-        """
-        Test the common pitfall of missing `generic_visit` in visitors by
-        ensuring that nested nodes are reported
-        """
-        visitor = self._run_visitor(
-            """\
-def f():
-    x = 1
-"""
-        )
-        self.assertEqual(visitor.typeable_lines, [1, 2])
-        self.assertIsInstance(visitor.typeable_nodes[1], ast.FunctionDef)
-        self.assertIsInstance(visitor.typeable_nodes[2], ast.Assign)
-
-    def test_py35_node_types(self):
-        """
-        Test that the PEP 492 node types are collected
-        """
-        visitor = self._run_visitor(
-            """\
-async def f():  # async def
-    async for x in y:  pass  # async for
-    async with a as b: pass  # async with
-"""
-        )
-        self.assertEqual(visitor.typeable_lines, [1, 2, 3])
-        self.assertIsInstance(visitor.typeable_nodes[1], ast.AsyncFunctionDef)
-        self.assertIsInstance(visitor.typeable_nodes[2], ast.AsyncFor)
-        self.assertIsInstance(visitor.typeable_nodes[3], ast.AsyncWith)
-
-    def test_last_node_wins(self):
-        """
-        Test that when two typeable nodes are present on a line, the last
-        typeable one wins.
-        """
-        visitor = self._run_visitor('x = 1; y = 1')
-        # detected both assignable nodes
-        self.assertEqual(visitor.typeable_lines, [1, 1])
-        # but the assignment to `y` wins
-        self.assertEqual(visitor.typeable_nodes[1].targets[0].id, 'y')
-
-
-class CollectTypeCommentsTests(TestCase):
-    """
-    Tests of L{_collect_type_comments}
-    """
-
-    @staticmethod
-    def _collect(s):
-        """
-        Run L{_collect_type_comments} on the parsed source and return the
-        mapping from nodes to comments.  The return value is converted to
-        a set: {(node_type, tuple of comments), ...}
-        """
-        tree = ast.parse(s)
-        tokens = checker.make_tokens(s)
-        ret = checker._collect_type_comments(tree, tokens)
-        return {(type(k), tuple(s for _, s in v)) for k, v in ret.items()}
-
-    def test_bytes(self):
-        """
-        Test that the function works for binary source
-        """
-        ret = self._collect(b'x = 1  # type: int')
-        self.assertSetEqual(ret, {(ast.Assign, ('# type: int',))})
-
-    def test_text(self):
-        """
-        Test that the function works for text source
-        """
-        ret = self._collect('x = 1  # type: int')
-        self.assertEqual(ret, {(ast.Assign, ('# type: int',))})
-
-    def test_non_type_comment_ignored(self):
-        """
-        Test that a non-type comment is ignored
-        """
-        ret = self._collect('x = 1  # noqa')
-        self.assertSetEqual(ret, set())
-
-    def test_type_comment_before_typeable(self):
-        """
-        Test that a type comment before something typeable is ignored.
-        """
-        ret = self._collect('# type: int\nx = 1')
-        self.assertSetEqual(ret, set())
-
-    def test_type_ignore_comment_ignored(self):
-        """
-        Test that `# type: ignore` comments are not collected.
-        """
-        ret = self._collect('x = 1  # type: ignore')
-        self.assertSetEqual(ret, set())
-
-    def test_type_ignore_with_other_things_ignored(self):
-        """
-        Test that `# type: ignore` comments with more content are also not
-        collected.
-        """
-        ret = self._collect('x = 1  # type: ignore # noqa')
-        self.assertSetEqual(ret, set())
-        ret = self._collect('x = 1  #type:ignore#noqa')
-        self.assertSetEqual(ret, set())
-
-    def test_type_comment_with_extra_still_collected(self):
-        ret = self._collect('x = 1  # type: int  # noqa')
-        self.assertSetEqual(ret, {(ast.Assign, ('# type: int  # noqa',))})
-
-    def test_type_comment_without_whitespace(self):
-        ret = self._collect('x = 1 #type:int')
-        self.assertSetEqual(ret, {(ast.Assign, ('#type:int',))})
-
-    def test_type_comment_starts_with_word_ignore(self):
-        ret = self._collect('x = 1 # type: ignore[T]')
-        self.assertSetEqual(ret, set())
-
-    def test_last_node_wins(self):
-        """
-        Test that when two typeable nodes are present on a line, the last
-        typeable one wins.
-        """
-        ret = self._collect('def f(): x = 1  # type: int')
-        self.assertSetEqual(ret, {(ast.Assign, ('# type: int',))})
-
-    def test_function_def_assigned_comments(self):
-        """
-        Test that type comments for function arguments are all attributed to
-        the function definition.
-        """
-        ret = self._collect(
-            """\
-def f(
-        a,  # type: int
-        b,  # type: str
-):
-    # type: (...) -> None
-    pass
-"""
-        )
-        expected = {(
-            ast.FunctionDef,
-            ('# type: int', '# type: str', '# type: (...) -> None'),
-        )}
-        self.assertSetEqual(ret, expected)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/pyflakes/test/test_other.py 
new/pyflakes-3.0.1/pyflakes/test/test_other.py
--- old/pyflakes-2.5.0/pyflakes/test/test_other.py      2022-07-30 
19:03:28.000000000 +0200
+++ new/pyflakes-3.0.1/pyflakes/test/test_other.py      2022-11-24 
17:51:58.000000000 +0100
@@ -2052,6 +2052,10 @@
         self.assertEqual(exc.lineno, 4)
         self.assertEqual(exc.col, 0)
 
+    def test_print_augmented_assign(self):
+        # nonsense, but shouldn't crash pyflakes
+        self.flakes('print += 1')
+
     def test_print_function_assignment(self):
         """
         A valid assignment, tested for catching false positives.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/pyflakes-2.5.0/pyflakes/test/test_type_annotations.py 
new/pyflakes-3.0.1/pyflakes/test/test_type_annotations.py
--- old/pyflakes-2.5.0/pyflakes/test/test_type_annotations.py   2022-07-30 
19:03:28.000000000 +0200
+++ new/pyflakes-3.0.1/pyflakes/test/test_type_annotations.py   2022-11-24 
17:02:51.000000000 +0100
@@ -17,22 +17,22 @@
         from typing import overload
 
         @overload
-        def f(s):  # type: (None) -> None
+        def f(s: None) -> None:
             pass
 
         @overload
-        def f(s):  # type: (int) -> int
+        def f(s: int) -> int:
             pass
 
         def f(s):
             return s
 
         @typing.overload
-        def g(s):  # type: (None) -> None
+        def g(s: None) -> None:
             pass
 
         @typing.overload
-        def g(s):  # type: (int) -> int
+        def g(s: int) -> int:
             pass
 
         def g(s):
@@ -46,22 +46,22 @@
         from typing_extensions import overload
 
         @overload
-        def f(s):  # type: (None) -> None
+        def f(s: None) -> None:
             pass
 
         @overload
-        def f(s):  # type: (int) -> int
+        def f(s: int) -> int:
             pass
 
         def f(s):
             return s
 
         @typing_extensions.overload
-        def g(s):  # type: (None) -> None
+        def g(s: None) -> None:
             pass
 
         @typing_extensions.overload
-        def g(s):  # type: (int) -> int
+        def g(s: int) -> int:
             pass
 
         def g(s):
@@ -74,11 +74,11 @@
         from typing import overload
 
         @overload
-        async def f(s):  # type: (None) -> None
+        async def f(s: None) -> None:
             pass
 
         @overload
-        async def f(s):  # type: (int) -> int
+        async def f(s: int) -> int:
             pass
 
         async def f(s):
@@ -92,12 +92,12 @@
 
             @dec
             @overload
-            def f(x):  # type: (int) -> int
+            def f(x: int) -> int:
                 pass
 
             @dec
             @overload
-            def f(x):  # type: (str) -> str
+            def f(x: str) -> str:
                 pass
 
             @dec
@@ -110,11 +110,11 @@
 
         class C:
             @overload
-            def f(self, x):  # type: (int) -> int
+            def f(self, x: int) -> int:
                 pass
 
             @overload
-            def f(self, x):  # type: (str) -> str
+            def f(self, x: str) -> str:
                 pass
 
             def f(self, x): return x
@@ -126,11 +126,11 @@
         import typing as t
 
         @t.overload
-        def f(s):  # type: (None) -> None
+        def f(s: None) -> None:
             pass
 
         @t.overload
-        def f(s):  # type: (int) -> int
+        def f(s: int) -> int:
             pass
 
         def f(s):
@@ -174,7 +174,7 @@
         def f():
             name: str
             age: int
-        ''')
+        ''', m.UnusedAnnotation, m.UnusedAnnotation)
         self.flakes('''
         def f():
             name: str = 'Bob'
@@ -190,7 +190,7 @@
         from typing import Any
         def f():
             a: Any
-        ''')
+        ''', m.UnusedAnnotation)
         self.flakes('''
         foo: not_a_real_type
         ''', m.UndefinedName)
@@ -298,6 +298,11 @@
         a: 'a: "A"'
         ''', m.ForwardAnnotationSyntaxError)
 
+    def test_variable_annotation_references_self_name_undefined(self):
+        self.flakes("""
+        x: int = x
+        """, m.UndefinedName)
+
     def test_TypeAlias_annotations(self):
         self.flakes("""
         from typing_extensions import TypeAlias
@@ -351,11 +356,10 @@
         class Cls:
             y: int
         ''')
-        # TODO: this should print a UnusedVariable message
         self.flakes('''
         def f():
             x: int
-        ''')
+        ''', m.UnusedAnnotation)
         # This should only print one UnusedVariable message
         self.flakes('''
         def f():
@@ -363,6 +367,12 @@
             x = 3
         ''', m.UnusedVariable)
 
+    def test_unassigned_annotation_is_undefined(self):
+        self.flakes('''
+        name: str
+        print(name)
+        ''', m.UndefinedName)
+
     def test_annotated_async_def(self):
         self.flakes('''
         class c: pass
@@ -406,115 +416,6 @@
             __all__: List[str]
         ''')
 
-    def test_typeCommentsMarkImportsAsUsed(self):
-        self.flakes("""
-        from mod import A, B, C, D, E, F, G
-
-
-        def f(
-            a,  # type: A
-        ):
-            # type: (...) -> B
-            for b in a:  # type: C
-                with b as c:  # type: D
-                    d = c.x  # type: E
-                    return d
-
-
-        def g(x):  # type: (F) -> G
-            return x.y
-        """)
-
-    def test_typeCommentsFullSignature(self):
-        self.flakes("""
-        from mod import A, B, C, D
-        def f(a, b):
-            # type: (A, B[C]) -> D
-            return a + b
-        """)
-
-    def test_typeCommentsStarArgs(self):
-        self.flakes("""
-        from mod import A, B, C, D
-        def f(a, *b, **c):
-            # type: (A, *B, **C) -> D
-            return a + b
-        """)
-
-    def test_typeCommentsFullSignatureWithDocstring(self):
-        self.flakes('''
-        from mod import A, B, C, D
-        def f(a, b):
-            # type: (A, B[C]) -> D
-            """do the thing!"""
-            return a + b
-        ''')
-
-    def test_typeCommentsAdditionalComment(self):
-        self.flakes("""
-        from mod import F
-
-        x = 1 # type: F  # noqa
-        """)
-
-    def test_typeCommentsNoWhitespaceAnnotation(self):
-        self.flakes("""
-        from mod import F
-
-        x = 1  #type:F
-        """)
-
-    def test_typeCommentsInvalidDoesNotMarkAsUsed(self):
-        self.flakes("""
-        from mod import F
-
-        # type: F
-        """, m.UnusedImport)
-
-    def test_typeCommentsSyntaxError(self):
-        self.flakes("""
-        def f(x):  # type: (F[) -> None
-            pass
-        """, m.CommentAnnotationSyntaxError)
-
-    def test_typeCommentsSyntaxErrorCorrectLine(self):
-        checker = self.flakes("""\
-        x = 1
-        # type: definitely not a PEP 484 comment
-        """, m.CommentAnnotationSyntaxError)
-        self.assertEqual(checker.messages[0].lineno, 2)
-
-    def test_typeCommentsAssignedToPreviousNode(self):
-        # This test demonstrates an issue in the implementation which
-        # associates the type comment with a node above it, however the type
-        # comment isn't valid according to mypy.  If an improved approach
-        # which can detect these "invalid" type comments is implemented, this
-        # test should be removed / improved to assert that new check.
-        self.flakes("""
-        from mod import F
-        x = 1
-        # type: F
-        """)
-
-    def test_typeIgnore(self):
-        self.flakes("""
-        a = 0  # type: ignore
-        b = 0  # type: ignore[excuse]
-        c = 0  # type: ignore=excuse
-        d = 0  # type: ignore [excuse]
-        e = 0  # type: ignore whatever
-        """)
-
-    def test_typeIgnoreBogus(self):
-        self.flakes("""
-        x = 1  # type: ignored
-        """, m.UndefinedName)
-
-    def test_typeIgnoreBogusUnicode(self):
-        self.flakes("""
-        x = 2  # type: ignore\xc3
-        """, m.UndefinedName)
-
     def test_return_annotation_is_class_scope_variable(self):
         self.flakes("""
         from typing import TypeVar
@@ -704,7 +605,7 @@
             if TYPE_CHECKING:
                 from t import T
 
-            def f():  # type: () -> T
+            def f() -> T:
                 pass
         """)
         # False: the old, more-compatible approach
@@ -712,7 +613,7 @@
             if False:
                 from t import T
 
-            def f():  # type: () -> T
+            def f() -> T:
                 pass
         """)
         # some choose to assign a constant and do it that way
@@ -722,7 +623,7 @@
             if MYPY:
                 from t import T
 
-            def f():  # type: () -> T
+            def f() -> T:
                 pass
         """)
 
@@ -736,7 +637,7 @@
                 Protocol = object
 
             class C(Protocol):
-                def f():  # type: () -> int
+                def f() -> int:
                     pass
         """)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/pyflakes/test/test_undefined_names.py 
new/pyflakes-3.0.1/pyflakes/test/test_undefined_names.py
--- old/pyflakes-2.5.0/pyflakes/test/test_undefined_names.py    2022-07-30 
19:03:28.000000000 +0200
+++ new/pyflakes-3.0.1/pyflakes/test/test_undefined_names.py    2022-11-24 
17:18:39.000000000 +0100
@@ -814,7 +814,6 @@
         raised.
         """
         tree = ast.parse("x = 10")
-        file_tokens = checker.make_tokens("x = 10")
         # Make it into something unrecognizable.
         tree.body[0].targets[0].ctx = object()
-        self.assertRaises(RuntimeError, checker.Checker, tree, 
file_tokens=file_tokens)
+        self.assertRaises(RuntimeError, checker.Checker, tree)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/pyflakes.egg-info/PKG-INFO 
new/pyflakes-3.0.1/pyflakes.egg-info/PKG-INFO
--- old/pyflakes-2.5.0/pyflakes.egg-info/PKG-INFO       2022-07-30 
19:28:49.000000000 +0200
+++ new/pyflakes-3.0.1/pyflakes.egg-info/PKG-INFO       2022-11-24 
17:53:21.000000000 +0100
@@ -1,12 +1,11 @@
 Metadata-Version: 2.1
 Name: pyflakes
-Version: 2.5.0
+Version: 3.0.1
 Summary: passive checker of Python programs
 Home-page: https://github.com/PyCQA/pyflakes
 Author: A lot of people
 Author-email: code-qual...@python.org
 License: MIT
-Platform: UNKNOWN
 Classifier: Development Status :: 6 - Mature
 Classifier: Environment :: Console
 Classifier: Intended Audience :: Developers
@@ -52,11 +51,11 @@
 Useful tips:
 
 * Be sure to install it for a version of Python which is compatible
-  with your codebase: for Python 2, ``pip2 install pyflakes`` and for
-  Python3, ``pip3 install pyflakes``.
+  with your codebase: ``python#.# -m pip install pyflakes`` (for example,
+  ``python3.10 -m pip install pyflakes``)
 
-* You can also invoke Pyflakes with ``python3 -m pyflakes .`` or
-  ``python2 -m pyflakes .`` if you have it installed for both versions.
+* You can also invoke Pyflakes with ``python#.# -m pyflakes .`` if you want
+  to run it for a specific python version.
 
 * If you require more options and more flexibility, you could give a
   look to Flake8_ too.
@@ -92,7 +91,7 @@
 
 Patches may be submitted via a `GitHub pull request`_ or via the mailing list
 if you prefer. If you are comfortable doing so, please `rebase your changes`_
-so they may be applied to master with a fast-forward merge, and each commit is
+so they may be applied to main with a fast-forward merge, and each commit is
 a coherent unit of work with a well-written log message.  If you are not
 comfortable with this rebase workflow, the project maintainers will be happy to
 rebase your commits for you.
@@ -112,6 +111,4 @@
 Changelog
 ---------
 
-Please see `NEWS.rst 
<https://github.com/PyCQA/pyflakes/blob/master/NEWS.rst>`_.
-
-
+Please see `NEWS.rst <https://github.com/PyCQA/pyflakes/blob/main/NEWS.rst>`_.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pyflakes-2.5.0/pyflakes.egg-info/SOURCES.txt 
new/pyflakes-3.0.1/pyflakes.egg-info/SOURCES.txt
--- old/pyflakes-2.5.0/pyflakes.egg-info/SOURCES.txt    2022-07-30 
19:28:49.000000000 +0200
+++ new/pyflakes-3.0.1/pyflakes.egg-info/SOURCES.txt    2022-11-24 
17:53:21.000000000 +0100
@@ -23,7 +23,6 @@
 pyflakes/test/harness.py
 pyflakes/test/test_api.py
 pyflakes/test/test_builtin.py
-pyflakes/test/test_checker.py
 pyflakes/test/test_code_segment.py
 pyflakes/test/test_dict.py
 pyflakes/test/test_doctests.py

Reply via email to