I am using pylint on most of my code to make sure nothing
bad or too complicated sneaks in.
So far it has helped me a lot in discovering stuff I would not notice, and
if you are not using #pylint: disable=...
too often it forces you
to write better code.
I just stumbled across this:
I want to find the first element in a list of elements that is bigger than the specified one. For simplicity I am just using numbers here…
./some.py
:
def function(current, *selection):
for number in [num for num in sorted(selection) if num > current]:
return number
But my tests show me that something bad is happening…
./test_some.py
:
from some import function
NUMBERS = [5, 4, 3, 2, 1]
def test_function():
assert function(3, *NUMBERS) == 4
assert function(3) is None
Running the tests shows that the last assert statement goes over the
for loop end exits the function
, returning None
.
$ pytest -vv test_some.py
================= test session starts =================
collected 1 item
test_some.py::test_function PASSED [100%]
================== 1 passed in 0.02s ==================
But running the tests yields no errors:
$ pylint --disable "C0114" --disable "C0116" some.py test_some.py
------------------------------------
Your code has been rated at 10.00/10
I would have expected this typical message:
Either all return statements in a function should return an expression, or none of them should. (
inconsistent-return-statements
)
Weird.
So, digging a little further, that example can be trimmed down to this:
def fun():
for _ in []:
return True
It seems, that the check for inconsistent-return-statements
gets
confused by the return
inside the for
loop.
It does (or cannot?) not check if the input of the for
loop is empty or
not.
So, now I am aware of this. Anyway, I only discovered this while doing
test driven development. For a moment I was confused why some assert
bailed out with some None
value for some edge-case that was not implemented
yet..
So long!