Give AlbumentationsX a star on GitHub — it powers this leaderboard

Star on GitHub

flake8-bugbear

A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle.

Rank: #1485Downloads: 6,687,001 (30 days)Stars: 1,111Forks: 115

Description

==============
flake8-bugbear
==============

.. image:: https://github.com/PyCQA/flake8-bugbear/actions/workflows/ci.yml/badge.svg
   :target: https://github.com/PyCQA/flake8-bugbear/actions/workflows/ci.yml

.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
    :target: https://github.com/psf/black

.. image:: https://results.pre-commit.ci/badge/github/PyCQA/flake8-bugbear/main.svg
   :target: https://results.pre-commit.ci/latest/github/PyCQA/flake8-bugbear/main
   :alt: pre-commit.ci status

A plugin for ``flake8`` finding likely bugs and design problems in your
program.  Contains warnings that don't belong in ``pyflakes`` and
``pycodestyle``::

    bug·bear  (bŭg′bâr′)
    n.
    1. A cause of fear, anxiety, or irritation: *Overcrowding is often
       a bugbear for train commuters.*
    2. A difficult or persistent problem: *"One of the major bugbears of
       traditional AI is the difficulty of programming computers to
       recognize that different but similar objects are instances of the
       same type of thing" (Jack Copeland).*
    3. A fearsome imaginary creature, especially one evoked to frighten
       children.

It is felt that these lints don't belong in the main Python tools as they
are very opinionated and do not have a PEP or standard behind them. Due to
``flake8`` being designed to be extensible, the original creators of these lints
believed that a plugin was the best route. This has resulted in better development
velocity for contributors and adaptive deployment for ``flake8`` users.

Installation
------------

Install from ``pip`` with:

.. code-block:: sh

     pip install flake8-bugbear

It will then automatically be run as part of ``flake8``; you can check it has
been picked up with:

.. code-block:: sh

    $ flake8 --version
    3.5.0 (assertive: 1.0.1, flake8-bugbear: 18.2.0, flake8-comprehensions: 1.4.1, mccabe: 0.6.1, pycodestyle: 2.3.1, pyflakes: 1.6.0) CPython 3.7.0 on Darwin

Development
-----------

If you'd like to do a PR we have development instructions `here <https://github.com/PyCQA/flake8-bugbear/blob/master/DEVELOPMENT.md>`_.

List of warnings
----------------

.. _B001:

**B001**: Do not use bare ``except:``, it also catches unexpected events
like memory errors, interrupts, system exit, and so on.  Prefer ``except
Exception:``.  If you're sure what you're doing, be explicit and write
``except BaseException:``.  Disable ``E722`` to avoid duplicate warnings.

.. _B002:

**B002**: Python does not support the unary prefix increment. Writing
``++n`` is equivalent to ``+(+(n))``, which equals ``n``. You meant ``n
+= 1``.

.. _B003:

**B003**: Assigning to ``os.environ`` doesn't clear the
environment.  Subprocesses are going to see outdated
variables, in disagreement with the current process.  Use
``os.environ.clear()`` or the ``env=``  argument to Popen.

.. _B004:

**B004**: Using ``hasattr(x, '__call__')`` to test if ``x`` is callable
is unreliable.  If ``x`` implements custom ``__getattr__`` or its
``__call__`` is itself not callable, you might get misleading
results.  Use ``callable(x)`` for consistent results.

.. _B005:

**B005**: Using ``.strip()`` with multi-character strings is misleading
the reader. It looks like stripping a substring. Move your
character set to a constant if this is deliberate. Use
``.replace()``, ``.removeprefix()``, ``.removesuffix()`` or regular
expressions to remove string fragments.

.. _B006:

**B006**: Do not use mutable data structures for argument defaults.  They
are created during function definition time. All calls to the function
reuse this one instance of that data structure, persisting changes
between them.

.. _B007:

**B007**: Loop control variable not used within the loop body.  If this is
intended, start the name with an underscore.

.. _B008:

**B008**: Do not perform function calls in argument defaults.  The call is
performed only once at function definition time. All calls to your
function will reuse the result of that definition-time function call.  If
this is intended, assign the function call to a module-level variable and
use that variable as a default value.

.. _B009:

**B009**: Do not call ``getattr(x, 'attr')``, instead use normal
property access: ``x.attr``. Missing a default to ``getattr`` will cause
an ``AttributeError`` to be raised for non-existent properties. There is
no additional safety in using ``getattr`` if you know the attribute name
ahead of time.

.. _B010:

**B010**: Do not call ``setattr(x, 'attr', val)``, instead use normal
property access: ``x.attr = val``. There is no additional safety in
using ``setattr`` if you know the attribute name ahead of time.

.. _B011:

**B011**: Do not call ``assert False`` since ``python -O`` removes these calls.
Instead callers should ``raise AssertionError()``.

.. _B012:

**B012**: Use of ``break``, ``continue`` or ``return`` inside ``finally`` blocks will
silence exceptions or override return values from the ``try`` or ``except`` blocks.
To silence an exception, do it explicitly in the ``except`` block. To properly use
a ``break``, ``continue`` or ``return`` refactor your code so these statements are not
in the ``finally`` block.

.. _B013:

**B013**: A length-one tuple literal is redundant.  Write ``except SomeError:``
instead of ``except (SomeError,):``.

.. _B014:

**B014**: Redundant exception types in ``except (Exception, TypeError):``.
Write ``except Exception:``, which catches exactly the same exceptions.

.. _B015:

**B015**: Pointless comparison. This comparison does nothing but
waste CPU instructions. Either prepend ``assert`` or remove it.

.. _B016:

**B016**: Cannot raise a literal. Did you intend to return it or raise
an Exception?

.. _B017:

**B017**: ``assertRaises(Exception)`` and ``pytest.raises(Exception)`` should
be considered evil. They can lead to your test passing even if the
code being tested is never executed due to a typo. Assert for a more
specific exception (builtin or custom), or use ``assertRaisesRegex``
(if using ``assertRaises``), or add the ``match`` keyword argument (if
using ``pytest.raises``), or use the context manager form with a target
(e.g. ``with self.assertRaises(Exception) as ex:``).

.. _B018:

**B018**: Found useless expression. Either assign it to a variable or remove it.
Note that dangling commas will cause things to be interpreted as useless tuples.
For example, in the statement ``print(".."),`` is the same as ``(print(".."),)``
which is an unassigned tuple. Simply remove the comma to clear the error.

.. _B019:

**B019**: Use of ``functools.lru_cache`` or ``functools.cache`` on methods
can lead to memory leaks. The cache may retain instance references, preventing
garbage collection.

.. _B020:

**B020**: Loop control variable overrides iterable it iterates

.. _B021:

**B021**: f-string used as docstring. This will be interpreted by python
as a joined string rather than a docstring.

.. _B022:

**B022**: No arguments passed to `contextlib.suppress`.
No exceptions will be suppressed and therefore this context manager is redundant.
N.B. this rule currently does not flag `suppress` calls to avoid potential false
positives due to similarly named user-defined functions.

.. _B023:

**B023**: Functions defined inside a loop must not use variables redefined in
the loop, because `late-binding closures are a classic gotcha
<https://docs.python-guide.org/writing/gotchas/#late-binding-closures>`__.

.. _B024:

**B024**: Abstract base class has methods, but none of them are abstract. This
is not necessarily an error, but you might have forgotten to add the @abstractmethod
decorator, potentially in conjunction with @classmethod, @property and/or @staticmethod.

.. _B025:

**B025**: ``try-except`` block with duplicate exceptions found.
This check identifies exception types that are specified in multiple ``except``
clauses. The first specification is the only one ever considered, so all others can be removed.

.. _B026:

**B026**: Star-arg unpacking after a keyword argument is strongly discouraged, because
it only works when the keyword parameter is declared after all parameters supplied by
the unpacked sequence, and this change of ordering can surprise and mislead readers.
There was `cpython discussion of disallowing this syntax
<https://github.com/python/cpython/issues/82741>`_, but legacy usage and parser
limitations make it difficult.

.. _B027:

**B027**: Empty method in abstract base class, but has no abstract decorator. Consider adding @abstractmethod.

.. _B028:

**B028**: No explicit stacklevel argument found. The warn method from the warnings module uses a
stacklevel of 1 by default. This will only show a stack trace for the line on which the warn method is called.
It is therefore recommended to use a stacklevel of 2 or greater to provide more information to the user.
The check is skipped when skip_file_prefixes is used.

.. _B029:

**B029**: Using ``except ():`` with an empty tuple does not handle/catch anything. Add exceptions to handle.

.. _B030:

**B030**: Except handlers should only be exception classes or tuples of exception classes.

.. _B031:

**B031**: Using the generator returned from `itertools.groupby()` more than once will do nothing on the
second usage. Save the result to a list if the result is needed multiple times.

.. _B032:

**B032**: Possible unintentional type annotation (using ``:``). Did you mean to assign (using ``=``)?

.. _B033:

**B033**: Sets should not contain duplicate items. Duplicate items will be replaced with a single item at runtime.

.. _B034:

**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)`.

.. _B035:

**B035**: Found dict comprehension with a static key - either a constant value or variable not from the co