flake8-simplify


Nameflake8-simplify JSON
Version 0.19.3 PyPI version JSON
download
home_pagehttps://github.com/MartinThoma/flake8-simplify
Summaryflake8 plugin which checks for code that can be simplified
upload_time2022-07-28 16:32:36
maintainerMartin Thoma
docs_urlNone
authorMartin Thoma
requires_python>=3.6.1
licenseMIT
keywords flake8
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            [![PyPI version](https://badge.fury.io/py/flake8-simplify.svg)](https://badge.fury.io/py/flake8-simplify)
[![Code on Github](https://img.shields.io/badge/Code-GitHub-brightgreen)](https://github.com/MartinThoma/flake8-simplify)
[![Actions Status](https://github.com/MartinThoma/flake8-simplify/workflows/Unit%20Tests/badge.svg)](https://github.com/MartinThoma/flake8-simplify/actions)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

# flake8-simplify

A [flake8](https://flake8.pycqa.org/en/latest/index.html) plugin that helps you simplify your code.

## Installation

Install with `pip`:

```bash
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

Python-specific rules:

* `SIM101`: Multiple isinstance-calls which can be merged into a single call by
  using a tuple as a second argument ([example](#SIM101))
* [`SIM104`](https://github.com/MartinThoma/flake8-simplify/issues/4) ![](https://shields.io/badge/-legacyfix-inactive): Use 'yield from iterable' (introduced in Python 3.3, see [PEP 380](https://docs.python.org/3/whatsnew/3.3.html#pep-380)) ([example](#SIM104))
* [`SIM105`](https://github.com/MartinThoma/flake8-simplify/issues/5): Use ['contextlib.suppress(...)'](https://docs.python.org/3/library/contextlib.html#contextlib.suppress) instead of try-except-pass ([example](#SIM105))
* [`SIM107`](https://github.com/MartinThoma/flake8-simplify/issues/9): Don't use `return` in try/except and finally  ([example](#SIM107))
* [`SIM108`](https://github.com/MartinThoma/flake8-simplify/issues/12): Use the ternary operator if it's reasonable  ([example](#SIM108))
* [`SIM109`](https://github.com/MartinThoma/flake8-simplify/issues/11): Use a tuple to compare a value against multiple values ([example](#SIM109))
* [`SIM110`](https://github.com/MartinThoma/flake8-simplify/issues/15): Use [any(...)](https://docs.python.org/3/library/functions.html#any)  ([example](#SIM110))
* [`SIM111`](https://github.com/MartinThoma/flake8-simplify/issues/15): Use [all(...)](https://docs.python.org/3/library/functions.html#all) ([example](#SIM111))
* [`SIM113`](https://github.com/MartinThoma/flake8-simplify/issues/18): Use enumerate instead of manually incrementing a counter ([example](#SIM113))
* [`SIM114`](https://github.com/MartinThoma/flake8-simplify/issues/10): Combine conditions via a logical or to prevent duplicating code ([example](#SIM114))
* [`SIM115`](https://github.com/MartinThoma/flake8-simplify/issues/17): Use context handler for opening files ([example](#SIM115))
* [`SIM116`](https://github.com/MartinThoma/flake8-simplify/issues/31): Use a dictionary instead of many if/else equality checks ([example](#SIM116))
* [`SIM117`](https://github.com/MartinThoma/flake8-simplify/issues/35): Merge with-statements that use the same scope ([example](#SIM117))
* `SIM119`: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 63](https://github.com/MartinThoma/flake8-simplify/issues/63)
* `SIM120` ![](https://shields.io/badge/-legacyfix-inactive): Use 'class FooBar:' instead of 'class FooBar(object):' ([example](#SIM120))
* `SIM121`: Reserved for [SIM908](#sim908) once it's stable
* `SIM125`: Reserved for [SIM905](#sim905) once it's stable
* `SIM126`: Reserved for [SIM906](#sim906) once it's stable
* `SIM127`: Reserved for [SIM907](#sim907) once it's stable

Simplifying Comparisons:

* `SIM201`: Use 'a != b' instead of 'not a == b' ([example](#SIM201))
* `SIM202`: Use 'a == b' instead of 'not a != b' ([example](#SIM202))
* `SIM203`: Use 'a not in b' instead of 'not (a in b)' ([example](#SIM203))
* `SIM204`: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 116](https://github.com/MartinThoma/flake8-simplify/issues/116)
* `SIM205`: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 116](https://github.com/MartinThoma/flake8-simplify/issues/116)
* `SIM206`: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 116](https://github.com/MartinThoma/flake8-simplify/issues/116)
* `SIM207`: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 116](https://github.com/MartinThoma/flake8-simplify/issues/116)
* `SIM208`: Use 'a' instead of 'not (not a)' ([example](#SIM208))
* `SIM210`: Use 'bool(a)' instead of 'True if a else False' ([example](#SIM210))
* `SIM211`: Use 'not a' instead of 'False if a else True' ([example](#SIM211))
* [`SIM212`](https://github.com/MartinThoma/flake8-simplify/issues/6): Use 'a if a else b' instead of 'b if not a else a' ([example](#SIM212))
* [`SIM220`](https://github.com/MartinThoma/flake8-simplify/issues/6): Use 'False' instead of 'a and not a' ([example](#SIM220))
* [`SIM221`](https://github.com/MartinThoma/flake8-simplify/issues/6): Use 'True' instead of 'a or not a' ([example](#SIM221))
* [`SIM222`](https://github.com/MartinThoma/flake8-simplify/issues/6): Use 'True' instead of '... or True' ([example](#SIM222))
* [`SIM223`](https://github.com/MartinThoma/flake8-simplify/issues/6): Use 'False' instead of '... and False' ([example](#SIM223))
* [`SIM224`](https://github.com/MartinThoma/flake8-simplify/issues/88): Reserved for [SIM901](#sim901) once it's stable
* [`SIM300`](https://github.com/MartinThoma/flake8-simplify/issues/16): Use 'age == 42' instead of '42 == age' ([example](#SIM300))

Simplifying usage of dictionaries:

* [`SIM401`](https://github.com/MartinThoma/flake8-simplify/issues/72): Use 'a_dict.get(key, "default_value")' instead of an if-block ([example](#SIM401))
* [`SIM118`](https://github.com/MartinThoma/flake8-simplify/issues/40): Use 'key in dict' instead of 'key in dict.keys()' ([example](#SIM118))

General Code Style:

* `SIM102`: Use a single if-statement instead of nested if-statements ([example](#SIM102))
* [`SIM103`](https://github.com/MartinThoma/flake8-simplify/issues/3): Return the boolean condition directly ([example](#SIM103))
* [`SIM106`](https://github.com/MartinThoma/flake8-simplify/issues/8): Handle error-cases first ([example](#SIM106)). This rule was removed due to too many false-positives.
* [`SIM112`](https://github.com/MartinThoma/flake8-simplify/issues/19): Use CAPITAL environment variables ([example](#SIM112))
* `SIM122` / SIM902: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 125](https://github.com/MartinThoma/flake8-simplify/issues/125)
* `SIM123` / SIM902: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 130](https://github.com/MartinThoma/flake8-simplify/issues/130)
* `SIM124`: Reserved for SIM909 once it's stable

**Experimental rules:**

Getting rules right for every possible case is hard. I don't want to disturb
peoples workflows. For this reason, flake8-simplify introduces new rules with
the `SIM9` prefix. Every new rule will start with SIM9 and stay there for at
least 6 months. In this time people can give feedback. Once the rule is stable,
the code will change to another number.

Current experimental rules:

* `SIM901`: Use comparisons directly instead of wrapping them in a `bool(...)` call ([example](#SIM901))
* `SIM904`: Assign values to dictionary directly at initialization ([example](#SIM904))
* [`SIM905`](https://github.com/MartinThoma/flake8-simplify/issues/86): Split string directly if only constants are used ([example](#SIM905))
* [`SIM906`](https://github.com/MartinThoma/flake8-simplify/issues/101): Merge nested os.path.join calls ([example](#SIM906))
* [`SIM907`](https://github.com/MartinThoma/flake8-simplify/issues/64): Use Optional[Type] instead of Union[Type, None] ([example](#SIM907))
* [`SIM908`](https://github.com/MartinThoma/flake8-simplify/issues/50): Use dict.get(key) ([example](#SIM908))
* [`SIM909`](https://github.com/MartinThoma/flake8-simplify/issues/114): Avoid reflexive assignments ([example](#SIM909))

## Disabling Rules

You might have good reasons to
[ignore some flake8 rules](https://flake8.pycqa.org/en/3.1.1/user/ignoring-errors.html).
To do that, use the standard Flake8 configuration. For example, within the `setup.cfg` file:

```python
[flake8]
ignore = SIM106, SIM113, SIM119, SIM9
```


## Examples

### SIM101

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

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

### SIM102

```python
# Bad
if a:
    if b:
        c

# Good
if a and b:
    c
```

### SIM105

```python
# Bad
try:
    foo()
except ValueError:
    pass

# Good
from contextlib import suppress

with suppress(ValueError):
    foo()
```

Please note that `contextlib.suppress` is roughly 3x slower than `try/except`
([source](https://github.com/MartinThoma/flake8-simplify/issues/91)).

### SIM107

```python
# 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

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

# Good
b = c if a else d
```

### SIM109

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

# Good
if a in (b, c):
    d
```

### SIM110

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

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

### SIM111

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

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

### SIM112

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

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

### SIM113

Using [`enumerate`](https://docs.python.org/3/library/functions.html#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).

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

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

### SIM114

```python
# Bad
if a:
    b
elif c:
    b

# Good
if a or c:
    b
```

### SIM115

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

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

### SIM116

```python
# 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

```python
# 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](https://github.com/Skylion007)!

### SIM118

```python
# Bad
key in a_dict.keys()

# Good
key in a_dict
```

Thank you for pointing this one out, [Aaron Gokaslan](https://github.com/Skylion007)!


### SIM120

```python
# Bad
class FooBar(object):
    ...


# Good
class FooBar:
    ...
```

Both notations are equivalent in Python 3, but the second one is shorter.


### SIM201

```python
# Bad
not a == b

# Good
a != b
```

### SIM202

```python
# Bad
not a != b

# Good
a == b
```

### SIM203

```python
# Bad
not a in b

# Good
a not in b
```


### SIM208

```python
# Bad
not (not a)

# Good
a
```

### SIM210

```python
# Bad
True if a else False

# Good
bool(a)
```

### SIM211

```python
# Bad
False if a else True

# Good
not a
```

### SIM212

```python
# Bad
b if not a else a

# Good
a if a else b
```

### SIM220

```python
# Bad
a and not a

# Good
False
```

### SIM221

```python
# Bad
a or not a

# Good
True
```

### SIM222

```python
# Bad
... or True

# Good
True
```

### SIM223

```python
# Bad
... and False

# Good
False
```

### SIM300

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

# Good
age == 42
```

### SIM401

```python
# Bad
if key in a_dict:
    value = a_dict[key]
else:
    value = "default_value"

# Good
thing = a_dict.get(key, "default_value")
```

### SIM901

This rule will be renamed to `SIM224` after its 6-month trial period is over.
Please report any issues you encounter with this rule!

The trial period starts on 23rd of January and will end on 23rd of August 2022.

```python
# Bad
bool(a == b)

# Good
a == b
```


### SIM904

This rule will be renamed to `SIM224` after its 6-month trial period is over.
Please report any issues you encounter with this rule!

The trial period starts on 12th of February and will end on 12th of September 2022.


```python
# Bad
a = {}
a["b"] = "c"

# Good
a = {"b": "c"}
```

### SIM905

This rule will be renamed to `SIM225` after its 6-month trial period is over.
Please report any issues you encounter with this rule!

The trial period starts on 13th of February and will end on 13th of September 2022.

```python
# Bad
domains = "de com net org".split()

# Good
domains = ["de", "com", "net", "org"]
```

### SIM906

This rule will be renamed to `SIM126` after its 6-month trial period is over.
Please report any issues you encounter with this rule!

The trial period starts on 20th of February and will end on 20th of September 2022.

```python
# Bad
os.path.join(a, os.path.join(b, c))

# Good
os.path.join(a, b, c)
```

### SIM907

This rule will be renamed to `SIM127` after its 6-month trial period is over.
Please report any issues you encounter with this rule!

The trial period starts on 28th of March and will end on 28th of September 2022.

```python
# Bad
def foo(a: Union[int, None]) -> Union[int, None]:
    return a


# Good
def foo(a: Optional[int]) -> Optional[int]:
    return a
```

### SIM908

This rule will be renamed to `SIM121` after its 6-month trial period is over.
Please report any issues you encounter with this rule!

The trial period starts on 28th of March and will end on 28th of September 2022.

```python
# Bad
name = "some_default"
if "some_key" in some_dict:
    name = some_dict["some_key"]

# Good
name = some_dict.get("some_key", "some_default")
```

### SIM909

Thank you Ryan Delaney for the idea!

This rule will be renamed to `SIM124` after its 6-month trial period is over.
Please report any issues you encounter with this rule!

The trial period starts on 28th of March and will end on 28th of September 2022.

```python
# Bad
foo = foo

# Good: Nothing. Reflexive assignments have no purpose.
```

or

```python
# Bad
foo = foo = 42

# Good
foo = 42
```



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/MartinThoma/flake8-simplify",
    "name": "flake8-simplify",
    "maintainer": "Martin Thoma",
    "docs_url": null,
    "requires_python": ">=3.6.1",
    "maintainer_email": "info@martin-thoma.de",
    "keywords": "flake8",
    "author": "Martin Thoma",
    "author_email": "info@martin-thoma.de",
    "download_url": "https://files.pythonhosted.org/packages/4f/ac/f48f7df445a8706ba2b34014dcb58a1d4f7f10e2f6126094c6069627bcfb/flake8_simplify-0.19.3.tar.gz",
    "platform": null,
    "description": "[![PyPI version](https://badge.fury.io/py/flake8-simplify.svg)](https://badge.fury.io/py/flake8-simplify)\n[![Code on Github](https://img.shields.io/badge/Code-GitHub-brightgreen)](https://github.com/MartinThoma/flake8-simplify)\n[![Actions Status](https://github.com/MartinThoma/flake8-simplify/workflows/Unit%20Tests/badge.svg)](https://github.com/MartinThoma/flake8-simplify/actions)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\n# flake8-simplify\n\nA [flake8](https://flake8.pycqa.org/en/latest/index.html) plugin that helps you simplify your code.\n\n## Installation\n\nInstall with `pip`:\n\n```bash\npip install flake8-simplify\n```\n\nPython 3.6 to 3.8 are supported.\n\n\n## Usage\n\nJust call `flake8 .` in your package or `flake your.py`:\n\n```\n$ flake8 .\n./foo/__init__.py:690:12: SIM101 Multiple isinstance-calls which can be merged into a single call for variable 'other'\n```\n\n\n## Rules\n\nPython-specific rules:\n\n* `SIM101`: Multiple isinstance-calls which can be merged into a single call by\n  using a tuple as a second argument ([example](#SIM101))\n* [`SIM104`](https://github.com/MartinThoma/flake8-simplify/issues/4) ![](https://shields.io/badge/-legacyfix-inactive): Use 'yield from iterable' (introduced in Python 3.3, see [PEP 380](https://docs.python.org/3/whatsnew/3.3.html#pep-380)) ([example](#SIM104))\n* [`SIM105`](https://github.com/MartinThoma/flake8-simplify/issues/5): Use ['contextlib.suppress(...)'](https://docs.python.org/3/library/contextlib.html#contextlib.suppress) instead of try-except-pass ([example](#SIM105))\n* [`SIM107`](https://github.com/MartinThoma/flake8-simplify/issues/9): Don't use `return` in try/except and finally  ([example](#SIM107))\n* [`SIM108`](https://github.com/MartinThoma/flake8-simplify/issues/12): Use the ternary operator if it's reasonable  ([example](#SIM108))\n* [`SIM109`](https://github.com/MartinThoma/flake8-simplify/issues/11): Use a tuple to compare a value against multiple values ([example](#SIM109))\n* [`SIM110`](https://github.com/MartinThoma/flake8-simplify/issues/15): Use [any(...)](https://docs.python.org/3/library/functions.html#any)  ([example](#SIM110))\n* [`SIM111`](https://github.com/MartinThoma/flake8-simplify/issues/15): Use [all(...)](https://docs.python.org/3/library/functions.html#all) ([example](#SIM111))\n* [`SIM113`](https://github.com/MartinThoma/flake8-simplify/issues/18): Use enumerate instead of manually incrementing a counter ([example](#SIM113))\n* [`SIM114`](https://github.com/MartinThoma/flake8-simplify/issues/10): Combine conditions via a logical or to prevent duplicating code ([example](#SIM114))\n* [`SIM115`](https://github.com/MartinThoma/flake8-simplify/issues/17): Use context handler for opening files ([example](#SIM115))\n* [`SIM116`](https://github.com/MartinThoma/flake8-simplify/issues/31): Use a dictionary instead of many if/else equality checks ([example](#SIM116))\n* [`SIM117`](https://github.com/MartinThoma/flake8-simplify/issues/35): Merge with-statements that use the same scope ([example](#SIM117))\n* `SIM119`: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 63](https://github.com/MartinThoma/flake8-simplify/issues/63)\n* `SIM120` ![](https://shields.io/badge/-legacyfix-inactive): Use 'class FooBar:' instead of 'class FooBar(object):' ([example](#SIM120))\n* `SIM121`: Reserved for [SIM908](#sim908) once it's stable\n* `SIM125`: Reserved for [SIM905](#sim905) once it's stable\n* `SIM126`: Reserved for [SIM906](#sim906) once it's stable\n* `SIM127`: Reserved for [SIM907](#sim907) once it's stable\n\nSimplifying Comparisons:\n\n* `SIM201`: Use 'a != b' instead of 'not a == b' ([example](#SIM201))\n* `SIM202`: Use 'a == b' instead of 'not a != b' ([example](#SIM202))\n* `SIM203`: Use 'a not in b' instead of 'not (a in b)' ([example](#SIM203))\n* `SIM204`: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 116](https://github.com/MartinThoma/flake8-simplify/issues/116)\n* `SIM205`: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 116](https://github.com/MartinThoma/flake8-simplify/issues/116)\n* `SIM206`: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 116](https://github.com/MartinThoma/flake8-simplify/issues/116)\n* `SIM207`: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 116](https://github.com/MartinThoma/flake8-simplify/issues/116)\n* `SIM208`: Use 'a' instead of 'not (not a)' ([example](#SIM208))\n* `SIM210`: Use 'bool(a)' instead of 'True if a else False' ([example](#SIM210))\n* `SIM211`: Use 'not a' instead of 'False if a else True' ([example](#SIM211))\n* [`SIM212`](https://github.com/MartinThoma/flake8-simplify/issues/6): Use 'a if a else b' instead of 'b if not a else a' ([example](#SIM212))\n* [`SIM220`](https://github.com/MartinThoma/flake8-simplify/issues/6): Use 'False' instead of 'a and not a' ([example](#SIM220))\n* [`SIM221`](https://github.com/MartinThoma/flake8-simplify/issues/6): Use 'True' instead of 'a or not a' ([example](#SIM221))\n* [`SIM222`](https://github.com/MartinThoma/flake8-simplify/issues/6): Use 'True' instead of '... or True' ([example](#SIM222))\n* [`SIM223`](https://github.com/MartinThoma/flake8-simplify/issues/6): Use 'False' instead of '... and False' ([example](#SIM223))\n* [`SIM224`](https://github.com/MartinThoma/flake8-simplify/issues/88): Reserved for [SIM901](#sim901) once it's stable\n* [`SIM300`](https://github.com/MartinThoma/flake8-simplify/issues/16): Use 'age == 42' instead of '42 == age' ([example](#SIM300))\n\nSimplifying usage of dictionaries:\n\n* [`SIM401`](https://github.com/MartinThoma/flake8-simplify/issues/72): Use 'a_dict.get(key, \"default_value\")' instead of an if-block ([example](#SIM401))\n* [`SIM118`](https://github.com/MartinThoma/flake8-simplify/issues/40): Use 'key in dict' instead of 'key in dict.keys()' ([example](#SIM118))\n\nGeneral Code Style:\n\n* `SIM102`: Use a single if-statement instead of nested if-statements ([example](#SIM102))\n* [`SIM103`](https://github.com/MartinThoma/flake8-simplify/issues/3): Return the boolean condition directly ([example](#SIM103))\n* [`SIM106`](https://github.com/MartinThoma/flake8-simplify/issues/8): Handle error-cases first ([example](#SIM106)). This rule was removed due to too many false-positives.\n* [`SIM112`](https://github.com/MartinThoma/flake8-simplify/issues/19): Use CAPITAL environment variables ([example](#SIM112))\n* `SIM122` / SIM902: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 125](https://github.com/MartinThoma/flake8-simplify/issues/125)\n* `SIM123` / SIM902: ![](https://img.shields.io/badge/-removed-lightgrey) Moved to [flake8-scream](https://github.com/MartinThoma/flake8-scream) due to [issue 130](https://github.com/MartinThoma/flake8-simplify/issues/130)\n* `SIM124`: Reserved for SIM909 once it's stable\n\n**Experimental rules:**\n\nGetting rules right for every possible case is hard. I don't want to disturb\npeoples workflows. For this reason, flake8-simplify introduces new rules with\nthe `SIM9` prefix. Every new rule will start with SIM9 and stay there for at\nleast 6 months. In this time people can give feedback. Once the rule is stable,\nthe code will change to another number.\n\nCurrent experimental rules:\n\n* `SIM901`: Use comparisons directly instead of wrapping them in a `bool(...)` call ([example](#SIM901))\n* `SIM904`: Assign values to dictionary directly at initialization ([example](#SIM904))\n* [`SIM905`](https://github.com/MartinThoma/flake8-simplify/issues/86): Split string directly if only constants are used ([example](#SIM905))\n* [`SIM906`](https://github.com/MartinThoma/flake8-simplify/issues/101): Merge nested os.path.join calls ([example](#SIM906))\n* [`SIM907`](https://github.com/MartinThoma/flake8-simplify/issues/64): Use Optional[Type] instead of Union[Type, None] ([example](#SIM907))\n* [`SIM908`](https://github.com/MartinThoma/flake8-simplify/issues/50): Use dict.get(key) ([example](#SIM908))\n* [`SIM909`](https://github.com/MartinThoma/flake8-simplify/issues/114): Avoid reflexive assignments ([example](#SIM909))\n\n## Disabling Rules\n\nYou might have good reasons to\n[ignore some flake8 rules](https://flake8.pycqa.org/en/3.1.1/user/ignoring-errors.html).\nTo do that, use the standard Flake8 configuration. For example, within the `setup.cfg` file:\n\n```python\n[flake8]\nignore = SIM106, SIM113, SIM119, SIM9\n```\n\n\n## Examples\n\n### SIM101\n\n```python\n# Bad\nisinstance(a, int) or isinstance(a, float)\n\n# Good\nisinstance(a, (int, float))\n```\n\n### SIM102\n\n```python\n# Bad\nif a:\n    if b:\n        c\n\n# Good\nif a and b:\n    c\n```\n\n### SIM105\n\n```python\n# Bad\ntry:\n    foo()\nexcept ValueError:\n    pass\n\n# Good\nfrom contextlib import suppress\n\nwith suppress(ValueError):\n    foo()\n```\n\nPlease note that `contextlib.suppress` is roughly 3x slower than `try/except`\n([source](https://github.com/MartinThoma/flake8-simplify/issues/91)).\n\n### SIM107\n\n```python\n# Bad: This example returns 3!\ndef foo():\n    try:\n        1 / 0\n        return \"1\"\n    except:\n        return \"2\"\n    finally:\n        return \"3\"\n\n\n# Good\ndef foo():\n    return_value = None\n    try:\n        1 / 0\n        return_value = \"1\"\n    except:\n        return_value = \"2\"\n    finally:\n        return_value = \"3\"  # you might also want to check if \"except\" happened\n    return return_value\n```\n\n### SIM108\n\n```python\n# Bad\nif a:\n    b = c\nelse:\n    b = d\n\n# Good\nb = c if a else d\n```\n\n### SIM109\n\n```python\n# Bad\nif a == b or a == c:\n    d\n\n# Good\nif a in (b, c):\n    d\n```\n\n### SIM110\n\n```python\n# Bad\nfor x in iterable:\n    if check(x):\n        return True\nreturn False\n\n# Good\nreturn any(check(x) for x in iterable)\n```\n\n### SIM111\n\n```python\n# Bad\nfor x in iterable:\n    if check(x):\n        return False\nreturn True\n\n# Good\nreturn all(not check(x) for x in iterable)\n```\n\n### SIM112\n\n```python\n# Bad\nos.environ[\"foo\"]\nos.environ.get(\"bar\")\n\n# Good\nos.environ[\"FOO\"]\nos.environ.get(\"BAR\")\n```\n\n### SIM113\n\nUsing [`enumerate`](https://docs.python.org/3/library/functions.html#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).\n\n```python\n# Bad\nidx = 0\nfor el in iterable:\n    ...\n    idx += 1\n\n# Good\nfor idx, el in enumerate(iterable):\n    ...\n```\n\n### SIM114\n\n```python\n# Bad\nif a:\n    b\nelif c:\n    b\n\n# Good\nif a or c:\n    b\n```\n\n### SIM115\n\n```python\n# Bad\nf = open(...)\n...  # (do something with f)\nf.close()\n\n# Good\nwith open(...) as f:\n    ...  # (do something with f)\n```\n\n### SIM116\n\n```python\n# Bad\nif a == \"foo\":\n    return \"bar\"\nelif a == \"bar\":\n    return \"baz\"\nelif a == \"boo\":\n    return \"ooh\"\nelse:\n    return 42\n\n# Good\nmapping = {\"foo\": \"bar\", \"bar\": \"baz\", \"boo\": \"ooh\"}\nreturn mapping.get(a, 42)\n```\n\n### SIM117\n\n```python\n# Bad\nwith A() as a:\n    with B() as b:\n        print(\"hello\")\n\n# Good\nwith A() as a, B() as b:\n    print(\"hello\")\n```\n\nThank you for pointing this one out, [Aaron Gokaslan](https://github.com/Skylion007)!\n\n### SIM118\n\n```python\n# Bad\nkey in a_dict.keys()\n\n# Good\nkey in a_dict\n```\n\nThank you for pointing this one out, [Aaron Gokaslan](https://github.com/Skylion007)!\n\n\n### SIM120\n\n```python\n# Bad\nclass FooBar(object):\n    ...\n\n\n# Good\nclass FooBar:\n    ...\n```\n\nBoth notations are equivalent in Python 3, but the second one is shorter.\n\n\n### SIM201\n\n```python\n# Bad\nnot a == b\n\n# Good\na != b\n```\n\n### SIM202\n\n```python\n# Bad\nnot a != b\n\n# Good\na == b\n```\n\n### SIM203\n\n```python\n# Bad\nnot a in b\n\n# Good\na not in b\n```\n\n\n### SIM208\n\n```python\n# Bad\nnot (not a)\n\n# Good\na\n```\n\n### SIM210\n\n```python\n# Bad\nTrue if a else False\n\n# Good\nbool(a)\n```\n\n### SIM211\n\n```python\n# Bad\nFalse if a else True\n\n# Good\nnot a\n```\n\n### SIM212\n\n```python\n# Bad\nb if not a else a\n\n# Good\na if a else b\n```\n\n### SIM220\n\n```python\n# Bad\na and not a\n\n# Good\nFalse\n```\n\n### SIM221\n\n```python\n# Bad\na or not a\n\n# Good\nTrue\n```\n\n### SIM222\n\n```python\n# Bad\n... or True\n\n# Good\nTrue\n```\n\n### SIM223\n\n```python\n# Bad\n... and False\n\n# Good\nFalse\n```\n\n### SIM300\n\n```python\n# Bad; This is called a \"Yoda-Condition\"\n42 == age\n\n# Good\nage == 42\n```\n\n### SIM401\n\n```python\n# Bad\nif key in a_dict:\n    value = a_dict[key]\nelse:\n    value = \"default_value\"\n\n# Good\nthing = a_dict.get(key, \"default_value\")\n```\n\n### SIM901\n\nThis rule will be renamed to `SIM224` after its 6-month trial period is over.\nPlease report any issues you encounter with this rule!\n\nThe trial period starts on 23rd of January and will end on 23rd of August 2022.\n\n```python\n# Bad\nbool(a == b)\n\n# Good\na == b\n```\n\n\n### SIM904\n\nThis rule will be renamed to `SIM224` after its 6-month trial period is over.\nPlease report any issues you encounter with this rule!\n\nThe trial period starts on 12th of February and will end on 12th of September 2022.\n\n\n```python\n# Bad\na = {}\na[\"b\"] = \"c\"\n\n# Good\na = {\"b\": \"c\"}\n```\n\n### SIM905\n\nThis rule will be renamed to `SIM225` after its 6-month trial period is over.\nPlease report any issues you encounter with this rule!\n\nThe trial period starts on 13th of February and will end on 13th of September 2022.\n\n```python\n# Bad\ndomains = \"de com net org\".split()\n\n# Good\ndomains = [\"de\", \"com\", \"net\", \"org\"]\n```\n\n### SIM906\n\nThis rule will be renamed to `SIM126` after its 6-month trial period is over.\nPlease report any issues you encounter with this rule!\n\nThe trial period starts on 20th of February and will end on 20th of September 2022.\n\n```python\n# Bad\nos.path.join(a, os.path.join(b, c))\n\n# Good\nos.path.join(a, b, c)\n```\n\n### SIM907\n\nThis rule will be renamed to `SIM127` after its 6-month trial period is over.\nPlease report any issues you encounter with this rule!\n\nThe trial period starts on 28th of March and will end on 28th of September 2022.\n\n```python\n# Bad\ndef foo(a: Union[int, None]) -> Union[int, None]:\n    return a\n\n\n# Good\ndef foo(a: Optional[int]) -> Optional[int]:\n    return a\n```\n\n### SIM908\n\nThis rule will be renamed to `SIM121` after its 6-month trial period is over.\nPlease report any issues you encounter with this rule!\n\nThe trial period starts on 28th of March and will end on 28th of September 2022.\n\n```python\n# Bad\nname = \"some_default\"\nif \"some_key\" in some_dict:\n    name = some_dict[\"some_key\"]\n\n# Good\nname = some_dict.get(\"some_key\", \"some_default\")\n```\n\n### SIM909\n\nThank you Ryan Delaney for the idea!\n\nThis rule will be renamed to `SIM124` after its 6-month trial period is over.\nPlease report any issues you encounter with this rule!\n\nThe trial period starts on 28th of March and will end on 28th of September 2022.\n\n```python\n# Bad\nfoo = foo\n\n# Good: Nothing. Reflexive assignments have no purpose.\n```\n\nor\n\n```python\n# Bad\nfoo = foo = 42\n\n# Good\nfoo = 42\n```\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "flake8 plugin which checks for code that can be simplified",
    "version": "0.19.3",
    "split_keywords": [
        "flake8"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "md5": "b70413c9df5c20179060a5fc034df245",
                "sha256": "1057320e9312d75849541fee822900d27bcad05b2405edc84713affee635629e"
            },
            "downloads": -1,
            "filename": "flake8_simplify-0.19.3-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "b70413c9df5c20179060a5fc034df245",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6.1",
            "size": 26512,
            "upload_time": "2022-07-28T16:32:34",
            "upload_time_iso_8601": "2022-07-28T16:32:34.948924Z",
            "url": "https://files.pythonhosted.org/packages/30/3f/7ec818e7404edbda0d86c918de6022725d2ebfa4382e3e2bdb85236e772e/flake8_simplify-0.19.3-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "md5": "a48442bc12200327354ae025520d7b1f",
                "sha256": "2fb083bf5142a98d9c9554755cf2f56f8926eb4a33eae30c0809041b1546879e"
            },
            "downloads": -1,
            "filename": "flake8_simplify-0.19.3.tar.gz",
            "has_sig": false,
            "md5_digest": "a48442bc12200327354ae025520d7b1f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6.1",
            "size": 24496,
            "upload_time": "2022-07-28T16:32:36",
            "upload_time_iso_8601": "2022-07-28T16:32:36.762088Z",
            "url": "https://files.pythonhosted.org/packages/4f/ac/f48f7df445a8706ba2b34014dcb58a1d4f7f10e2f6126094c6069627bcfb/flake8_simplify-0.19.3.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2022-07-28 16:32:36",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "MartinThoma",
    "github_project": "flake8-simplify",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "tox": true,
    "lcname": "flake8-simplify"
}
        
Elapsed time: 0.28381s