ModernCalcs

Python Formatter

import os,sys
from typing import List,Optional,Dict

class UserRepository:
    """Manages user data storage and retrieval."""
    def __init__(self,db_path:str)->None:
        self.db_path=db_path
        self._cache:Dict[int,dict]={}

    def find_by_id(self,user_id:int)->Optional[dict]:
        if user_id in self._cache:
            return self._cache[user_id]
        user={'id':user_id,'name':f'User {user_id}'}
        self._cache[user_id]=user
        return user
    def find_adults(self,users:List[dict])->List[dict]:
        return [u for u in users if u.get('age',0)>=18]
    def clear_cache(self)->None:
        self._cache.clear()

def process(repo:UserRepository,ids:List[int])->None:
    for uid in ids:
        user=repo.find_by_id(uid)
        if user:
            print(f"Found: {user['name']}")

if __name__=='__main__':
    repo=UserRepository('/tmp/users.db')
    process(repo,[1,2,3])

Python's indentation is syntax — this tool normalizes tabs to 4 spaces, strips trailing whitespace, and collapses excess blank lines. For full PEP 8 formatting (spacing, line length), use black or autopep8.

Python Formatter: Normalize Indentation and Whitespace

Python is unique among popular languages: its indentation is syntax, not decoration. This means a general-purpose re-indenter would silently corrupt valid Python. This tool does what IS safe without risking your logic: normalizes tabs to 4-space indentation, strips trailing whitespace from each line, and collapses 3+ consecutive blank lines to 2.

Formula
# Input: mixed tabs/spaces, trailing whitespace def greet(name): \tprint(f"Hello, {name}") \t\tif name: # wrong indent - preserved \n\n\n# 3+ blank lines # Output: normalized def greet(name): print(f"Hello, {name}") if name: # wrong indent - preserved # 2 blank lines max

Existing indentation structure is preserved — only the unit (tab vs spaces) is normalized. Wrong indentation in the original stays wrong.

Why Python Indentation Cannot Be Rewritten

In languages like JavaScript or Java, indentation is purely cosmetic — braces define blocks. In Python, the indentation level is what defines the block. A line at depth 4 vs depth 8 has different semantic meaning. Rewriting indentation without understanding the AST would produce code that runs differently. This tool only normalizes the whitespace unit, never the depth.

Tab Normalization

PEP 8 explicitly states that spaces are the preferred indentation method. Tabs are still allowed for consistency with code that already uses them, but mixing tabs and spaces causes IndentationError in Python 3. This tool converts tabs to 4 spaces, making the indentation consistently space-based.

black for Full Formatting

black is the standard Python auto-formatter. It goes beyond whitespace: it reformats string quotes, adds trailing commas, wraps long lines at 88 characters, and reorders imports (when used with isort). Install with pip and configure your editor to run it on save. Most Python projects now have a black config in pyproject.toml.

Practical Examples

Cleaning Up Code Pasted from a PDF or Web Page

Copy-pasted Python often has tabs or trailing whitespace that breaks execution.

  • 1.Paste the Python code (may have tab indentation or trailing spaces)
  • 2.Tabs are converted to 4 spaces, trailing whitespace stripped
  • 3.The code now runs without IndentationError from mixed whitespace
  • 4.For full PEP 8 compliance, run black on the result

What Gets Normalized

  • Tabs converted to 4 spaces (1 tab = 4 spaces)
  • Trailing whitespace stripped from every line
  • 3+ consecutive blank lines collapsed to 2
  • Existing indentation depth preserved (not re-inferred)

Good Use Cases

  • Fixing tab-indented Python to be PEP 8 compliant
  • Cleaning up copy-pasted Python that has trailing spaces
  • Normalizing AI-generated Python before review
  • Making legacy Python 2 code consistent for linting

Frequently Asked Questions

Why can't you fully reformat Python like you can other languages?

Python's indentation is syntax, not style — changing the indent level of a line changes what block it belongs to. An auto-formatter that guesses indentation would silently produce incorrect code. This tool safely normalizes what CAN be changed without ambiguity: tab size and trailing whitespace.

What does 'normalize tabs to 4 spaces' mean?

Python allows both tab and space indentation, but mixing them causes IndentationError. Code indented with tabs is rewritten to use 4 spaces per tab stop, making it consistently space-indented and PEP 8 compliant. Note: this assumes 1 tab = 4 spaces.

What is black and how do I use it?

black is Python's most popular auto-formatter. It enforces PEP 8 with additional opinions (88-char line length, trailing commas). Install with 'pip install black' and run 'black .' to format all .py files in a directory. Most Python IDEs integrate black as a format-on-save action.

What is PEP 8?

PEP 8 is Python's official style guide. Key rules include: 4-space indentation, 79-character line limit, two blank lines before top-level functions/classes, one blank line between methods, and spaces around operators. black enforces a slightly modified version of PEP 8.