tonybaloney / perflint

Python Linter for performance anti patterns
MIT License
663 stars 10 forks source link

invalid loop-invariant-statement detected #39

Open tauferp opened 1 year ago

tauferp commented 1 year ago

Following sample yields incorrect loop-invariant-statement

def test():
    dicts = ({'1': 'a', '2': 'b'}, {'3': 'c'})
    for d in dicts:
        print({int(k): v for k, v in d.items()})

sample.py:4:15: W8201: Consider moving this expression outside of the loop. (loop-invariant-statement)

FBruzzesi commented 1 year ago

I recently found another case where W8201 is a false positive.

A minimal reproducible example:

x, y = 1, 2
for t in range(2):
    if t % 2:
        a, b = x, y
    else:
        a, b = 2, 2
    # logic involving `a` and `b`
jenstroeger commented 9 months ago

And another case:

def test():
    d = {'key': 'some value here'}
    o = object()

    for key, value in d.items():
        if key == 'foo':
            s1, *_ = value.split(' ')
            a = getattr(o, s1)  # W8201: Consider moving this expression outside of the loop. (loop-invariant-statement)
            return a

It looks like a = getattr(o, s1) is independent of the loop variables key and value, but s1value.split(' ') depends on a loop variable and therefore isn’t invariant.