Changelog


← Back to all posts

December 06, 2021

New refactorings

Remove Redundant Slice Index

Sourcery refactoring id: remove-redundant-slice-index

Description:

Removes unnecessary explicit 0 when slicing the beginning of a sequence.

Before:

With an end index:

numbers[0:5]

Without an end index:

numbers[0:]

After:

With an end index:

numbers[:5]

Without an end index:

numbers[:]

Explanation:

The default starting value for a slice is 0, so it is unnecessary to explicitly define it. This refactoring removes such zeros, slightly shortening the code.

Remove Unused Enumerate

Sourcery refactoring id: remove-unused-enumerate

Description

Remove unnecessary calls to enumerate when the index variable is not used.

Before

for index, hat in enumerate(hats):
    print("I like this hat: ", hat)

for i, (key, value) in enumerate(my_dictionary.items(), start=100):
    do_something(key)
    do_something_else(value)

After

for hat in hats:
    print("I like this hat: ", hat)

for key, value in my_dictionary.items():
    do_something(key)
    do_something_else(value)

Explanation

Enumerating iterables with enumerate is a good practice for having access to both the values and their respective indices. However, when the indices are not necessary, it is cleaner to simply iterate over the original iterable and remove the call to enumerate.

Simplify String Length Comparison

Sourcery refactoring id: simplify-string-len-comparison

Description:

Changes an indirect comparison of a string's length to 0 into a direct comparison of the string to the empty string.

Before:

if len(s) == 0:
    ...

if len(r) > 0:
    ...

After:

if s == "":
    ...

if r != "":
    ...

Explanation:

This refactoring avoids an unnecessary calculation and keeps the logic in the domain of string types. It tends to unlock further improvements to string comparisons.

Useless Else on Loop

Sourcery refactoring id: useless-else-on-loop

Description:

Moves code in else blocks that is always executed to the main body

Before:

evens = []
for n in numbers:
    if n % 2:
        evens.append(n)
else:
    print("Done!")

After:

evens = []
for n in numbers:
    if n % 2:
        evens.append(n)
print("Done!")

Explanation:

Loops should only have an else clause if they can exit early with a break statement. If there is no break then the code in the else is always executed. In this case the else statements can be moved to the same scope as the loop itself, making the code slightly easier to understand (no need to look up what the else does).

Enhancements

  • If the Sourcery plugins are unable to contact our authentication server they will now fallback to our Free plan - this means that you can still use Sourcery in this case.
  • The simplify-len-comparison proposal has been extended to cover cases such as len(seq) != 0
  • The various comprehension proposals will now be suggested in more cases where there is a type annotation on the variable being

Bug fixes

  • Fixed issue where Sourcery would throw an exception if run with no internet connection.
  • Fix issue where remove-redundant-if was incorrectly suggested in situations with nested changes to condition variables
  • Fixed issue where use-any could be incorrectly suggested in cases where the for loop being replaced unpacked and used multiple variables