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.26k stars 1.12k forks source link

Spurious W3301: min(value, min(iterable)) does not do the same thing as min(value, iterable) #9923

Open zackw opened 2 weeks ago

zackw commented 2 weeks ago

Bug description

min(iterable) produces the minimum element of the iterable. min(value, value, ...) produces the minimum of all its arguments; it does not notice iterables among the values. Therefore min(value, min(iterable)) is a useful thing to do, but min(value, iterable) will typically throw a TypeError because int and list[int] (for instance) are not comparable. The same applies to max().

To sum up: The code below is the natural way to take the minimum/maximum of an iterable plus some other values, and it should not trigger any W3301 warnings.

#pylint:disable=missing-docstring
#pylint:enable=nested-min-max

def bounds(lo, hi, elements):
    return (
        min(lo, hi, min(elements)),
        max(lo, hi, max(elements)),
    )

Command used

pylint a.py

Pylint output

************* Module a
a.py:18:8: W3301: Do not use nested call of 'min'; it's possible to do 'min(lo, hi, elements)' instead (nested-min-max)
a.py:19:8: W3301: Do not use nested call of 'max'; it's possible to do 'max(lo, hi, elements)' instead (nested-min-max)

Expected behavior

Do not issue W3301 when the inner call(s) to min/max pass only one argument.

Pylint version

pylint 3.2.7
astroid 3.2.4
Python 3.8.19 (default, Sep  9 2024, 11:01:37)
[GCC 13.3.1 20240614]