When developing ReadmeGenie, I aimed to ensure consistent code quality with an automated setup for linting and formatting. After considering several tools, I selected Ruff as the linter and Black as the code formatter. Although Ruff can also handle both linting and formatting, I decided to set up Black as a separate formatter to gain experience with the configuration of both tools. Below, I’ll share why I chose these tools, how I configured them for my project, the challenges I faced, and the lessons I learned along the way.
1. Tool Selection
Why Ruff?
Ruff is a fast linter for Python that supports various linting rules from other linters (like Flake8 and Pyflakes) and offers significant performance improvements. It’s highly customizable, which allowed me to specify a mix of rules while ensuring compatibility with Black for formatting. Ruff’s design for speed and extensibility is ideal for projects that prioritize efficiency without sacrificing quality.
- Ruff Documentation: https://github.com/charliermarsh/ruff
Why Black?
Black is a Python formatter that strictly enforces one formatting style, helping reduce discussions and inconsistencies over code styling. While Ruff offers basic formatting capabilities, Black’s dedicated approach provides a few advantages:
- Consistency: Black enforces a strict, standard style that minimizes debates over code formatting.
Broad Adoption: Black is widely used, making it easier to integrate into most development workflows, especially in collaborative projects.
Black Documentation: https://github.com/psf/black
2. Project Setup
To ensure that Ruff and Black worked seamlessly in ReadmeGenie, I configured them in both pyproject.toml and
.pre-commit-config.yaml, allowing developers to automatically format and lint code when making commits.
Configuration for Ruff and Black in pyproject.toml
This setup ensures Ruff is used solely for linting and Black for formatting:
# pyproject.toml # Set up black as formatter [tool.black] line-length = 88 target-version = ["py311"] # Set up ruff as linter only [tool.ruff] # Exclude directories that don’t need linting (e.g., virtual environments) exclude = [ "venv/", "__pycache__/" ] fix = true # Enable specific linting rules select = ["F", "E", "W", "B", "I", "S"] # Example codes: F=flake8, E=errors, W=warnings, B=bugbear, I=import, S=safety # Exclude Black-compatible rules to avoid conflicts with Black's formatting. ignore = ["E501", "E203", "E231"] # Exclude Black-incompatible style issues
- ignore: Black handles specific styling, so we excluded these rules in Ruff.
- fix: Enables Ruff to fix issues where possible, leaving formatting to Black.
Adding Pre-commit Hook for Ruff and Black
Using pre-commit hooks, I configured .pre-commit-config.yaml to enforce linting and formatting on every commit:
# .pre-commit-config.yaml repos: - repo: https://github.com/psf/black rev: 23.1.0 hooks: - id: black - repo: https://github.com/charliermarsh/ruff-pre-commit rev: v0.7.1 hooks: - id: ruff
3. Running Ruff and Black from the Command Line
With the above setup, you can use the following commands:
- Run Ruff:
# pyproject.toml # Set up black as formatter [tool.black] line-length = 88 target-version = ["py311"] # Set up ruff as linter only [tool.ruff] # Exclude directories that don’t need linting (e.g., virtual environments) exclude = [ "venv/", "__pycache__/" ] fix = true # Enable specific linting rules select = ["F", "E", "W", "B", "I", "S"] # Example codes: F=flake8, E=errors, W=warnings, B=bugbear, I=import, S=safety # Exclude Black-compatible rules to avoid conflicts with Black's formatting. ignore = ["E501", "E203", "E231"] # Exclude Black-incompatible style issues
- Run Black:
# .pre-commit-config.yaml repos: - repo: https://github.com/psf/black rev: 23.1.0 hooks: - id: black - repo: https://github.com/charliermarsh/ruff-pre-commit rev: v0.7.1 hooks: - id: ruff
These commands apply fixes to all Python files, ensuring consistent styling and quality checks.
4. VS Code Integration
To automate Ruff and Black on save, I added the following configuration in .vscode/settings.json:
ruff check . --fix
This setup makes Black the default formatter and Ruff the only active linter in VS Code, allowing both to run
automatically upon saving.
5. Findings and Fixes
Once configured, Ruff and Black identified several issues:
- Line Length (E501): Ruff initially flagged long lines, which Black auto-formatted.
- Unused Imports and Variables: Ruff caught several unused imports and variables.
- Indentation and Styling Consistency: Black applied consistent spacing and indentation, enhancing readability.
6. Challenges
One notable challenge was understanding that some styles are incompatible between Ruff and Black. For example:
- Line Length (E501): Ruff initially flagged long lines exceeding 88 characters, which Black handles by wrapping lines. To prevent conflicts, I added E501 to Ruff’s ignore list. Despite this, Ruff sometimes flagged E501 errors if Black didn’t apply the expected breakpoints. These discrepancies underscored the importance of adjusting each tool’s configuration and understanding where they may overlap.
7. Lessons Learned
Using Ruff and Black together has been a great way to improve code quality. Here’s what I learned:
- Consistency: Black’s opinionated style reduces ambiguity in code styling.
- Automation: Pre-commit hooks save time and ensure consistent formatting.
- Editor Integration: Configuring Ruff and Black to run on save within VS Code streamlined development.
- Compatibility: Learning how to resolve conflicts like E501 taught me about tool configurations and helped fine-tune project workflows.
The above is the detailed content of Setting Up Tools for Code Quality. For more information, please follow other related articles on the PHP Chinese website!

TomergelistsinPython,youcanusethe operator,extendmethod,listcomprehension,oritertools.chain,eachwithspecificadvantages:1)The operatorissimplebutlessefficientforlargelists;2)extendismemory-efficientbutmodifiestheoriginallist;3)listcomprehensionoffersf

In Python 3, two lists can be connected through a variety of methods: 1) Use operator, which is suitable for small lists, but is inefficient for large lists; 2) Use extend method, which is suitable for large lists, with high memory efficiency, but will modify the original list; 3) Use * operator, which is suitable for merging multiple lists, without modifying the original list; 4) Use itertools.chain, which is suitable for large data sets, with high memory efficiency.

Using the join() method is the most efficient way to connect strings from lists in Python. 1) Use the join() method to be efficient and easy to read. 2) The cycle uses operators inefficiently for large lists. 3) The combination of list comprehension and join() is suitable for scenarios that require conversion. 4) The reduce() method is suitable for other types of reductions, but is inefficient for string concatenation. The complete sentence ends.

PythonexecutionistheprocessoftransformingPythoncodeintoexecutableinstructions.1)Theinterpreterreadsthecode,convertingitintobytecode,whichthePythonVirtualMachine(PVM)executes.2)TheGlobalInterpreterLock(GIL)managesthreadexecution,potentiallylimitingmul

Key features of Python include: 1. The syntax is concise and easy to understand, suitable for beginners; 2. Dynamic type system, improving development speed; 3. Rich standard library, supporting multiple tasks; 4. Strong community and ecosystem, providing extensive support; 5. Interpretation, suitable for scripting and rapid prototyping; 6. Multi-paradigm support, suitable for various programming styles.

Python is an interpreted language, but it also includes the compilation process. 1) Python code is first compiled into bytecode. 2) Bytecode is interpreted and executed by Python virtual machine. 3) This hybrid mechanism makes Python both flexible and efficient, but not as fast as a fully compiled language.

Useaforloopwheniteratingoverasequenceorforaspecificnumberoftimes;useawhileloopwhencontinuinguntilaconditionismet.Forloopsareidealforknownsequences,whilewhileloopssuitsituationswithundeterminediterations.

Pythonloopscanleadtoerrorslikeinfiniteloops,modifyinglistsduringiteration,off-by-oneerrors,zero-indexingissues,andnestedloopinefficiencies.Toavoidthese:1)Use'i


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

Zend Studio 13.0.1
Powerful PHP integrated development environment

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

mPDF
mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),
