Description
This post is about lab 06 for OSD600 course at Seneca College. This week we learned Static Analysis Tooling such as Formatter(prettier, Ruff) and Linter(Black, Ruff, ESLint). Using those tools, we made our code more consistent regardless of where it is written or who writes it. And also, we practiced git commands
such as git merge
and git rebase
Tasks
Q1. Which tools did you choose? Why did you choose them? Provide links to each tool and briefly introduce them.
I use Ruff for both formatter and linter. When I was reading the instruction for this lab, I found that Ruff can be used for both formatter and linter. I thought that I would be more conveninent and efficient to use one tool for the people who would work on this project as well as for myself. Ruff is orginally maded for formatter, but then its features expanded to Linter. The upside to this tool is that it's really faster and also compatable with other linters such as Black.
Q2. How did you set them up in your project? Be detailed so that other developers could read your blog and get some idea how to do the same.
I've created my own organized notes on GitHub to document what I've learned, as the content is quite extensive. I will also share the link.
Install Ruff
Include the following codes:
// pyproject.toml file
[tool.poetry.group.dev.dependencies]
ruff = "^0.7.1"
Run the following command:
poetry install
Ruff Formatter
Formatter Configuration
In the pyproject.toml
file, configure the Ruff formatter as the following example:
[tool.ruff]
line-length = 100
exclude = [
"tests/*", # Ignore all files in the tests directory
"docs/*", # Ignore all files in the docs directory
"*.pyc", # Ignore all compiled Python files
"migrations/*", # Ignore all files in the migrations directory
"example/*",
"__pycache__/*",
"*.env",
"**/*.md",
]
[tool.ruff.format]
quote-style = "double"
indent-style = "tab"
docstring-code-format = true
docstring-code-line-length = 20
docstring-code-format = true
: This will format code that starts with >>> inside """ ... """
For example, If docstring-code-format = true
option is applied to the following code,
def calculate_square(n):
"""
Calculate the square of a number.
Example:
>>> result = calculate_square(5)
>>> print(result) # Outputs 25
>>> long_calculation = calculate_square(10) + calculate_square(20) + calculate_square(30)
>>> print(long_calculation) # Outputs 1300
"""
return n ** 2
It will become formatted as follows:
def calculate_square(n):
"""
Calculate the square of a number.
Example:
>>> result = calculate_square(5)
>>> print(result) # Outputs 25
>>> long_calculation = (
... calculate_square(10)
... + calculate_square(20)
... + calculate_square(30)
... )
>>> print(long_calculation) # Outputs 1300
"""
return n ** 2
Docstring code can be executed. Refer to doctest Docs
Run the Ruff formatter
poetry run ruff format .
Ruff Linter
Linter Configuration
Since I am using ruff formatter together, I only need a bit more configuration settings.
[tool.ruff.lint]
select = ["E4", "E7", "E9", "F", "F841"]
I asekd ChatGPT what those are for.
E4
: This code typically corresponds to various syntax errors or issues related to the structure of your code. It may include checks for problems such as unclosed parentheses, braces, or other syntax-related issues.
E7
: This code is generally related to type errors or issues involving type annotations. It may indicate that there are inconsistencies or issues with type hints in your code, which can lead to confusion or runtime errors.
E9
: This error code often relates to import errors or issues with the organization of your import statements. It can flag problems such as unused imports or circular imports that can complicate module loading.
F
: This category usually encompasses formatting issues. It can include a variety of stylistic checks, such as line length, whitespace usage, and general adherence to PEP 8 (the Python style guide).
F841
: This code specifically checks for assigned variables that are never used.
We could also do:
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["E402"]
"**/{tests,docs,tools}/*" = ["E402"]
I asked ChatGPT what those configurations are for:
ChatGPT => The E402
error, which means "module level import not at top of file," occurs when import statements are not placed at the top of a Python file. According to PEP 8, the Python style guide, all imports should be at the top of the file, right after any module comments and docstrings but before any other code.
Here are common scenarios where E402 might happen:
1. Conditional Imports:
if some_condition:
import os # E402 error: Import is not at the top level of the file
2. Delayed Imports for Performance Reasons:
Sometimes, you might place an import further down in the file to avoid unnecessary imports until they are actually needed, such as in a function:
def some_function():
import numpy as np # E402 error: Import is inside a function
return np.array([1, 2, 3])
In those scenarios, you can use the configuration for the files that need to ingore the rules.
How to skip linting some pieces of code in a file
1. Ignore Specific Lines
You can add an # noqa
comment at the end of a line to ignore linting on that specific line. To ignore specific rules, specify the rule codes:
if self.model is "groq": # noqa: F632
In this example, Ruff will ignore the F632
warning on that line.
2. Ignore a Block of Code
To ignore a block of code, wrap the code with # noqa: BEGIN
and # noqa: END
:
# noqa: BEGIN
# This code block will be ignored by the linter
if some_condition:
import sys # Normally flagged as E402
# noqa: END
3. Ignore Rules for the Whole File
To ignore specific rules for the entire file, add a comment at the top of the file listing the rule codes to ignore:
# ruff: noqa: E402, F632
This approach is useful if the whole file has patterns that would otherwise be flagged by Ruff, such as non-top-level imports or value comparisons using is
Run the Ruff Linter
poetry run ruff check .
Q3. What did the tools find in your code? Did you have to fix a lot of issues?
Python is already a bit strict when it comes to its formatting such as indentation or line changes, formatter didn't do a lot; only in the main function it changed quite a bit. However, Linter actually caught some syntax errors that I missed.
Before Formatter in codeMage.py
file
After Formatter
Linter found
Q4.How did you get the tools to run from the command line?
I think I answered this question above, and since the post is getting too long, I will not make an redunant writing. Sometimes when the post is too long, Dev.to
seems to get some bugs. Some part of the content disappears.
Q5. How did you integrate the tools with your editor/IDE?
These are the steps that I followed. I contained them in CONTRIBUTING.md
in my project
1. Python Extension for VS Code (if not already installed):
The Python extension for VS Code is needed to enable Python-specific features, such as linting and formatting integration. Open VS Code, go to the Extensions view (Ctrl+Shift+X or Cmd+Shift+X on macOS),search for "Python" by Microsoft and install it if you haven’t already.
2. Ruff VS Code Extension:
Install the Ruff extension in VS Code to enable real-time linting and formatting.
In the Extensions view, search for "Ruff," and install the extension.
Manually Running Ruff Formatter and Linter
Run the Ruff formatter
with the following command in the root directory
poetry run ruff format .
Run the Ruff Linter
with the following command in the root directory
poetry run ruff check .
Q6. What did you learn from the process?
When I looked around gitHub and saw all these files, I didn't like them. It's because I didn't know them and I didn't need the necessity. As I learned it now and know how to use it, I love them. It's really useful and helpful. Especially when you are working with Dynamically Typed Language, it is so helpful. I think I will use these tools every time I start a new project, from now on. It's so cool
Top comments (0)