Search code examples
pythonpylintdivide-by-zero

pylint division by zero warning


Is there any way to enable division by zero warning in pylint?

"""
Oh my ...
"""
SOME_WRONG_GLOBAL = 0
NUMER = 7 / SOME_WRONG_GLOBAL

An equivalent example in cpp issues a proper warning:

$ cat main.cpp
#define SOME_WRONG_MACRO 0
int main(int argc, char **argv)
{
    int NUMBER = 7/SOME_WRONG_MACRO;
    return 0;
}
$ g++ main.cpp -o main
main.cpp: In function ‘int main(int, char**)’:
main.cpp:4:19: warning: division by zero [-Wdiv-by-zero]
     int NUMBER = 7/SOME_WRONG_MACRO;

EDIT Even if I add const-ness with:

from typing import Final
SOME_WRONG_GLOBAL: Final[int] = 0

I still don't get any warning with pylint (and neither with mypy)


Solution

  • The underlying AST representation of astroid used by pylint is powerful and can infer values of variable.

    >>> from astroid import parse
    >>> a = parse("""
     ... SOME_WRONG_GLOBAL = 0
     ... NUMER = 7 / SOME_WRONG_GLOBAL
     ... """)
    >>> list(a.locals["NUMER"][0].infer())
    [Uninferable]
    >>>list(a.locals["SOME_WRONG_GLOBAL"][0].infer())[0].value
    0
    

    If we change the value of SOME_WRONG_GLOBAL to 2, it could tell that the value of list(a.locals["NUMER"][0].infer())[0].value is 3.5.

    So it's not impossible but would require a new check in pylint and maybe a more explicit return than Uninferable from astroid. Something being Uninferable does not mean that there's an error in the code, only that astroid cannot tell what the value is.