2

There's a common error in the code where people write something like:

if (id):
    query.filter(row.id == id)

instead of

if (id):
    query = query.filter(row.id == id)

The code looks "valid" and it's very hard to spot these by hand. In C++ there's the [[nodiscard]] function attribute that effectively prevents this mistake by enforcing the usage of the return value. I wasn't able to find anything similar in Python, does it exist?

UPD A similar question: How to make pylint report unused return values

I've checked pylint and mypy, apparently neither of them catch this as of today.

UPD2 A pylint feature request: https://github.com/PyCQA/pylint/issues/7935

salmin
  • 457
  • 3
  • 12
  • 2
    you can use this, https://pylint.pycqa.org/en/latest/user_guide/messages/warning/expression-not-assigned.html, this is not something python would do natively – python_user Dec 13 '22 at 13:49
  • If you don't know *why* the result should be assigned back to the name `query`, such a feature won't necessarily help you. Say it did exist; you could satisfy it by writing `foo = query.filter(row.id = id)`, and your code would still not work for the same reasons. – chepner Dec 13 '22 at 13:57
  • 1
    @chepner In theory yes but on practice it does prevent like 90% of such mistakes or even more, it worked really well when I used in C++ libraries. The thing is, most of the times you DO know that you need the return value, it's just that you don't have a moment to stop and think about it. The error message would trigger exactly that. – salmin Dec 13 '22 at 14:19
  • In practice, someone that doesn't know that `query.filter(row.id = id)` is wrong isn't likely to know why `foo = ...` and `query = ...` are different. – chepner Dec 13 '22 at 14:21
  • 1
    @chepner You miss the point. People know it's wrong. If we're talking about the sqlalchemy example it's the most basic thing that you learn first. But it doesn't prevent this mistake from happening, it's something you can easily overlook. – salmin Dec 13 '22 at 14:31
  • That's not Python's problem to solve. – chepner Dec 13 '22 at 14:32
  • @python_user This is great, thanks for the link. Unfortunately it doesn't fix the query.filter() example because it specifically ignores the case of function calls. And it's reasonable because functions often have side-effects besides the return value, so some kind of function annotations are necessary to solve it. – salmin Dec 13 '22 at 14:35
  • 2
    @salmin my bad, I did not read that properly, but checking if a linter does this is your best bet at this point if you ask me – python_user Dec 13 '22 at 14:55

0 Answers0