tonybaloney / perflint

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

Constant expressions are incorrectly marked as invariant #25

Closed tonybaloney closed 2 years ago

tonybaloney commented 2 years ago
def constant_expressions():
    for i in range(10):
        _ = (0, 1, 2) # [loop-invariant]
        _ = [0, 1, 2] # [loop-invariant]
        _ = {"a": 1, "b": 2} # [loop-invariant]

Compiles to

  2           0 LOAD_CONST               1 ((0, 1, 2))
              2 STORE_FAST               0 (_)

  3           4 LOAD_CONST               2 (0)
              6 LOAD_CONST               3 (1)
              8 LOAD_CONST               4 (2)
             10 BUILD_LIST               3
             12 STORE_FAST               0 (_)

  4          14 LOAD_CONST               3 (1)
             16 LOAD_CONST               4 (2)
             18 LOAD_CONST               5 (('a', 'b'))
             20 BUILD_CONST_KEY_MAP      2
             22 STORE_FAST               0 (_)
             24 LOAD_CONST               0 (None)
             26 RETURN_VALUE
hughdbrown commented 2 years ago

Another one for you:

from collections import Counter

def main():
    target = 'crate'
    target_s = set(target)
    target_c = Counter(target)
    for word in ('trace', 'cater'):
        c = Counter(word)
        if (
            target_s.issuperset(word) and
            all(target_c[k] >= v for k, v in c.items())
        ):
            print(f'{target} {word}')

if __name__ == '__main__':
    main()

Gets these warnings:

❯ pylint --load-plugins perflint ../perlint-test.py
************* Module hughbrown.perlint-test
/Users/hughbrown/perlint-test.py:1:0: C0103: Module name "perlint-test" doesn't conform to snake_case naming style (invalid-name)
/Users/hughbrown/perlint-test.py:1:0: C0114: Missing module docstring (missing-module-docstring)
/Users/hughbrown/perlint-test.py:3:0: C0116: Missing function or method docstring (missing-function-docstring)
/Users/hughbrown/perlint-test.py:8:8: C0103: Variable name "c" doesn't conform to snake_case naming style (invalid-name)
/Users/hughbrown/perlint-test.py:11:16: W8201: Consider moving this expression outside of the loop. (loop-invariant-statement)
/Users/hughbrown/perlint-test.py:11:16: W8201: Consider moving this expression outside of the loop. (loop-invariant-statement)
/Users/hughbrown/perlint-test.py:11:16: W8201: Consider moving this expression outside of the loop. (loop-invariant-statement)

Especially note line 11 where there is no invariant to hoist.

Also, it would be nice if the message identified which message is thought to be invariant.