diff --git a/package-structure-code/code-style-linting-format.md b/package-structure-code/code-style-linting-format.md index 78a97a7c0..4f746ecf0 100644 --- a/package-structure-code/code-style-linting-format.md +++ b/package-structure-code/code-style-linting-format.md @@ -6,10 +6,11 @@ * pyOpenSci requires authors to follow PEP 8 code format guidelines * Setting up a code formatters like Black and isort will help you enforce PEP 8 style guidelines and also consistent, readable code format -* Some commonly used tools are: Black/Blue, Isort, flake8 +* Some commonly used tools are: Black, Isort, flake8, Ruff * You can also setup pre-commit hooks which will run code formatters locally each time you make a commit. * [precommit.ci](https://pre-commit.ci/) is a bot that you can add to your GitHub repository. It will automagically apply code format to every PR using the tools specified in your pre-commit-config.yaml file. It can save significant time and make contributions easier for new contributors. +* Automation is good! By making code quality tools care of your code, you can focus on structural and high values tasks. ``` Consistent code format and style is useful to both your package @@ -50,6 +51,7 @@ Setting up a code format suite of tools will: - Ensure that format and style is consistent across your entire code-base. - Avoid lengthy discussions with contributors and other maintainers about personalized code format preferences during reviews. +- Avoid pure visual edits in the code base so that code reviews focus on added value Many packages use a suite of tools to apply code format rules, taking the work out of manually implementing code format requirements. @@ -82,27 +84,25 @@ You will learn more about Black below. ## Code format and style -### Black and Blue +### Black -[Black](https://black.readthedocs.io/en/stable/) and [Blue](https://blue.readthedocs.io/en/latest/) (which wraps around Black) are code -formatters. Both Black and Blue will automagically (and _unapologetically_) +[Black](https://black.readthedocs.io/en/stable/) is a code +formatter. Black will automagically (and _unapologetically_) fix spacing issues and ensure code format is consistent throughout your -package. Black and Blue also generally adhere to PEP 8 style guidelines with +package. Black also generally adhere to PEP 8 style guidelines with some exceptions. A few examples of those exceptions are below: - Black defaults to a line length of 88 (79 + 10%) rather than the 79 character `PEP 8` specification. However, line length is a setting can be manually overwritten in your Black configuration. -- Black and Blue will not adjust line length in your comments or docstrings. -- Neither tool will review and fix import order (you need _isort_ to do that - see below). +- Black will not adjust line length in your comments or docstrings. +- This tool will not review and fix import order (you need _isort_ or _Ruff_ to do that - see below). -Blue addresses a few format decisions in Black that some maintainers do not like. -[You can compare the differences here](https://blue.readthedocs.io/en/latest/#so-what-s-different) and decide which tool you prefer! ```{tip} If you are interested in seeing how Black will format your code, you can use the [Black playground](https://black.vercel.app/) ``` -Using a code formatter like Black or Blue will leave you more time to work on +Using a code formatter like Black will leave you more time to work on code function rather than worry about format. ### flake8 for linting code in Python packages @@ -163,7 +163,7 @@ order. It will then modify your code, automatically reordering all imports. This leaves you with one less thing to think about when cleaning up your code. -### Example application of isort +#### Example application of isort Code imports before `isort` is run: @@ -197,6 +197,46 @@ from stravalib import exc from stravalib import unithelper as uh ``` +### Ruff + +[Ruff](https://beta.ruff.rs) is a new addition to the code quality ecosystem, +gaining some traction since its release. +`ruff` is a linter for Python, aiming to replace several tools behind a single interface. +As such, `ruff` can be used instead of `flake8` and `isort`. + +`ruff` has some interesting features that distinguish it from other linters: +- Linter configuration in `pyproject.toml` +- Several hundred rules included, many of which are automatically fixable +- Rules explanation, see [F403](https://beta.ruff.rs/docs/rules/undefined-local-with-import-star/) for an example +- Fast execution time, makes a quick feedback loop possible even on large projects. + +Here is a simple configuration to get started with `ruff`: + +```toml +# pyproject.toml + +[tool.ruff] +select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes. "E" + "W" + "F" + "C90" (mccabe complexity) is equivalent to flake8 + "I", # isort +] +ignore = [ + "E501", # line >79, handled by black +] +``` + +Depending on your project, you might want to add the following to sort imports correctly: + +```toml +# pyproject.toml + +[tool.ruff.isort] +known-first-party = [""] +``` + + ## How to use code formatter in your local workflow ### Linters, code formatters and your favorite coding tools @@ -369,7 +409,7 @@ pyOpenSci suggests setting up a linter and a code styler for your package, regardless of whether you use pre-commit hooks, CI or other infrastructure to manage code format. Setting up these tools will give you automatic feedback about your code's -structure as you (or a contributor) write it. And using tools -like black or blue that format code for you, reduce effort that +structure as you (or a contributor) write it. And using a tool +like black that format code for you, reduce effort that you need to make surrounding decisions around code format and style.