github dosisod/refurb v2.0.0
Release v2.0.0

2 months ago

This new release greatly improves the type checking capabilities of Refurb. You might find that you are getting a lot more errors in your projects, as well as a few false positives. Please report any incorrect changes you might find!

Add better type deduction

Refurb now makes better use of Mypy's type deduction system, allowing Refurb to find more errors and with better accuracy.

For example, the following is not detected in older versions of Refurb:

nums = [[]]

if len(nums[0]):
    print("nums[0] is not empty")

With this new version of Refurb, the type of nums[0] is inferred as a list:

$ refurb file.py
file.py:3:4 [FURB115]: Replace `len(nums[0])` with `nums[0]`

While this new type deduction is a great improvement on what existed before, there is still a lot of room for improvement. If you find any typing related bugs, please report it!

Add use-isinstance-bool check (FURB191)

Don't check if a value is True or False using in, use an isinstance() call.

Bad:

if value in {True, False}:
    pass

Good:

if isinstance(value, bool):
    pass

Add use-str-method check (FURB190)

Don't use a lambda function to call a no-arg method on a string, use the name of the string method directly. It is faster, and often times improves readability.

Bad:

def normalize_phone_number(phone_number: str) -> int:
    digits = filter(lambda x: x.isdigit(), phone_number)

    return int("".join(digits))

Good:

def normalize_phone_number(phone_number: str) -> int:
    digits = filter(str.isdigit, phone_number)

    return int("".join(digits))

Add no-subclass-builtin check (FURB189)

Note: this check is disabled by default, see below.

Subclassing dict, list, or str objects can be error prone, use the UserDict, UserList, and UserStr objects from the collections module instead.

Bad:

class CaseInsensitiveDict(dict):
    ...

Good:

from collections import UserDict

class CaseInsensitiveDict(UserDict):
    ...

Note: isinstance() checks for dict, list, and str types will fail when using the corresponding User class. If you need to pass custom dict or list objects to code you don't control, ignore this check. If you do control the code, consider using the following type checks instead:

  • dict -> collections.abc.MutableMapping
  • list -> collections.abc.MutableSequence
  • str -> No such conversion exists

Rename no-del to use-clear (FURB131)

Read dbe3126 for more info. In short, FURB131 will now detect both of the following snippets:

nums = [[1, 2, 3], [4, 5, 6]]

nums[0][:] = []
del nums[0][:]

Running Refurb:

$ refurb file.py
file.py:3:1 [FURB131]: Replace `nums[0][:] = []` with `nums[0].clear()`
file.py:4:1 [FURB131]: Replace `del nums[0][:]` with `nums[0].clear()`

What's Changed

  • Add no-subclass-builtin check by @dosisod in #324
  • Add better detection and error messages for len compatible types in FURB115 by @dosisod in #331

Full Changelog: v1.28.0...v2.0.0

Don't miss a new refurb release

NewReleases is sending notifications on new releases.