pylint-dev / pylint

It's not just a linter that annoys you!
https://pylint.readthedocs.io/en/latest/
GNU General Public License v2.0
5.33k stars 1.14k forks source link

False positive: unneeded not #8890

Open clo-vis opened 1 year ago

clo-vis commented 1 year ago

Bug description

a = {1: 1}
b = {2: 2}
if not a.keys() < b.keys():
    print("!")

Configuration

No response

Command used

pylint a.py

Pylint output

************* Module a
a.py:3:3: C0113: Consider changing "not a.keys() < b.keys()" to "a.keys() >= b.keys()" (unneeded-not)

Expected behavior

No error message, as for sets (not A < B) is not the same as (B >= A).

Pylint version

pylint 2.17.4
astroid 2.15.6
Python 3.10.4

OS / Environment

No response

Additional dependencies

No response

nickdrozd commented 1 year ago

Flipping not < to >= is valid just when the relation is a total order -- when for any two distinct values a and b, either a < b or b > a. This is true for the < relation over int, and also over list (where < denotes lexicographic ordering).

But for sets, < denotes the subset relation, which is a partial order. So {1} < {2} and {1} > {2} are both false.

The warning should only trigger when the relation can be confirmed to be a total order (int, list, etc).

nickdrozd commented 1 year ago

Looks like the check does work correctly for sets, but not for dict_keys, which are not sets but are set-like.