Full project refactoring, extract method refactoring
Extract Method Refactoring
Sourcery can now propose refactorings to extract blocks of code into new functions. This currently proposes in two circumstances:
- When finding duplicate and near duplicate blocks of code within a single function
- When finding a large block of code in the function that would be better off in it’s own function
This feature will be available in the upcoming Pro subscription.
Full project scan for refactorings
Select the project or a folder within a project in the IDE plugins, and then have Sourcery scan every file within it. All refactoring suggestions will be displayed as they are found in the Problems window.
This makes it easy to refactor a large portion of the codebase quickly without manually having to visit every file to see the Sourcery suggestions.
This feature will be available in the upcoming Pro subscription.
Improve project and module code metrics in Quality Report
Previously when aggregating metrics we simply calculated metrics for each function and then averaged them. This did not account for the differing size of functions - a 100 line function has more impact on quality than a 10 line one.
We now weight each metric (apart from method length) by the number of lines in each method when averaging them. This gives a better view of the actual file and project-level quality.
New Refactorings
Hoist code from else after guard clause: remove-else-after-guard
Hoist code from an else
after a guard clause. This will happen where the main
body of an if
contains only a raise or return statement, and there are
multiple statements in the else
.
def f(a=None):
if a is None:
return 42
else:
# some long statement
var = (i**2 for i in range(a))
return sum(var)
is converted into:
def f(a=None):
if a is None:
return 42
# some long statement
var = (i**2 for i in range(a))
return sum(var)
Inline variable that is immediately returned after if
Where a value is set on each branch of an if
and then immediately returned,
instead return it directly from each branch.
def f():
if condition:
val = 42
else:
val = 0
return val
is converted into:
def f():
if condition:
return 42
else:
return 0
Add Command Line Interface —backup option
Use with sourcery refactor --in-place
to backup changed files with given
suffix:
sourcery refactor --in-place --backup .bak main.py
If any refactorings are found in main.py
a copy will be made at main.py.bak
before it is updated in place.
Bug Fixes and other adjustments
- Only propose
for-index-replacement
for lists, as it’s possible__len__
and__getitem__
are implemented but__iter__
is not. - Minor changes to the
swap-if-else refactoring
. This will now also be triggered where it can enable the aboveremove-else-after-guard
refactoring. The description has also changed to reflect this. - Fix issue where block comments above a changed line stopped refactorings being suggested
- We now don’t convert an if/else to an if expression where the test contains a boolean operation. This prevents creation of hard-to-read if expression lines.
- Quality warnings in PyCharm Problems pane no longer show as raw HTML
- IDE Code metrics now have link to our documentation. We have added a title to the code metrics in the IDE with a link to our documentation. This will let you easily see how the metrics are calculated and how to improve your code.
- Fix formatting issue in Vim where a blank line was deleted after the refactored function