Changelog

New updates and improvements to Sourcery


Sourcery CLI

Sourcery CLI

Sourcery is now available as a command line interface. This enables several new use cases:

  • Refactor files on your machine without needing to run Sourcery through PyCharm or VSCode
  • Check every commit is refactored using a pre-commit hook
  • Run a continuous integration job to check all code is refactored

This functionality is only available with Pro/Team subscriptions. If you'd like to try it out for your team please contact us.

Installation

The Sourcery command line interface can be installed by running:

pip install sourcery-cli

Login

Once installed you can interactively login with:

sourcery login

which will open up a browser tab and ask for confirmation.

Usage

To display suggested refactorings as a diff:

sourcery refactor {file_or_directory}

And to apply those changes to the files:

sourcery refactor --in-place {file_or_directory}

Full documentation is available here.

Code quality metrics enabled by default in the IDE plugins

You can now hover over a method definition to see a quick view of its code quality. The metrics available are:

  • Cognitive complexity - a measure of how much complex nested logic is in the method
  • Size - a measure of how large the method is
  • Working memory - a measure of how many variables you need to keep in mind to understand the most complex parts of the method
  • Quality - a combination of the above metrics to give a percentage quality score

This can be switched off in the Sourcery section of the plugin settings.

New Refactorings

Use with context manager to ensure file closure

A common way of opening and using files is:

file = open("welcome.txt")
data = file.read()
print(data)
file.close()

However if an exception is thrown in between the file being opened and closed the call to file.close() may end up being skipped. By using Python's with context manager the file is closed for you as soon as the block is exited.

with open("welcome.txt") as file:
    data = file.read()
    print(data)

Extending the list-comprehension refactoring

We have now extended this refactoring to include an additional case, where augmented assignment is used to add to the list rather than append.

The following code:

files = []
for x in file_iterator:
    if x[-4:] == ".csv":
        files += [x]

will now be refactored as:

files = [x for x in file_iterator if x[-4:] == ".csv"]

Simplify if expression by using or

Often we find ourselves setting a value if it evaluates to True, and otherwise using a default.

currency = args['currency'] if args['currency'] else DEFAULT_CURRENCY

This can be simplified to the following, which is a bit easier to read and avoids the duplication of args['currency'].

currency = args['currency'] or DEFAULT_CURRENCY

Bug Fixes

  • Prevent use-assigned-variable from re-using properties

Metrics in VS Code

Enhanced code quality metrics in the IDE

We've been making some changes to how our code quality metrics are displayed.

When hovering over a method definition you now get more explanation of the code metrics. This means that you can see if the metric scores are good or bad at a glance.

In VS Code this is an emoji as shown above, whereas in PyCharm it is shown in writing. For each metric if the score is below average we also give a tip on how to improve it.

Metrics in PyCharm

Right now these metrics are hidden by default in PyCharm and VS Code, but they're very easy to enable.

To set them up just add the following setting to your Sourcery config file:

metrics:
    enabled: True

BooleanIfExpIdentity

New Refactorings

Enumerate

Loop counters that are incremented on each iteration of the loop like so:

i = 0
for animal in animals:
    i += 1
    print(i, animal)

can be replaced with a call to enumerate with a suitable start index:

for i, animal in enumerate(animals, start=1):
    print(i, animal)

Boolean IfExp identity

The following simple but overly verbose code:

return True if some_boolean_expression else False

is refactored to:

return bool(some_boolean_expression)

The negated version:

return False if some_boolean_expression else True

is refactored to:

return not some_boolean_expression

Writing a code editor plugin documentation

Instructions for how to write a code editor plugin are now available here. As the Sourcery binary implements the Language Server Protocol it is very easy to write a plugin for a new code editor.

Website changes

  • GitHub repo page allows you to select which branch to create refactor PR for
  • GitHub repo page shows instructions for starting refactoring reviews if none exist
  • GitHub repo page shows all refactoring jobs, including running and failed ones

Free Teams

Free for 3 team members on private repos

We wanted to make it easier for you to bring Sourcery into your workplace so you can improve your codebase. Starting today you can now use Sourcery for free with up to 3 team members! This is for both public and private repos.

Sourcery will review and refactor all new pull requests for these team members and give you insight to code quality. The only limitation is that refactoring whole private repos is still disabled on the free tier.

Public repos, as always, get access to all of Sourcery's features for free.

Choosing team members

One of the big takeaways from some of our conversations with you is that teams != full GitHub organisations.

Now you can pick and choose individual team members within your organisation who should have Sourcery access.

All organisation members still get full Sourcery functionality for public repositories.

More insights into code quality

Our code quality tools are now available outside of GitHub! Right now they're hidden by default in PyCharm and VS Code, but they're very easy to enable.

To set them up just add the following setting to your Sourcery config file:

metrics:
    enabled: True

We're still in the alpha stage of our code quality tools within IDEs, so we'd love to get your feedback and thoughts as we continue to make improvements.