Python Formatter

Format Python with Ruff (Black-compatible).

Runs locallyYour input is processed in this tab. The editor blocks outgoing network requests.
Python input

The Python Formatter rewrites Python code in Black style using Ruff's formatter compiled to WebAssembly. Indentation, spacing, quotes, blank lines and long calls come out the way a Black-formatted codebase expects. It is for developers tidying a script, a notebook cell or a snippet before review. Everything runs in your browser — nothing is uploaded.

How to format Python code

  1. Paste your code, open a .py or .pyi file with ⌘/Ctrl O, or load an example. The output updates as you type.
  2. Pick the Line length your project uses: 88 matches Black, 79 matches PEP 8's limit.
  3. Copy the formatted code with ⌥/Alt C or download it with ⌘/Ctrl S.

Examples

Functions and a class

Two-space indentation, cramped operators and a one-line method body are normalised. Top-level definitions get two blank lines between them, as PEP 8 recommends.

Python
import os,sys
def greet( name:str,excited = False ):
  msg="Hello, %s"%name
  if excited : msg+= "!"
  return msg
class Config :
  def __init__(self,path=None): self.path=path or os.getcwd()

Result:

Python
import os, sys


def greet(name: str, excited=False):
    msg = "Hello, %s" % name
    if excited:
        msg += "!"
    return msg


class Config:
    def __init__(self, path=None):
        self.path = path or os.getcwd()

A call longer than the line length

When a call does not fit in 88 columns, its arguments move to one per line and a trailing comma is added. With Line length at 120 the arguments fit on a single indented line instead.

Python
result = client.request(method="POST", url="https://api.example.com/v1/orders", json={"items": [1,2,3], "note": "rush"}, timeout=30)

Result:

Python
result = client.request(
    method="POST",
    url="https://api.example.com/v1/orders",
    json={"items": [1, 2, 3], "note": "rush"},
    timeout=30,
)

The magic trailing comma and quote handling

A trailing comma you add yourself keeps a collection expanded even when it would fit on one line. Strings switch to double quotes unless that would require escaping.

Python
COLORS = ["red", "green",]
point = (1, 2)
msg = 'It"s fine'
name = 'Asha'

Result:

Python
COLORS = [
    "red",
    "green",
]
point = (1, 2)
msg = 'It"s fine'
name = "Asha"

Options explained

  • Line length — the column limit Ruff wraps at: 79 (PEP 8), 88 (Black's default), 100 or 120.
  • Indent — spaces per indentation level; 4 follows PEP 8 and Black, 2 suits codebases that already use two-space blocks.
  • Quotes — Double rewrites string literals to double quotes, Single to single quotes, and Preserve leaves each string's quotes as written; in every mode quotes are kept where changing them would add escapes.

Troubleshooting Python syntax errors

Ruff formats only code that parses, so a syntax error stops formatting and the error panel shows the parser's message with the line and column where it stopped, for example "(line 2, column 1)". Press F8 to jump there.

Simple statements must be separated by newlines or semicolons

This almost always means Python 2 code, such as print "hello". Ruff parses Python 3 only; change it to print("hello"). It also appears when two statements are pasted onto one line without a separator.

Expected :, found newline

A def, class, if, for, while, with or try line is missing its trailing colon.

Expected an indented block after function definition

The body of a function, class or block is not indented, which often happens when code is copied from a web page that strips leading spaces. Re-indent the body under its header.

Unexpected indentation

A line is indented more than the block it belongs to, or tabs and spaces are mixed within one block. Replace tabs with spaces and line the statement up with its neighbours.

Expected ,, found name

A bracket was opened and never closed, so the parser reads the next line as part of the same call. Check the line above the one the message points to for a missing ) or ].

Expected a statement

The input starts with something that is not Python, such as IPython %magic or !shell lines from a notebook. Remove those lines, format, then add them back.

FAQ

Is this the same as running Black?

Ruff's formatter is designed as a drop-in replacement for Black and produces the same output for the vast majority of code. There are a small number of documented differences in edge cases, mostly around comments and some parenthesised expressions. If your CI runs black --check, a file formatted here will usually pass; if it runs ruff format --check, it will pass exactly.

Does it sort imports or remove unused ones?

No. The formatter changes layout only, so import os, sys stays on one line and unused imports remain. Import sorting and unused-import removal are lint fixes (Ruff's I and F401 rules, or isort), not formatting, and they are not applied here.

Which Python versions are supported?

Any Python 3 syntax that Ruff's parser understands, including type hints, f-strings, the walrus operator, match statements, async code and type parameter syntax. Python 2 code such as print "x" or backtick repr is rejected with a syntax error. Type stub files (.pyi) can be opened and formatted too.

Is my code uploaded to a server?

No. Ruff runs as WebAssembly inside your browser, and the editor is an isolated frame that blocks network requests, so nothing is uploaded or stored on a server. Line length, indent and quote settings are remembered on this device. Your code is kept only if you turn on "Remember my last input".

Can I format a Jupyter notebook cell?

Yes, if the cell contains plain Python. Copy the cell, format it, and paste it back. Notebook-only syntax such as %timeit, %%bash or !pip install lines is not valid Python and causes a parse error; remove those lines first and restore them after formatting.

How do I make Ruff leave a block alone?

Wrap the lines in # fmt: off and # fmt: on comments. Everything between them is kept exactly as written, which is useful for hand-aligned matrices, lookup tables or long regular expressions. The comments are the same ones Black uses, so the region stays untouched when the file is later formatted in your editor or CI.

Ruff vs Black

Both produce the same style; they differ in how they run.

Ruff formatter Black
Written in Rust (compiled to WebAssembly here) Python
Default line length 88 88
Quote options Double, single, preserve Double (or skip normalisation)
Indent width Configurable Fixed at 4
Suppression comments fmt: off / fmt: on Same

Formatting Python in other languages' projects is covered across the code tools, including the Go Formatter and the Java Formatter.

Browse all Code Formatters