PyCQA / 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.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Feature request: a rule for calling super().__init__() in custom exception's __init__()

m-aciek opened this issue · comments

class CustomException(Exception):
    def __init__(self, custom: int, arguments: str) -> None:
        self.msg = f"Something specific happened with custom: {custom} and {arguments}"

Above exception class has an issue, in my personal experience it's quite common. The implementer assumes, that they will use the self.msg parameter during exception handling. The issue araises when the exception gets anywhere else as its string representation is as follows:

>>> raise CustomException(42, 'test')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.CustomException: (42, 'test')

and when the exception is instantiated with keyword arguments, we lose the information about the arguments' values.

>>> raise CustomException(custom=1, arguments='two')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.CustomException

How to fix it? By calling super().__init__() in the constructor. That way the string representation of the custom exception will contain the error message.

class CustomException(Exception):
    def __init__(self, custom: int, arguments: str) -> None:
        self.msg = "Something specific happened with custom: {custom} and {arguments}"
        super().__init__(self.msg)
>>> raise CustomException(1, 'two')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.CustomException: Something specific happened with custom: 1 and two
>>> raise CustomException(custom=1, parameters='two')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.CustomException: Something specific happened with custom: 1 and two

Specification proposal

If a class:

  • inherits from from Exception,
  • doesn't implement own __str__() method,
  • its __init__() method doesn't enforce any positional-only argument,
  • and doesn't call super().__init__() in its __init__() method

Then:

  • new rule should raise an error, calling to fix it.

Should the example be:

class CustomException(Exception):
    def __init__(self, custom: int, arguments: str) -> None:
        self.msg = f"Something specific happened with custom: {custom} and {arguments}"  # <-- custom
         super().__init__(self.msg)

Seems a good check for me and a bug waiting to happen. Please explain why this is bad to do in the README. And as always, provide good tests with correct code and bad code please.

Should the example be:

Yes, right, thanks. I fixed the original post.