Skip to main content

flake8 plugin which checks for code that can be simpified

Project description

PyPI version Code on Github Actions Status Code style: black

flake8-simplify

A flake8 plugin that helps you simplify your code.

Installation

Install with pip:

pip install flake8-simplify

Python 3.6 to 3.8 are supported.

Usage

Just call flake8 . in your package or flake your.py:

$ flake8 .
./foo/__init__.py:690:12: SIM101 Multiple isinstance-calls which can be merged into a single call for variable 'other'

Rules

  • SIM101: Multiple isinstance-calls which can be merged into a single call by using a tuple as a second argument (example)
  • SIM102: Use a single if-statement instead of nested if-statements (example)
  • SIM103: Return the boolean condition directly (example)
  • SIM104: Use 'yield from iterable' (introduced in Python 3.3, see PEP 380) (example)
  • SIM105: Use 'contextlib.suppress(...)' instead of try-except-pass (example)
  • SIM106: Handle error-cases first (example)
  • SIM107: Don't use return in try/except and finally (example)
  • SIM108: Use the ternary operator if it's reasonable (example)
  • SIM109: Use a list to compare a value against multiple values (example)
  • SIM110: Use any(...) (example)
  • SIM111: Use all(...) (example)
  • SIM112: Use CAPITAL environment variables (example)
  • SIM113: Use enumerate instead of manually incrementing a counter (example)
  • SIM114: Combine conditions via a logical or to prevent duplicating code (example)
  • SIM115: Use context handler for opening files (example)
  • SIM116: Use a dictionary instead of many if/else equality checks (example)
  • SIM117: Merge with-statements that use the same scope (example)
  • SIM201: Use 'a != b' instead of 'not a == b' (example)
  • SIM202: Use 'a == b' instead of 'not a != b' (example)
  • SIM203: Use 'a not in b' instead of 'not (a in b)' (example)
  • SIM204: Use 'a >= b' instead of 'not (a < b)' (example)
  • SIM205: Use 'a > b' instead of 'not (a <= b)' (example)
  • SIM206: Use 'a <= b' instead of 'not (a > b)' (example)
  • SIM207: Use 'a < b' instead of 'not (a <= b)' (example)
  • SIM208: Use 'a' instead of 'not (not a)' (example)
  • SIM210: Use 'bool(a)' instead of 'True if a else False' (example)
  • SIM211: Use 'not a' instead of 'False if a else True' (example)
  • SIM212: Use 'a if a else b' instead of 'b if not a else a' (example)
  • SIM220: Use 'False' instead of 'a and not a' (example)
  • SIM221: Use 'True' instead of 'a or not a' (example)
  • SIM222: Use 'True' instead of '... or True' (example)
  • SIM223: Use 'False' instead of '... and False' (example)
  • SIM300: Use 'age == 42' instead of '42 == age' (example)

The SIM201 - SIM208 rules have one good reason to be ignored: When you are checking an error condition:

if not correct_condition:
    handle_error()  # e.g. raise Exception

Examples

SIM101

# Bad
isinstance(a, int) or isinstance(a, float)

# Good
isinstance(a, (int, float))

SIM102

# Bad
if a:
    if b:
        c

# Good
if a and b:
    c

SIM107

# Bad: This example returns 3!
def foo():
    try:
        1 / 0
        return "1"
    except:
        return "2"
    finally:
        return "3"


# Good
def foo():
    return_value = None
    try:
        1 / 0
        return_value = "1"
    except:
        return_value = "2"
    finally:
        return_value = "3"  # you might also want to check if "except" happened
    return return_value

SIM108

# Bad
if a:
    b = c
else:
    b = d

# Good
b = c if a else d

SIM109

# Bad
if a == b or a == c:
    d

# Good
if a in [b, c]:
    d

SIM110

# Bad
for x in iterable:
    if check(x):
        return True
return False

# Good
return any(check(x) for x in iterable)

SIM111

# Bad
for x in iterable:
    if check(x):
        return False
return True

# Good
return all(check(x) for x in iterable)

SIM112

# Bad
os.environ["foo"]
os.environ.get("bar")

# Good
os.environ["FOO"]
os.environ.get("BAR")

SIM113

Using enumerate in simple cases like the loops below is a tiny bit easier to read as the reader does not have to figure out where / when the loop variable is incremented (or if it is incremented in multiple places).

# Bad
idx = 0
for el in iterable:
    ...
    idx += 1

# Good
for idx, el in enumerate(iterable):
    ...

SIM114

# Bad
if a:
    b
elif c:
    b

# Good
if a or c:
    b

SIM115

# Bad
f = open(...)
...  # (do something with f)
f.close()

# Good
with open(...) as f:
    ...  # (do something with f)

SIM116

# Bad
if a == "foo":
    return "bar"
elif a == "bar":
    return "baz"
elif a == "boo":
    return "ooh"
else:
    return 42

# Good
mapping = {"foo": "bar", "bar": "baz", "boo": "ooh"}
return mapping.get(a, 42)

SIM117

# Bad
with A() as a:
    with B() as b:
        print("hello")

# Good
with A() as a, B() as b:
    print("hello")

Thank you for pointing this one out, Aaron Gokaslan!

SIM201

# Bad
not a == b

# Good
a != b

SIM202

# Bad
not a != b

# Good
a == b

SIM203

# Bad
not a in b

# Good
a not in b

SIM204

# Bad
not a < b

# Good
a >= b

SIM205

# Bad
not a <= b

# Good
a > b

SIM206

# Bad
not a > b

# Good
a <= b

SIM207

# Bad
not a >= b

# Good
a < b

SIM208

# Bad
not (not a)

# Good
a

SIM210

# Bad
True if a else False

# Good
bool(a)

SIM211

# Bad
False if a else True

# Good
not a

SIM212

# Bad
b if not a else a

# Good
a if a else b

SIM220

# Bad
a and not a

# Good
False

SIM221

# Bad
a or not a

# Good
True

SIM222

# Bad
... or True

# Good
True

SIM223

# Bad
... and False

# Good
False

SIM300

# Bad; This is called a "Yoda-Condition"
42 == age

# Good
age == 42

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flake8_simplify-0.13.0.tar.gz (14.0 kB view hashes)

Uploaded Source

Built Distribution

flake8_simplify-0.13.0-py3-none-any.whl (13.1 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page