From d77e9744e2fa10f663b487f20d99371bd3db4648 Mon Sep 17 00:00:00 2001 From: Perry Vargas Date: Fri, 31 Dec 2021 12:50:04 -0800 Subject: [PATCH 1/2] Allow the same special cases for B950 as E501 (176) --- .gitignore | 1 + README.rst | 15 ++++++++++++++- bugbear.py | 25 ++++++++++++++++++++++++- tests/b950.py | 14 ++++++++++++++ tests/test_bugbear.py | 10 +++++++++- 5 files changed, 62 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index fc8539e..1dc5815 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ var/ *.egg-info/ .installed.cfg *.egg +venv/ # PyInstaller # Usually these files are written by a python script from a template diff --git a/README.rst b/README.rst index 6d94ba7..7ad3874 100644 --- a/README.rst +++ b/README.rst @@ -173,7 +173,15 @@ significantly violate the line length, you will receive a message that states what the actual limit is. This is inspired by Raymond Hettinger's `"Beyond PEP 8" talk `_ and highway patrol not stopping you if you drive < 5mph too fast. Disable -E501 to avoid duplicate warnings. +E501 to avoid duplicate warnings. Like E501, this error ignores long shebangs +on the first line and urls or paths that are on their own line:: + + #! long shebang ignored + + # https://some-super-long-domain-name.com/with/some/very/long/paths + url = ( + "https://some-super-long-domain-name.com/with/some/very/long/paths" + ) How to enable opinionated warnings @@ -237,6 +245,11 @@ MIT Change Log ---------- +21.12.0 +~~~~~~~~~~ + +* B950: Add same special cases as E501 (#213) + 21.11.29 ~~~~~~~~~~ diff --git a/bugbear.py b/bugbear.py index eab2b53..97c6f86 100644 --- a/bugbear.py +++ b/bugbear.py @@ -12,7 +12,7 @@ import attr import pycodestyle -__version__ = "21.11.29" +__version__ = "21.12.0" LOG = logging.getLogger("flake8.bugbear") CONTEXTFUL_NODES = ( @@ -67,8 +67,31 @@ def gen_line_based_checks(self): The following simple checks are based on the raw lines, not the AST. """ for lineno, line in enumerate(self.lines, start=1): + # Special case: ignore long shebang (following pycodestyle). + if lineno == 1 and line.startswith("#!"): + continue + length = len(line) - 1 if length > 1.1 * self.max_line_length: + # Special case long URLS and paths to follow pycodestyle. + # Would use the `pycodestyle.maximum_line_length` directly but + # need to supply it arguments that are not available so chose + # to replicate instead. + chunks = line.split() + + is_line_comment_url_path = len(chunks) == 2 and chunks[0] == "#" + + just_long_url_path = len(chunks) == 1 + + num_leading_whitespaces = len(line) - len(chunks[-1]) + too_many_leading_white_spaces = ( + num_leading_whitespaces >= self.max_line_length - 7 + ) + + skip = is_line_comment_url_path or just_long_url_path + if skip and not too_many_leading_white_spaces: + continue + yield B950(lineno, length, vars=(length, self.max_line_length)) @classmethod diff --git a/tests/b950.py b/tests/b950.py index 1939105..942e50c 100644 --- a/tests/b950.py +++ b/tests/b950.py @@ -1,3 +1,4 @@ +#! Ignore long shebang fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo # Assumes the default allowed line length of 79 "line is fine" @@ -5,3 +6,16 @@ " line is still fine " " line is no longer fine by any measures, yup" "line is fine again" + +# Ensure URL/path on it's own line is fine +"https://foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.com" +"NOT OK: https://foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.com" +# https://foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.com +# NOT OK: https://foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.com +# +#: Okay +# This +# almost_empty_line_too_long + +# This +# almost_empty_line_too_long diff --git a/tests/test_bugbear.py b/tests/test_bugbear.py index 319a508..d1af992 100644 --- a/tests/test_bugbear.py +++ b/tests/test_bugbear.py @@ -318,7 +318,15 @@ def test_b950(self): filename = Path(__file__).absolute().parent / "b950.py" bbc = BugBearChecker(filename=str(filename)) errors = list(bbc.run()) - self.assertEqual(errors, self.errors(B950(6, 92, vars=(92, 79)))) + self.assertEqual( + errors, + self.errors( + B950(7, 92, vars=(92, 79)), + B950(12, 103, vars=(103, 79)), + B950(14, 103, vars=(103, 79)), + B950(21, 97, vars=(97, 79)), + ), + ) def test_selfclean_bugbear(self): filename = Path(__file__).absolute().parent.parent / "bugbear.py" From 85853f8aabec1964de3a35a53018816496557b18 Mon Sep 17 00:00:00 2001 From: Perry Vargas Date: Sat, 1 Jan 2022 14:10:18 -0800 Subject: [PATCH 2/2] Undo version bump --- bugbear.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bugbear.py b/bugbear.py index 97c6f86..78c2ca3 100644 --- a/bugbear.py +++ b/bugbear.py @@ -12,7 +12,7 @@ import attr import pycodestyle -__version__ = "21.12.0" +__version__ = "21.11.29" LOG = logging.getLogger("flake8.bugbear") CONTEXTFUL_NODES = (