How to Enforce Indentation Rules From .editorconfig in Python

A mock function that reads .editorconfig-style indentation rules (spaces or tabs, size) and fixes indentation in source code lines by tracking brace depth.

Medium Python 3.9+ Aug 9, 2026 Modern tooling 14 views 0 copies

Python code

51 lines
Python 3.9+
def enforce_indent(editorconfig_rules, file_content):
    """
    Mock function to enforce indentation rules from .editorconfig.
    Returns the content with indentation fixed (or unchanged if already compliant).
    """
    indent_style = editorconfig_rules.get("indent_style", "spaces")
    indent_size = int(editorconfig_rules.get("indent_size", "4"))
    
    # Determine expected indentation unit
    if indent_style == "tab":
        expected = "\t"
        pattern = r"^\s*"
    else:
        expected = " " * indent_size
        pattern = r"^\s*"
    
    lines = file_content.splitlines(keepends=True)
    fixed_lines = []
    indent_level = 0
    
    for line in lines:
        stripped = line.lstrip()
        if not stripped:
            fixed_lines.append("\n")
            continue
        
        # Adjust indent level based on braces (simple mock heuristic)
        if stripped.startswith("}"):
            indent_level = max(0, indent_level - 1)
        
        # Build the correct indentation
        if indent_style == "tab":
            new_indent = expected * indent_level
        else:
            new_indent = expected * indent_level
        
        fixed_lines.append(new_indent + stripped)
        
        # Increment level after opening brace
        if stripped.endswith("{"):
            indent_level += 1
    
    return "".join(fixed_lines)


if __name__ == "__main__":
    rules = {"indent_style": "spaces", "indent_size": "2"}
    sample_code = "function test() {\nif (true) {\nconsole.log('hi');\n}\n}\n"
    
    result = enforce_indent(rules, sample_code)
    print(result)

Output

stdout
function test() {
  if (true) {
    console.log('hi');
  }
}

How it works

The function parses .editorconfig rules for indent_style and indent_size, then rebuilds each non-empty line with the correct leading whitespace. It tracks indentation level by counting opening and closing braces {/} on each line — a simple heuristic that works for C-like syntax. The regex pattern r"^\s*" is used only to strip existing leading whitespace via lstrip(). Because empty lines are replaced with a plain newline, whitespace-only lines are normalized instead of preserved. This mock mirrors how tools like autopep8 or prettier apply formatting rules before a commit.

Common mistakes

  • Using lstrip() and then re-adding indentation only for non-empty lines, losing intentional blank-line whitespace
  • Forgetting to handle closing braces before computing the current indent level, causing off-by-one indentation
  • Assuming indent_size is always an integer without coercing it, which breaks when .editorconfig has `indent_size = tab`

Variations

  1. Use `textwrap.dedent` or a custom tokenizer to handle indentation more robustly for nested structures beyond braces
  2. Parse .editorconfig files directly with the `configparser` module and apply rules per-file glob patterns

Real-world use cases

  • Pre-commit hook that normalizes indentation across a team's codebase before files are staged.
  • IDE or editor plugin that reformats pasted code to match the project's .editorconfig settings.
  • CI pipeline that checks and auto-fixes indentation drift in pull requests for mixed-contributor repos.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Modern tooling

Related tutorials and quizzes for this topic.