black — Python formatting rule for Cursor: setup guide
This Cursor rule standardizes Python formatting with Black and describes how to enforce style checks before commits and during CI builds.
.cursor/rules/black.mdcWhat black does
The rule targets files matching **/*.py and treats Black as the project's formatter. It recommends keeping configuration in pyproject.toml, declaring Black as a development dependency, and aligning its version across local environments and CI. The suggested workflow uses pre-commit to format code before commits and black --check . to reject formatting differences in CI.
Black normalizes string quotes, adds trailing commas to multiline expressions, and formats type annotations consistently. It does not reorder imports, so the rule pairs it with isort or Ruff's import-sorting feature. The configuration should stay close to Black's defaults, including an 88-character line length, unless an existing project has a concrete reason to differ. Version pinning also helps prevent unnecessary formatting changes between developers.
For new projects or migrations, the rule suggests evaluating Ruff, which combines formatting, linting, and import sorting. Existing Black-based projects can follow the documented workflow instead. Add the rule as .cursor/rules/black.mdc to apply its guidance in Cursor.
What it helps with
- Standardize formatting across Python source files
- Run Black automatically before Git commits
- Fail CI checks when Python formatting differs
- Keep formatter versions aligned across local development and CI
- Handle import sorting separately from code formatting
Example prompts for the agent
- Format the Python files according to Black and keep the project configuration in
pyproject.toml. - Set up
pre-committo run Black before each commit. - Add
black --check .to CI and explain how to sort imports withisort.
How to install black
Manually: put the files in place
.cursor/rules/black.mdcFrontmatter: description, globs, alwaysApply
Manually: put the files in place
.claude/rules/black.mdThe paths frontmatter field limits the files: move globs from the source into paths
AGENTS.md
Codex reads AGENTS.md: paste the rule text there
Manually: put the files in place
.github/instructions/black.instructions.mdThe applyTo field sets which files it applies to: move globs from the source into applyTo
Manually: put the files in place
.devin/rules/black.mdManually: put the files in place
.clinerules/black.mdStep by step, with commands for each platform: Cursor rules: .mdc files, four modes and what replaced .cursorrules
Questions about black
How do I install the black rule in Cursor?
Add the rule file at .cursor/rules/black.mdc in your project. Cursor can then apply its guidance to Python files matching **/*.py.
What does the black rule for Cursor do?
It provides project guidance for formatting Python with Black, configuring pyproject.toml, and running checks through pre-commit and CI. It also recommends keeping the formatter version consistent across environments.
Does Black sort Python imports?
No. The rule recommends using isort or Ruff's built-in import-sorting feature to organize imports.
Source text
black.mdc · CC0-1.0
---
description: Enforce consistent Python code formatting using Black, automate style checks, and integrate seamlessly into development workflows to eliminate style debates and speed up code reviews.
globs: **/*.py
---
# black Best Practices
`black` is the uncompromising Python code formatter. Our team adopts `black` as the definitive style guide for all Python projects. By using `black`, you cede control over formatting minutiae, gaining speed, determinism, and freedom from style debates.
**🚨 IMPORTANT: For new projects, or if migrating, strongly consider [Ruff](https://pydevtools.com/handbook/reference/ruff/) instead of `black`. Ruff offers superior performance and combines formatting, linting, and import sorting into a single tool. If your project is already committed to `black`, these guidelines apply.**
## 1. Core Principle: Cede Control
`black` is opinionated by design. Do not fight its formatting. Embrace its defaults to achieve ultimate consistency across the codebase.
## 2. Installation and Configuration
Always install the latest stable version of `black` (v25.12.0 as of Dec 2025) and configure it via `pyproject.toml`.
### 2.1. Project Dependency
Declare `black` as a development dependency.
❌ **BAD: Global installation or missing dependency**
```toml
# pyproject.toml
# black not listed, relies on global install or manual management
```
✅ **GOOD: `black` as a development dependency**
```toml
# pyproject.toml
[project]
name = "my-project"
version = "0.1.0"
[tool.poetry.dependencies]
python = ">=3.10,<3.13"
[tool.poetry.group.dev.dependencies]
black = "^25.12.0" # Always pin to latest major/minor
```
### 2.2. `pyproject.toml` Configuration
Stick to `black`'s defaults. Only configure line length if absolutely necessary for legacy reasons (e.g., integrating with an older codebase that has a different standard).
❌ **BAD: Over-configuring `black`**
```toml
# pyproject.toml
[tool.black]
line-length = 100 # Deviating from 88 without strong reason
skip-string-normalization = true # Disabling core black features
```
✅ **GOOD: Minimal `black` configuration (default 88 chars)**
```toml
# pyproject.toml
[tool.black]
# No configuration needed; defaults are best.
# If you must change line-length, do so sparingly:
# line-length = 88
```
## 3. Automated Formatting Workflow
Integrate `black` into your development pipeline to ensure continuous consistency.
### 3.1. Pre-commit Hooks
Use `pre-commit` to automatically format files before every commit. This catches formatting issues early.
❌ **BAD: Manual formatting or relying on CI only**
```bash
# Developer forgets to run black before committing
git commit -m "feat: new feature" # Unformatted code committed
```
✅ **GOOD: `black` via `pre-commit`**
```yaml
# .pre-commit-config.yaml
repos:
- repo: https://github.com/psf/black
rev: 25.12.0 # Use the latest stable version
hooks:
- id: black
language_version: python3.11 # Match your project's Python version
```
**Action**: Install `pre-commit` (`pip install pre-commit`) and set up hooks (`pre-commit install`).
### 3.2. CI/CD Integration
Ensure your CI pipeline checks for `black` compliance and fails the build on any formatting mismatch.
❌ **BAD: CI passes even with unformatted code**
```bash
# In CI script
# No black check, or black --diff only
```
✅ **GOOD: CI enforces `black` formatting**
```bash
# In CI script (e.g., .github/workflows/main.yml)
- name: Check code style with Black
run: pip install black==25.12.0 && black --check .
```
## 4. Code Organization and Structure
`black` ensures consistent formatting, which indirectly improves code organization and readability.
### 4.1. Import Sorting
`black` does *not* sort imports. Pair it with `isort` (or Ruff's built-in import sorting) for a complete solution.
❌ **BAD: Unsorted imports**
```python
import os
from my_module import ClassA
import sys
from third_party import lib
```
✅ **GOOD: Sorted imports (with `isort` or Ruff)**
```python
import os
import sys
from third_party import lib
from my_module import ClassA
```
**Action**: Add `isort` to your `pre-commit-config.yaml` or use Ruff.
### 4.2. Consistent String Quotes and Trailing Commas
`black` enforces double quotes for strings and trailing commas in multi-line constructs.
❌ **BAD: Inconsistent quotes, missing trailing commas**
```python
my_string = 'hello world'
my_list = [
1,
2
]
```
✅ **GOOD: `black`-formatted strings and lists**
```python
my_string = "hello world"
my_list = [
1,
2, # Trailing comma for multi-line
]
```
## 5. Type Hints
`black` consistently formats type hints, making them more readable. Always use explicit type hints.
❌ **BAD: Inconsistent spacing or missing type hints**
```python
def process_data(data : list):
return len(data)
def get_name(user):
return user.name
```
✅ **GOOD: `black`-formatted and explicit type hints**
```python
from typing import Any
def process_data(data: list[Any]) -> int:
return len(data)
def get_name(user: Any) -> str:
return user.name
```
## 6. Testing Approaches
`black` ensures your test files are as consistently formatted and readable as your application code. This aids in test maintenance and debugging.
❌ **BAD: Unformatted or inconsistently formatted test files**
```python
def test_addition():
assert 1+1 == 2
```
✅ **GOOD: `black`-formatted test files**
```python
def test_addition():
assert 1 + 1 == 2
```
**Action**: Ensure `black` runs on your `tests/` directory.
## 7. Common Pitfalls and Gotchas
### 7.1. Version Mismatches
Inconsistent `black` versions across the team or CI can lead to re-formatting churn.
❌ **BAD: Different `black` versions in use**
```bash
# Dev A uses black 24.1.0, Dev B uses black 25.12.0
# Code formatted by A gets re-formatted by B, leading to noisy diffs.
```
✅ **GOOD: Standardized `black` version**
```toml
# pyproject.toml
[tool.poetry.group.dev.dependencies]
black = "==25.12.0" # Pin to exact version for consistency
```
**Action**: Pin `black` to an exact version in `pyproject.toml` and `pre-commit-config.yaml`.
### 7.2. Ignoring `black`
Disabling `black` for specific files or sections without a strong, documented reason undermines consistency.
❌ **BAD: Disabling `black` for convenience**
```python
# my_module.py
# fmt: off
def ugly_function():
# ... unformatted code ...
# fmt: on
```
✅ **GOOD: Trust `black`'s formatting**
```python
# my_module.py
def ugly_function():
# black will format this consistently
result = (
"a_very_long_string_that_black_will_wrap_nicely"
+ "another_part_of_the_string"
)
return result
```
**Action**: Only use `fmt: off`/`fmt: on` directives as a last resort for genuinely un-black-able code, and document why.
© sanjeed5 · CC0-1.0 · sanjeed5/awesome-cursor-rules-mdc