Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-flake8-bugbear for
openSUSE:Factory checked in at 2023-07-12 17:27:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-flake8-bugbear (Old)
and /work/SRC/openSUSE:Factory/.python-flake8-bugbear.new.8922 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-flake8-bugbear"
Wed Jul 12 17:27:24 2023 rev:15 rq:1098207 version:23.7.10
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-flake8-bugbear/python-flake8-bugbear.changes
2023-06-11 19:58:36.872366122 +0200
+++
/work/SRC/openSUSE:Factory/.python-flake8-bugbear.new.8922/python-flake8-bugbear.changes
2023-07-12 17:27:50.466706226 +0200
@@ -1,0 +2,10 @@
+Tue Jul 11 14:10:46 UTC 2023 - Dirk Müller <[email protected]>
+
+- update to 23.7.10:
+ * Add B034: re.sub/subn/split must pass flags/count/maxsplit as
+ keyword arguments.
+ * Fix a crash and several test failures on Python 3.12, all
+ relating to the B907 * check.
+ * Declare support for Python 3.12.
+
+-------------------------------------------------------------------
Old:
----
flake8-bugbear-23.6.5.tar.gz
New:
----
flake8-bugbear-23.7.10.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-flake8-bugbear.spec ++++++
--- /var/tmp/diff_new_pack.znxZnQ/_old 2023-07-12 17:27:51.086710518 +0200
+++ /var/tmp/diff_new_pack.znxZnQ/_new 2023-07-12 17:27:51.090710546 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-flake8-bugbear
-Version: 23.6.5
+Version: 23.7.10
Release: 0
Summary: A plugin for flake8 finding likely bugs and design problems in
your program
License: MIT
++++++ flake8-bugbear-23.6.5.tar.gz -> flake8-bugbear-23.7.10.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8-bugbear-23.6.5/PKG-INFO
new/flake8-bugbear-23.7.10/PKG-INFO
--- old/flake8-bugbear-23.6.5/PKG-INFO 2023-06-05 18:20:50.367162500 +0200
+++ new/flake8-bugbear-23.7.10/PKG-INFO 2023-07-10 18:29:34.876180400 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: flake8-bugbear
-Version: 23.6.5
+Version: 23.7.10
Summary: A plugin for flake8 finding likely bugs and design problems in your
program. Contains warnings that don't belong in pyflakes and pycodestyle.
Author-email: Åukasz Langa <[email protected]>
License: MIT
@@ -19,6 +19,7 @@
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Quality Assurance
@@ -217,6 +218,8 @@
**B033**: Sets should not contain duplicate items. Duplicate items will be
replaced with a single item at runtime.
+**B034**: Calls to `re.sub`, `re.subn` or `re.split` should pass `flags` or
`count`/`maxsplit` as keyword arguments. It is commonly assumed that `flags` is
the third positional parameter, forgetting about `count`/`maxsplit`, since many
other `re` module functions are of the form `f(pattern, string, flags)`.
+
Opinionated warnings
~~~~~~~~~~~~~~~~~~~~
@@ -249,8 +252,11 @@
for details.
**B905**: ``zip()`` without an explicit `strict=` parameter set.
``strict=True`` causes the resulting iterator
-to raise a ``ValueError`` if the arguments are exhausted at differing lengths.
The ``strict=`` argument
-was added in Python 3.10, so don't enable this flag for code that should work
on <3.10.
+to raise a ``ValueError`` if the arguments are exhausted at differing lengths.
+
+Exclusions are `itertools.count
<https://docs.python.org/3/library/itertools.html#itertools.count>`_,
`itertools.cycle
<https://docs.python.org/3/library/itertools.html#itertools.cycle>`_ and
`itertools.repeat
<https://docs.python.org/3/library/itertools.html#itertools.repeat>`_ (with
times=None) since they are infinite iterators.
+
+The ``strict=`` argument was added in Python 3.10, so don't enable this flag
for code that should work on <3.10.
For more information: https://peps.python.org/pep-0618/
**B906**: ``visit_`` function with no further call to a ``visit`` function.
This is often an error, and will stop the visitor from recursing into the
subnodes of a visited node. Consider adding a call ``self.generic_visit(node)``
at the end of the function.
@@ -358,6 +364,14 @@
Change Log
----------
+23.7.10
+~~~~~~~~~~
+
+* Add B034: re.sub/subn/split must pass flags/count/maxsplit as keyword
arguments.
+* Fix a crash and several test failures on Python 3.12, all relating to the
B907
+ check.
+* Declare support for Python 3.12.
+
23.6.5
~~~~~~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8-bugbear-23.6.5/README.rst
new/flake8-bugbear-23.7.10/README.rst
--- old/flake8-bugbear-23.6.5/README.rst 2023-06-05 18:20:41.000000000
+0200
+++ new/flake8-bugbear-23.7.10/README.rst 2023-07-10 18:29:25.000000000
+0200
@@ -188,6 +188,8 @@
**B033**: Sets should not contain duplicate items. Duplicate items will be
replaced with a single item at runtime.
+**B034**: Calls to `re.sub`, `re.subn` or `re.split` should pass `flags` or
`count`/`maxsplit` as keyword arguments. It is commonly assumed that `flags` is
the third positional parameter, forgetting about `count`/`maxsplit`, since many
other `re` module functions are of the form `f(pattern, string, flags)`.
+
Opinionated warnings
~~~~~~~~~~~~~~~~~~~~
@@ -220,8 +222,11 @@
for details.
**B905**: ``zip()`` without an explicit `strict=` parameter set.
``strict=True`` causes the resulting iterator
-to raise a ``ValueError`` if the arguments are exhausted at differing lengths.
The ``strict=`` argument
-was added in Python 3.10, so don't enable this flag for code that should work
on <3.10.
+to raise a ``ValueError`` if the arguments are exhausted at differing lengths.
+
+Exclusions are `itertools.count
<https://docs.python.org/3/library/itertools.html#itertools.count>`_,
`itertools.cycle
<https://docs.python.org/3/library/itertools.html#itertools.cycle>`_ and
`itertools.repeat
<https://docs.python.org/3/library/itertools.html#itertools.repeat>`_ (with
times=None) since they are infinite iterators.
+
+The ``strict=`` argument was added in Python 3.10, so don't enable this flag
for code that should work on <3.10.
For more information: https://peps.python.org/pep-0618/
**B906**: ``visit_`` function with no further call to a ``visit`` function.
This is often an error, and will stop the visitor from recursing into the
subnodes of a visited node. Consider adding a call ``self.generic_visit(node)``
at the end of the function.
@@ -329,6 +334,14 @@
Change Log
----------
+23.7.10
+~~~~~~~~~~
+
+* Add B034: re.sub/subn/split must pass flags/count/maxsplit as keyword
arguments.
+* Fix a crash and several test failures on Python 3.12, all relating to the
B907
+ check.
+* Declare support for Python 3.12.
+
23.6.5
~~~~~~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8-bugbear-23.6.5/bugbear.py
new/flake8-bugbear-23.7.10/bugbear.py
--- old/flake8-bugbear-23.6.5/bugbear.py 2023-06-05 18:20:41.000000000
+0200
+++ new/flake8-bugbear-23.7.10/bugbear.py 2023-07-10 18:29:25.000000000
+0200
@@ -5,6 +5,7 @@
import math
import re
import sys
+import warnings
from collections import namedtuple
from contextlib import suppress
from functools import lru_cache, partial
@@ -13,7 +14,7 @@
import attr
import pycodestyle
-__version__ = "23.6.5"
+__version__ = "23.7.10"
LOG = logging.getLogger("flake8.bugbear")
CONTEXTFUL_NODES = (
@@ -200,7 +201,7 @@
if not isinstance(arg, ast.Constant) or not isinstance(arg.value, str):
return False
- return re.match(r"^[A-Za-z_][A-Za-z0-9_]*$", arg.s) is not None
+ return re.match(r"^[A-Za-z_][A-Za-z0-9_]*$", arg.value) is not None
def _flatten_excepthandler(node):
@@ -401,14 +402,14 @@
with suppress(AttributeError, IndexError):
if (
node.func.id in ("getattr", "hasattr")
- and node.args[1].s == "__call__"
+ and node.args[1].value == "__call__"
):
self.errors.append(B004(node.lineno, node.col_offset))
if (
node.func.id == "getattr"
and len(node.args) == 2
and _is_identifier(node.args[1])
- and not iskeyword(node.args[1].s)
+ and not iskeyword(node.args[1].value)
):
self.errors.append(B009(node.lineno, node.col_offset))
elif (
@@ -416,14 +417,15 @@
and node.func.id == "setattr"
and len(node.args) == 3
and _is_identifier(node.args[1])
- and not iskeyword(node.args[1].s)
+ and not iskeyword(node.args[1].value)
):
self.errors.append(B010(node.lineno, node.col_offset))
self.check_for_b026(node)
- self.check_for_b905(node)
self.check_for_b028(node)
+ self.check_for_b034(node)
+ self.check_for_b905(node)
self.generic_visit(node)
def visit_Module(self, node):
@@ -556,11 +558,11 @@
if call_path in B005.valid_paths:
return # path is exempt
- s = node.args[0].s
- if len(s) == 1:
+ value = node.args[0].value
+ if len(value) == 1:
return # stripping just one character
- if len(s) == len(set(s)):
+ if len(value) == len(set(value)):
return # no characters appear more than once
self.errors.append(B005(node.lineno, node.col_offset))
@@ -1168,12 +1170,46 @@
for duplicate in duplicates:
self.errors.append(B025(node.lineno, node.col_offset,
vars=(duplicate,)))
- def check_for_b905(self, node):
- if (
- isinstance(node.func, ast.Name)
- and node.func.id == "zip"
- and not any(kw.arg == "strict" for kw in node.keywords)
+ @staticmethod
+ def _is_infinite_iterator(node: ast.expr) -> bool:
+ if not (
+ isinstance(node, ast.Call)
+ and isinstance(node.func, ast.Attribute)
+ and isinstance(node.func.value, ast.Name)
+ and node.func.value.id == "itertools"
):
+ return False
+ if node.func.attr in {"cycle", "count"}:
+ return True
+ elif node.func.attr == "repeat":
+ if len(node.args) == 1 and len(node.keywords) == 0:
+ # itertools.repeat(iterable)
+ return True
+ if (
+ len(node.args) == 2
+ and isinstance(node.args[1], ast.Constant)
+ and node.args[1].value is None
+ ):
+ # itertools.repeat(iterable, None)
+ return True
+ for kw in node.keywords:
+ # itertools.repeat(iterable, times=None)
+ if (
+ kw.arg == "times"
+ and isinstance(kw.value, ast.Constant)
+ and kw.value.value is None
+ ):
+ return True
+
+ return False
+
+ def check_for_b905(self, node):
+ if not (isinstance(node.func, ast.Name) and node.func.id == "zip"):
+ return
+ for arg in node.args:
+ if self._is_infinite_iterator(arg):
+ return
+ if not any(kw.arg == "strict" for kw in node.keywords):
self.errors.append(B905(node.lineno, node.col_offset))
def check_for_b906(self, node: ast.FunctionDef):
@@ -1182,7 +1218,12 @@
# extract what's visited
class_name = node.name[len("visit_") :]
- class_type = getattr(ast, class_name, None)
+
+ # silence any DeprecationWarnings
+ # that might come from accessing a deprecated AST node
+ with warnings.catch_warnings():
+ warnings.simplefilter("ignore", category=DeprecationWarning)
+ class_type = getattr(ast, class_name, None)
if (
# not a valid ast subclass
@@ -1239,36 +1280,34 @@
current_mark = None
variable = None
for value in node.values:
- # check for quote mark after pre-marked variable
- if (
- current_mark is not None
- and variable is not None
- and isinstance(value, ast.Constant)
- and isinstance(value.value, str)
- and value.value[0] == current_mark
- ):
- self.errors.append(
- B907(
- variable.lineno,
- variable.col_offset,
- vars=(myunparse(variable.value),),
- )
- )
- current_mark = variable = None
- # don't continue with length>1, so we can detect a new pre-mark
- # in the same string as a post-mark, e.g. `"{foo}" "{bar}"`
- if len(value.value) == 1:
+ if isinstance(value, ast.Constant) and isinstance(value.value,
str):
+ if not value.value:
continue
- # detect pre-mark
- if (
- isinstance(value, ast.Constant)
- and isinstance(value.value, str)
- and value.value[-1] in quote_marks
- ):
- current_mark = value.value[-1]
- variable = None
- continue
+ # check for quote mark after pre-marked variable
+ if (
+ current_mark is not None
+ and variable is not None
+ and value.value[0] == current_mark
+ ):
+ self.errors.append(
+ B907(
+ variable.lineno,
+ variable.col_offset,
+ vars=(myunparse(variable.value),),
+ )
+ )
+ current_mark = variable = None
+ # don't continue with length>1, so we can detect a new
pre-mark
+ # in the same string as a post-mark, e.g. `"{foo}" "{bar}"`
+ if len(value.value) == 1:
+ continue
+
+ # detect pre-mark
+ if value.value[-1] in quote_marks:
+ current_mark = value.value[-1]
+ variable = None
+ continue
# detect variable, if there's a pre-mark
if (
@@ -1362,6 +1401,27 @@
else:
seen.add(elt.value)
+ def check_for_b034(self, node: ast.Call):
+ if not isinstance(node.func, ast.Attribute):
+ return
+ if not isinstance(node.func.value, ast.Name) or node.func.value.id !=
"re":
+ return
+
+ def check(num_args, param_name):
+ if len(node.args) > num_args:
+ self.errors.append(
+ B034(
+ node.args[num_args].lineno,
+ node.args[num_args].col_offset,
+ vars=(node.func.attr, param_name),
+ )
+ )
+
+ if node.func.attr in ("sub", "subn"):
+ check(3, "count")
+ elif node.func.attr == "split":
+ check(2, "maxsplit")
+
def compose_call_path(node):
if isinstance(node, ast.Attribute):
@@ -1766,6 +1826,13 @@
)
)
+B034 = Error(
+ message=(
+ "B034 {} should pass `{}` and `flags` as keyword arguments to avoid
confusion"
+ " due to unintuitive argument positions."
+ )
+)
+
# Warnings disabled by default.
B901 = Error(
message=(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flake8-bugbear-23.6.5/flake8_bugbear.egg-info/PKG-INFO
new/flake8-bugbear-23.7.10/flake8_bugbear.egg-info/PKG-INFO
--- old/flake8-bugbear-23.6.5/flake8_bugbear.egg-info/PKG-INFO 2023-06-05
18:20:50.000000000 +0200
+++ new/flake8-bugbear-23.7.10/flake8_bugbear.egg-info/PKG-INFO 2023-07-10
18:29:34.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: flake8-bugbear
-Version: 23.6.5
+Version: 23.7.10
Summary: A plugin for flake8 finding likely bugs and design problems in your
program. Contains warnings that don't belong in pyflakes and pycodestyle.
Author-email: Åukasz Langa <[email protected]>
License: MIT
@@ -19,6 +19,7 @@
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
+Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Quality Assurance
@@ -217,6 +218,8 @@
**B033**: Sets should not contain duplicate items. Duplicate items will be
replaced with a single item at runtime.
+**B034**: Calls to `re.sub`, `re.subn` or `re.split` should pass `flags` or
`count`/`maxsplit` as keyword arguments. It is commonly assumed that `flags` is
the third positional parameter, forgetting about `count`/`maxsplit`, since many
other `re` module functions are of the form `f(pattern, string, flags)`.
+
Opinionated warnings
~~~~~~~~~~~~~~~~~~~~
@@ -249,8 +252,11 @@
for details.
**B905**: ``zip()`` without an explicit `strict=` parameter set.
``strict=True`` causes the resulting iterator
-to raise a ``ValueError`` if the arguments are exhausted at differing lengths.
The ``strict=`` argument
-was added in Python 3.10, so don't enable this flag for code that should work
on <3.10.
+to raise a ``ValueError`` if the arguments are exhausted at differing lengths.
+
+Exclusions are `itertools.count
<https://docs.python.org/3/library/itertools.html#itertools.count>`_,
`itertools.cycle
<https://docs.python.org/3/library/itertools.html#itertools.cycle>`_ and
`itertools.repeat
<https://docs.python.org/3/library/itertools.html#itertools.repeat>`_ (with
times=None) since they are infinite iterators.
+
+The ``strict=`` argument was added in Python 3.10, so don't enable this flag
for code that should work on <3.10.
For more information: https://peps.python.org/pep-0618/
**B906**: ``visit_`` function with no further call to a ``visit`` function.
This is often an error, and will stop the visitor from recursing into the
subnodes of a visited node. Consider adding a call ``self.generic_visit(node)``
at the end of the function.
@@ -358,6 +364,14 @@
Change Log
----------
+23.7.10
+~~~~~~~~~~
+
+* Add B034: re.sub/subn/split must pass flags/count/maxsplit as keyword
arguments.
+* Fix a crash and several test failures on Python 3.12, all relating to the
B907
+ check.
+* Declare support for Python 3.12.
+
23.6.5
~~~~~~
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/flake8-bugbear-23.6.5/flake8_bugbear.egg-info/SOURCES.txt
new/flake8-bugbear-23.7.10/flake8_bugbear.egg-info/SOURCES.txt
--- old/flake8-bugbear-23.6.5/flake8_bugbear.egg-info/SOURCES.txt
2023-06-05 18:20:50.000000000 +0200
+++ new/flake8-bugbear-23.7.10/flake8_bugbear.egg-info/SOURCES.txt
2023-07-10 18:29:34.000000000 +0200
@@ -48,6 +48,7 @@
tests/b031.py
tests/b032.py
tests/b033.py
+tests/b034.py
tests/b901.py
tests/b902.py
tests/b902_py38.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8-bugbear-23.6.5/pyproject.toml
new/flake8-bugbear-23.7.10/pyproject.toml
--- old/flake8-bugbear-23.6.5/pyproject.toml 2023-06-05 18:20:41.000000000
+0200
+++ new/flake8-bugbear-23.7.10/pyproject.toml 2023-07-10 18:29:25.000000000
+0200
@@ -30,6 +30,7 @@
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
+ "Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3 :: Only",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Software Development :: Quality Assurance",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8-bugbear-23.6.5/tests/b034.py
new/flake8-bugbear-23.7.10/tests/b034.py
--- old/flake8-bugbear-23.6.5/tests/b034.py 1970-01-01 01:00:00.000000000
+0100
+++ new/flake8-bugbear-23.7.10/tests/b034.py 2023-07-10 18:29:25.000000000
+0200
@@ -0,0 +1,30 @@
+import re
+from re import sub
+
+# error
+re.sub("a", "b", "aaa", re.IGNORECASE)
+re.sub("a", "b", "aaa", 5)
+re.sub("a", "b", "aaa", 5, re.IGNORECASE)
+re.subn("a", "b", "aaa", re.IGNORECASE)
+re.subn("a", "b", "aaa", 5)
+re.subn("a", "b", "aaa", 5, re.IGNORECASE)
+re.split(" ", "a a a a", re.I)
+re.split(" ", "a a a a", 2)
+re.split(" ", "a a a a", 2, re.I)
+
+# okay
+re.sub("a", "b", "aaa")
+re.sub("a", "b", "aaa", flags=re.IGNORECASE)
+re.sub("a", "b", "aaa", count=5)
+re.sub("a", "b", "aaa", count=5, flags=re.IGNORECASE)
+re.subn("a", "b", "aaa")
+re.subn("a", "b", "aaa", flags=re.IGNORECASE)
+re.subn("a", "b", "aaa", count=5)
+re.subn("a", "b", "aaa", count=5, flags=re.IGNORECASE)
+re.split(" ", "a a a a", flags=re.I)
+re.split(" ", "a a a a", maxsplit=2)
+re.split(" ", "a a a a", maxsplit=2, flags=re.I)
+
+
+# not covered
+sub("a", "b", "aaa", re.IGNORECASE)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8-bugbear-23.6.5/tests/b905_py310.py
new/flake8-bugbear-23.7.10/tests/b905_py310.py
--- old/flake8-bugbear-23.6.5/tests/b905_py310.py 2023-06-05
18:20:41.000000000 +0200
+++ new/flake8-bugbear-23.7.10/tests/b905_py310.py 2023-07-10
18:29:25.000000000 +0200
@@ -8,3 +8,15 @@
zip(range(3), strict=True)
zip("a", "b", strict=False)
zip("a", "b", "c", strict=True)
+
+# infinite iterators from itertools module should not raise errors
+import itertools
+
+zip([1, 2, 3], itertools.cycle("ABCDEF"))
+zip([1, 2, 3], itertools.count())
+zip([1, 2, 3], itertools.repeat(1))
+zip([1, 2, 3], itertools.repeat(1, None))
+zip([1, 2, 3], itertools.repeat(1, times=None))
+
+zip([1, 2, 3], itertools.repeat(1, 1))
+zip([1, 2, 3], itertools.repeat(1, times=4))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8-bugbear-23.6.5/tests/b907.py
new/flake8-bugbear-23.7.10/tests/b907.py
--- old/flake8-bugbear-23.6.5/tests/b907.py 2023-06-05 18:20:41.000000000
+0200
+++ new/flake8-bugbear-23.7.10/tests/b907.py 2023-07-10 18:29:25.000000000
+0200
@@ -17,12 +17,12 @@
f'a "{foo()}" b'
# fmt: off
-k = (f'"' # error emitted on this line since all values are assigned the same
lineno
+k = (f'"' # Error emitted here on <py312 (all values assigned the same lineno)
f'{var}'
f'"'
f'"')
-k = (f'"' # error emitted on this line
+k = (f'"' # error emitted on this line on <py312
f'{var}'
'"'
f'"')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8-bugbear-23.6.5/tests/test_bugbear.py
new/flake8-bugbear-23.7.10/tests/test_bugbear.py
--- old/flake8-bugbear-23.6.5/tests/test_bugbear.py 2023-06-05
18:20:41.000000000 +0200
+++ new/flake8-bugbear-23.7.10/tests/test_bugbear.py 2023-07-10
18:29:25.000000000 +0200
@@ -8,9 +8,6 @@
from argparse import Namespace
from pathlib import Path
-from hypothesis import HealthCheck, given, settings
-from hypothesmith import from_grammar
-
from bugbear import (
B001,
B002,
@@ -45,6 +42,7 @@
B031,
B032,
B033,
+ B034,
B901,
B902,
B903,
@@ -505,6 +503,23 @@
)
self.assertEqual(errors, expected)
+ def test_b034(self):
+ filename = Path(__file__).absolute().parent / "b034.py"
+ bbc = BugBearChecker(filename=str(filename))
+ errors = list(bbc.run())
+ expected = self.errors(
+ B034(5, 24, vars=("sub", "count")),
+ B034(6, 24, vars=("sub", "count")),
+ B034(7, 24, vars=("sub", "count")),
+ B034(8, 25, vars=("subn", "count")),
+ B034(9, 25, vars=("subn", "count")),
+ B034(10, 25, vars=("subn", "count")),
+ B034(11, 25, vars=("split", "maxsplit")),
+ B034(12, 25, vars=("split", "maxsplit")),
+ B034(13, 25, vars=("split", "maxsplit")),
+ )
+ self.assertEqual(errors, expected)
+
def test_b908(self):
filename = Path(__file__).absolute().parent / "b908.py"
bbc = BugBearChecker(filename=str(filename))
@@ -524,43 +539,51 @@
filename = Path(__file__).absolute().parent / "b907.py"
bbc = BugBearChecker(filename=str(filename))
errors = list(bbc.run())
- expected = self.errors(
- B907(8, 0, vars=("var",)),
- B907(9, 0, vars=("var",)),
- B907(10, 0, vars=("var",)),
- B907(12, 0, vars=("var",)),
- B907(13, 0, vars=("var",)),
- B907(14, 0, vars=("var",)),
- B907(16, 0, vars=("'hello'",)),
- B907(17, 0, vars=("foo()",)),
- B907(20, 5, vars=("var",)),
- B907(25, 5, vars=("var",)),
- B907(31, 0, vars=("var",)),
- B907(32, 0, vars=("var",)),
- B907(33, 0, vars=("var",)),
- B907(33, 0, vars=("var2",)),
- B907(34, 0, vars=("var",)),
- B907(34, 0, vars=("var2",)),
- B907(35, 0, vars=("var",)),
- B907(35, 0, vars=("var2",)),
- B907(38, 0, vars=("var2",)),
- B907(41, 0, vars=("var",)),
- B907(42, 0, vars=("var.__str__",)),
- B907(43, 0, vars=("var.__str__.__repr__",)),
- B907(44, 0, vars=("3 + 5" if sys.version_info >= (3, 9) else
"BinOp",)),
- B907(45, 0, vars=("foo()",)),
- B907(46, 0, vars=("None",)),
- B907(47, 0, vars=("..." if sys.version_info >= (3, 9) else
"Ellipsis",)),
- B907(48, 0, vars=("True",)),
- B907(51, 0, vars=("var",)),
- B907(52, 0, vars=("var",)),
- B907(53, 0, vars=("var",)),
- B907(54, 0, vars=("var",)),
- B907(57, 0, vars=("var",)),
- B907(60, 0, vars=("var",)),
- B907(64, 0, vars=("var",)),
- B907(66, 0, vars=("var",)),
- B907(68, 0, vars=("var",)),
+ py39 = sys.version_info >= (3, 9)
+ py312 = sys.version_info >= (3, 12)
+
+ def on_py312(number):
+ """F-string nodes have column numbers set to 0 on <py312"""
+ return number if py312 else 0
+
+ expected = self.errors(
+ B907(8, on_py312(9), vars=("var",)),
+ B907(9, on_py312(3), vars=("var",)),
+ B907(10, on_py312(9), vars=("var",)),
+ B907(12, on_py312(9), vars=("var",)),
+ B907(13, on_py312(3), vars=("var",)),
+ B907(14, on_py312(9), vars=("var",)),
+ B907(16, on_py312(5), vars=("'hello'",)),
+ B907(17, on_py312(5), vars=("foo()",)),
+ # Multiline f-strings have lineno changes as well as colno changes
on py312+
+ B907(21 if py312 else 20, 7 if py312 else 5, vars=("var",)),
+ B907(26 if py312 else 25, 7 if py312 else 5, vars=("var",)),
+ B907(31, on_py312(12), vars=("var",)),
+ B907(32, on_py312(3), vars=("var",)),
+ B907(33, on_py312(3), vars=("var",)),
+ B907(33, on_py312(29), vars=("var2",)),
+ B907(34, on_py312(3), vars=("var",)),
+ B907(34, on_py312(15), vars=("var2",)),
+ B907(35, on_py312(3), vars=("var",)),
+ B907(35, on_py312(10), vars=("var2",)),
+ B907(38, on_py312(13), vars=("var2",)),
+ B907(41, on_py312(3), vars=("var",)),
+ B907(42, on_py312(3), vars=("var.__str__",)),
+ B907(43, on_py312(3), vars=("var.__str__.__repr__",)),
+ B907(44, on_py312(3), vars=("3 + 5" if py39 else "BinOp",)),
+ B907(45, on_py312(3), vars=("foo()",)),
+ B907(46, on_py312(3), vars=("None",)),
+ B907(47, on_py312(3), vars=("..." if py39 else "Ellipsis",)),
+ B907(48, on_py312(3), vars=("True",)),
+ B907(51, on_py312(3), vars=("var",)),
+ B907(52, on_py312(3), vars=("var",)),
+ B907(53, on_py312(3), vars=("var",)),
+ B907(54, on_py312(3), vars=("var",)),
+ B907(57, on_py312(3), vars=("var",)),
+ B907(60, on_py312(3), vars=("var",)),
+ B907(64, on_py312(5), vars=("var",)),
+ B907(66, on_py312(3), vars=("var",)),
+ B907(68, on_py312(3), vars=("var",)),
)
self.assertEqual(errors, expected)
@@ -695,6 +718,8 @@
B905(4, 15),
B905(5, 4),
B905(6, 0),
+ B905(21, 0),
+ B905(22, 0),
]
self.assertEqual(errors, self.errors(*expected))
@@ -795,13 +820,18 @@
class TestFuzz(unittest.TestCase):
- @settings(suppress_health_check=[HealthCheck.too_slow])
- @given(from_grammar().map(ast.parse))
- def test_does_not_crash_on_any_valid_code(self, syntax_tree):
- # Given any syntatically-valid source code, flake8-bugbear should
- # not crash. This tests doesn't check that we do the *right* thing,
- # just that we don't crash on valid-if-poorly-styled code!
- BugBearVisitor(filename="<string>", lines=[]).visit(syntax_tree)
+ # TODO: enable this test on py312 once hypothesmith supports py312
+ if sys.version_info < (3, 12):
+ from hypothesis import HealthCheck, given, settings
+ from hypothesmith import from_grammar
+
+ @settings(suppress_health_check=[HealthCheck.too_slow])
+ @given(from_grammar().map(ast.parse))
+ def test_does_not_crash_on_any_valid_code(self, syntax_tree):
+ # Given any syntatically-valid source code, flake8-bugbear should
+ # not crash. This tests doesn't check that we do the *right*
thing,
+ # just that we don't crash on valid-if-poorly-styled code!
+ BugBearVisitor(filename="<string>", lines=[]).visit(syntax_tree)
def test_does_not_crash_on_site_code(self):
# Because the generator isn't perfect, we'll also test on all the code
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/flake8-bugbear-23.6.5/tox.ini
new/flake8-bugbear-23.7.10/tox.ini
--- old/flake8-bugbear-23.6.5/tox.ini 2023-06-05 18:20:41.000000000 +0200
+++ new/flake8-bugbear-23.7.10/tox.ini 2023-07-10 18:29:25.000000000 +0200
@@ -1,7 +1,7 @@
# The test environment and commands
[tox]
# default environments to run without `-e`
-envlist = py38, py39, py310, py311
+envlist = py38, py39, py310, py311, py312
[gh-actions]
python =
@@ -9,8 +9,9 @@
3.9: py39
3.10: py310
3.11: py311
+ 3.12: py312
-[testenv:{py38, py39, py310, py311}]
+[testenv]
description = Run coverage
deps =
coverage
@@ -19,3 +20,8 @@
commands =
coverage run tests/test_bugbear.py {posargs}
coverage report -m
+
+[testenv:py312]
+deps =
+ # the other dependencies aren't yet installable on py312+
+ coverage