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 2026-11-10 14:38:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pyflakes (Old)
and /work/SRC/openSUSE:Factory/.python-pyflakes.new.3759290 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pyflakes"
Tue Nov 10 14:38:12 2026 rev:44 rq:1396168 version:4.1.0
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pyflakes/python-pyflakes.changes
2026-10-27 18:20:58.990673232 +0100
+++
/work/SRC/openSUSE:Factory/.python-pyflakes.new.3759290/python-pyflakes.changes
2026-11-10 14:38:17.600224034 +0100
@@ -1,0 +2,8 @@
+Sun Nov 8 18:56:20 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 4.1.0:
+ * Drop support for EOL python 3.10
+ * Significant performance improvements
+ * Fix handling of Literal and Annotated for lazy imports
+
+-------------------------------------------------------------------
Old:
----
pyflakes-4.0.3.tar.gz
New:
----
pyflakes-4.1.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-pyflakes.spec ++++++
--- /var/tmp/diff_new_pack.Oau17j/_old 2026-11-10 14:38:18.987282086 +0100
+++ /var/tmp/diff_new_pack.Oau17j/_new 2026-11-10 14:38:18.992282295 +0100
@@ -23,13 +23,13 @@
%endif
%{?sle15_python_module_pythons}
Name: python-pyflakes
-Version: 4.0.3
+Version: 4.1.0
Release: 0
Summary: Passive checker of Python programs
License: MIT
URL: https://github.com/PyCQA/pyflakes
Source:
https://files.pythonhosted.org/packages/source/p/pyflakes/pyflakes-%{version}.tar.gz
-BuildRequires: %{python_module base >= 3.10}
+BuildRequires: %{python_module base >= 3.11}
BuildRequires: %{python_module pip}
BuildRequires: %{python_module pytest}
BuildRequires: %{python_module setuptools}
++++++ pyflakes-4.0.3.tar.gz -> pyflakes-4.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyflakes-4.0.3/NEWS.rst new/pyflakes-4.1.0/NEWS.rst
--- old/pyflakes-4.0.3/NEWS.rst 2026-10-07 20:55:21.000000000 +0200
+++ new/pyflakes-4.1.0/NEWS.rst 2026-10-28 21:08:31.000000000 +0100
@@ -1,3 +1,9 @@
+4.1.0 (2026-10-28)
+
+- Drop support for EOL python 3.10
+- Significant performance improvements
+- Fix handling of ``Literal`` and ``Annotated`` for lazy imports
+
4.0.3 (2026-10-07)
- A few performance improvements
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyflakes-4.0.3/PKG-INFO new/pyflakes-4.1.0/PKG-INFO
--- old/pyflakes-4.0.3/PKG-INFO 2026-10-07 20:57:05.259256800 +0200
+++ new/pyflakes-4.1.0/PKG-INFO 2026-10-28 21:09:32.999373700 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: pyflakes
-Version: 4.0.3
+Version: 4.1.0
Summary: passive checker of Python programs
Home-page: https://github.com/PyCQA/pyflakes
Author: A lot of people
@@ -17,7 +17,7 @@
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development
Classifier: Topic :: Utilities
-Requires-Python: >=3.10
+Requires-Python: >=3.11
License-File: LICENSE
Dynamic: author
Dynamic: author-email
@@ -56,7 +56,7 @@
* Be sure to install it for a version of Python which is compatible
with your codebase: ``python#.# -m pip install pyflakes`` (for example,
- ``python3.10 -m pip install pyflakes``)
+ ``python3.15 -m pip install pyflakes``)
* You can also invoke Pyflakes with ``python#.# -m pyflakes .`` if you want
to run it for a specific python version.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyflakes-4.0.3/README.rst
new/pyflakes-4.1.0/README.rst
--- old/pyflakes-4.0.3/README.rst 2026-10-07 20:38:35.000000000 +0200
+++ new/pyflakes-4.1.0/README.rst 2026-10-28 21:07:25.000000000 +0100
@@ -25,7 +25,7 @@
* Be sure to install it for a version of Python which is compatible
with your codebase: ``python#.# -m pip install pyflakes`` (for example,
- ``python3.10 -m pip install pyflakes``)
+ ``python3.15 -m pip install pyflakes``)
* You can also invoke Pyflakes with ``python#.# -m pyflakes .`` if you want
to run it for a specific python version.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyflakes-4.0.3/pyflakes/__init__.py
new/pyflakes-4.1.0/pyflakes/__init__.py
--- old/pyflakes-4.0.3/pyflakes/__init__.py 2026-10-07 20:55:27.000000000
+0200
+++ new/pyflakes-4.1.0/pyflakes/__init__.py 2026-10-28 21:08:49.000000000
+0100
@@ -1 +1 @@
-__version__ = '4.0.3'
+__version__ = '4.1.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyflakes-4.0.3/pyflakes/checker.py
new/pyflakes-4.1.0/pyflakes/checker.py
--- old/pyflakes-4.0.3/pyflakes/checker.py 2026-10-07 20:54:03.000000000
+0200
+++ new/pyflakes-4.1.0/pyflakes/checker.py 2026-10-28 21:07:25.000000000
+0100
@@ -690,7 +690,6 @@
NONE = 0
STRING = 1
BARE = 2
- STR_AS_TYPE = 3
def in_annotation(func):
@@ -731,6 +730,8 @@
def __init__(self, tree, filename='(none)', builtins=None,
withDoctest='PYFLAKES_DOCTEST' in os.environ):
self._nodeHandlers = {}
+ self._parents = {}
+ self._node_depths = {}
self._deferred = collections.deque()
self.deadScopes = []
self.messages = []
@@ -743,8 +744,10 @@
self.root = tree
self.scopeStack = []
- scope_tp = Checker._ast_node_scope[type(tree)]
+ self._running_deferred = False
+
+ scope_tp = Checker._ast_node_scope[type(tree)]
with self.in_scope(scope_tp):
for builtin in self.builtIns:
self.addBinding(None, Builtin(builtin))
@@ -765,6 +768,8 @@
self._deferred.append((callable, self.scopeStack[:], self.offset))
def _run_deferred(self):
+ self._running_deferred = True
+
orig = (self.scopeStack, self.offset)
while self._deferred:
@@ -794,9 +799,7 @@
@property
def annotationsFutureEnabled(self):
scope = self.scopeStack[0]
- if not isinstance(scope, ModuleScope):
- return False
- return scope._annotations_future_enabled
+ return isinstance(scope, ModuleScope) and
scope._annotations_future_enabled
@annotationsFutureEnabled.setter
def annotationsFutureEnabled(self, value):
@@ -890,29 +893,26 @@
def getParent(self, node):
# Lookup the first parent which is not Tuple, List or Starred
while True:
- node = node._pyflakes_parent
+ node = self._parents[node]
if not hasattr(node, 'elts') and not hasattr(node, 'ctx'):
return node
def getCommonAncestor(self, lnode, rnode, stop):
if (
stop in (lnode, rnode) or
- not (
- hasattr(lnode, '_pyflakes_parent') and
- hasattr(rnode, '_pyflakes_parent')
- )
+ not (lnode in self._parents and rnode in self._parents)
):
return None
if lnode is rnode:
return lnode
- if (lnode._pyflakes_depth > rnode._pyflakes_depth):
- return self.getCommonAncestor(lnode._pyflakes_parent, rnode, stop)
- if (lnode._pyflakes_depth < rnode._pyflakes_depth):
- return self.getCommonAncestor(lnode, rnode._pyflakes_parent, stop)
+ if self._node_depths[lnode] > self._node_depths[rnode]:
+ return self.getCommonAncestor(self._parents[lnode], rnode, stop)
+ if self._node_depths[lnode] < self._node_depths[rnode]:
+ return self.getCommonAncestor(lnode, self._parents[rnode], stop)
return self.getCommonAncestor(
- lnode._pyflakes_parent,
- rnode._pyflakes_parent,
+ self._parents[lnode],
+ self._parents[rnode],
stop,
)
@@ -940,7 +940,7 @@
- `node` is the statement responsible for the change
- `value` is the new value, a Binding instance
"""
- # assert value.source in (node, node._pyflakes_parent):
+ # assert value.source in (node, self._parents[node]):
for scope in reversed(self.scopeStack):
if value.name in scope:
break
@@ -1058,10 +1058,8 @@
elif (
isinstance(binding, Importation) and
binding.is_lazy and
- func_depth == 0 and (
- self._in_annotation == AnnotationState.NONE or
- self._in_annotation == AnnotationState.STR_AS_TYPE
- )
+ func_depth == 0 and
+ not self._running_deferred
): # pragma: >=3.15 cover
self.report(messages.EagerUseOfLazyImport, node, name,
binding.source)
@@ -1139,18 +1137,18 @@
if isinstance(parent_stmt, ast.AnnAssign) and parent_stmt.value is
None:
binding = Annotation(name, node)
elif isinstance(parent_stmt, (FOR_TYPES, ast.comprehension)) or (
- parent_stmt != node._pyflakes_parent and
+ parent_stmt != self._parents[node] and
not self.isLiteralTupleUnpacking(parent_stmt)):
binding = Binding(name, node)
elif (
name == '__all__' and
isinstance(self.scope, ModuleScope) and
isinstance(
- node._pyflakes_parent,
+ self._parents[node],
(ast.Assign, ast.AugAssign, ast.AnnAssign)
)
):
- binding = ExportBinding(name, node._pyflakes_parent, self.scope)
+ binding = ExportBinding(name, self._parents[node], self.scope)
elif isinstance(parent_stmt, ast.NamedExpr):
binding = NamedExprAssignment(name, node)
else:
@@ -1163,11 +1161,11 @@
"""
Return `True` if node is part of a conditional body.
"""
- current = getattr(node, '_pyflakes_parent', None)
+ current = self._parents.get(node)
while current:
if isinstance(current, (ast.If, ast.While, ast.IfExp)):
return True
- current = getattr(current, '_pyflakes_parent', None)
+ current = self._parents.get(current)
return False
if on_conditional_branch():
@@ -1247,8 +1245,8 @@
):
self.futuresAllowed = False
self.nodeDepth += 1
- node._pyflakes_depth = self.nodeDepth
- node._pyflakes_parent = parent
+ self._node_depths[node] = self.nodeDepth
+ self._parents[node] = parent
try:
handler = self.getNodeHandler(node.__class__)
handler(node)
@@ -1497,7 +1495,7 @@
self._handle_string_dot_format(node)
def _annotation(n: ast.AST) -> None:
- with self._enter_annotation(AnnotationState.STR_AS_TYPE):
+ with self._enter_annotation(AnnotationState.BARE):
self.handleNode(n, node)
def _annotations(nodes: list[ast.AST]) -> None:
@@ -1917,7 +1915,7 @@
if isinstance(node.ctx, ast.Load):
self.handleNodeLoad(node, self.getParent(node))
if (node.id == 'locals' and isinstance(self.scope, FunctionScope)
and
- isinstance(node._pyflakes_parent, ast.Call)):
+ isinstance(self._parents[node], ast.Call)):
# we are doing locals() call in current scope
self.scope.usesLocals = True
elif isinstance(node.ctx, ast.Store):
@@ -1933,8 +1931,8 @@
# definition (not OK), for 'continue', a finally block (not OK), or
# the top module scope (not OK)
n = node
- while hasattr(n, '_pyflakes_parent'):
- n, n_child = n._pyflakes_parent, n
+ while n in self._parents:
+ n, n_child = self._parents[n], n
if isinstance(n, (ast.While, ast.For, ast.AsyncFor)):
# Doesn't apply unless it's in the loop itself
if n_child not in n.orelse:
@@ -2073,7 +2071,7 @@
if node.value:
# If the annotation is `TypeAlias`, handle the *value* as an
annotation.
if _is_typing(node.annotation, 'TypeAlias', self.scopeStack):
- with self._enter_annotation(AnnotationState.STR_AS_TYPE):
+ with self._enter_annotation(AnnotationState.BARE):
self.handleNode(node.value, node)
else:
self.handleNode(node.value, node)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyflakes-4.0.3/pyflakes/test/test_api.py
new/pyflakes-4.1.0/pyflakes/test/test_api.py
--- old/pyflakes-4.0.3/pyflakes/test/test_api.py 2026-10-07
20:38:35.000000000 +0200
+++ new/pyflakes-4.1.0/pyflakes/test/test_api.py 2026-10-28
21:07:25.000000000 +0100
@@ -400,11 +400,11 @@
with self.makeTempFile(source) as sourcePath:
self.assertHasErrors(
sourcePath,
- ["""\
-%s:8:12: unterminated triple-quoted string literal (detected at line 8)
+ [f"""\
+{sourcePath}:8:12: unterminated triple-quoted string literal (detected at line
8)
'''quux'''
^
-""" % (sourcePath,)])
+"""])
def test_eofSyntaxError(self):
"""
@@ -579,11 +579,7 @@
x = "%s"
""" % SNOWMAN).encode('utf-16')
with self.makeTempFile(source) as sourcePath:
- if sys.version_info < (3, 11, 4): # pragma: <3.11 cover
- expected = f"{sourcePath}: problem decoding source\n"
- else: # pragma: >=3.11 cover
- expected = f"{sourcePath}:1: source code string cannot contain
null bytes\n" # noqa: E501
-
+ expected = f"{sourcePath}:1: source code string cannot contain
null bytes\n" # noqa: E501
self.assertHasErrors(sourcePath, [expected])
def test_checkRecursive(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyflakes-4.0.3/pyflakes/test/test_lazy_imports.py
new/pyflakes-4.1.0/pyflakes/test/test_lazy_imports.py
--- old/pyflakes-4.0.3/pyflakes/test/test_lazy_imports.py 2026-10-07
20:38:35.000000000 +0200
+++ new/pyflakes-4.1.0/pyflakes/test/test_lazy_imports.py 2026-10-28
21:07:25.000000000 +0100
@@ -80,7 +80,9 @@
{y for _ in [...]} # evaluated comprehensions
{0: y for _ in [...]} # evaluated comprehensions
- ''', *([m.EagerUseOfLazyImport] * 8))
+ @y
+ def u(): pass
+ ''', *([m.EagerUseOfLazyImport] * 9))
def test_lazy_imports_eager_use_in_type_alias(self):
self.flakes('''
@@ -102,3 +104,11 @@
type A = Literal[int]
''')
+
+ def test_literal_annotated_not_considered_eager(self):
+ self.flakes('''
+ lazy from x import y
+ from typing import Literal, Annotated
+ x: Literal[y]
+ z: Annotated[int, y]
+ ''')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyflakes-4.0.3/pyflakes/test/test_other.py
new/pyflakes-4.1.0/pyflakes/test/test_other.py
--- old/pyflakes-4.0.3/pyflakes/test/test_other.py 2026-10-07
20:38:35.000000000 +0200
+++ new/pyflakes-4.1.0/pyflakes/test/test_other.py 2026-10-28
21:07:25.000000000 +0100
@@ -1668,8 +1668,7 @@
except Exception as e: pass
''', m.UnusedVariable)
- @skipIf(version_info < (3, 11), 'new in Python 3.11')
- def test_exception_unused_in_except_star(self): # pragma: >=3.11 cover
+ def test_exception_unused_in_except_star(self):
self.flakes('''
try:
pass
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/pyflakes-4.0.3/pyflakes/test/test_type_annotations.py
new/pyflakes-4.1.0/pyflakes/test/test_type_annotations.py
--- old/pyflakes-4.0.3/pyflakes/test/test_type_annotations.py 2026-10-07
20:54:03.000000000 +0200
+++ new/pyflakes-4.1.0/pyflakes/test/test_type_annotations.py 2026-10-28
21:07:25.000000000 +0100
@@ -830,8 +830,7 @@
NamedTuple("NT", y)
""")
- @skipIf(version_info < (3, 11), 'new in Python 3.11')
- def test_variadic_generics(self): # pragma: >=3.11 cover
+ def test_variadic_generics(self):
self.flakes("""
from typing import Generic
from typing import TypeVarTuple
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyflakes-4.0.3/pyflakes.egg-info/PKG-INFO
new/pyflakes-4.1.0/pyflakes.egg-info/PKG-INFO
--- old/pyflakes-4.0.3/pyflakes.egg-info/PKG-INFO 2026-10-07
20:57:05.000000000 +0200
+++ new/pyflakes-4.1.0/pyflakes.egg-info/PKG-INFO 2026-10-28
21:09:32.000000000 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: pyflakes
-Version: 4.0.3
+Version: 4.1.0
Summary: passive checker of Python programs
Home-page: https://github.com/PyCQA/pyflakes
Author: A lot of people
@@ -17,7 +17,7 @@
Classifier: Programming Language :: Python :: Implementation :: PyPy
Classifier: Topic :: Software Development
Classifier: Topic :: Utilities
-Requires-Python: >=3.10
+Requires-Python: >=3.11
License-File: LICENSE
Dynamic: author
Dynamic: author-email
@@ -56,7 +56,7 @@
* Be sure to install it for a version of Python which is compatible
with your codebase: ``python#.# -m pip install pyflakes`` (for example,
- ``python3.10 -m pip install pyflakes``)
+ ``python3.15 -m pip install pyflakes``)
* You can also invoke Pyflakes with ``python#.# -m pyflakes .`` if you want
to run it for a specific python version.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/pyflakes-4.0.3/setup.py new/pyflakes-4.1.0/setup.py
--- old/pyflakes-4.0.3/setup.py 2026-10-07 20:38:35.000000000 +0200
+++ new/pyflakes-4.1.0/setup.py 2026-10-28 21:07:25.000000000 +0100
@@ -42,7 +42,7 @@
author_email="[email protected]",
url="https://github.com/PyCQA/pyflakes",
packages=["pyflakes", "pyflakes.scripts", "pyflakes.test"],
- python_requires='>=3.10',
+ python_requires='>=3.11',
classifiers=[
"Development Status :: 6 - Mature",
"Environment :: Console",