# Core Formatting Functions

Primary API functions for formatting Python code, providing both string-based and file-based formatting capabilities with comprehensive safety checks and validation.

## Capabilities

### String Formatting

The primary entry point for programmatic code formatting, taking source code as a string and returning formatted code.

```python { .api }
def format_str(src_contents: str, *, mode: Mode, lines: Collection[tuple[int, int]] = ()) -> str:
    """
    Format Python source code string.

    Parameters:
    - src_contents: Python source code to format
    - mode: Mode configuration controlling formatting behavior
    - lines: Optional line ranges to format (tuple of start, end line numbers)

    Returns:
    Formatted Python source code string

    Raises:
    - InvalidInput: If source code cannot be parsed
    - NothingChanged: If no formatting changes are needed
    """
```

### File Content Formatting

Formats file contents with optional AST safety checks, used internally by command line and server implementations.

```python { .api }
def format_file_contents(src_contents: str, *, fast: bool, mode: Mode, lines: Collection[tuple[int, int]] = ()) -> str:
    """
    Format file contents with safety checks.

    Parameters:
    - src_contents: File contents to format
    - fast: Skip AST safety checks if True
    - mode: Mode configuration controlling formatting behavior  
    - lines: Optional line ranges to format

    Returns:
    Formatted file contents

    Raises:
    - InvalidInput: If source cannot be parsed
    - NothingChanged: If no formatting changes needed
    - ASTSafetyError: If formatted code is not AST-equivalent (when fast=False)
    """
```

### In-Place File Formatting

Formats files directly on disk with configurable write-back behavior and automatic file type detection.

```python { .api }
def format_file_in_place(
    src: Path, 
    fast: bool, 
    mode: Mode, 
    write_back: WriteBack = WriteBack.NO, 
    lock: Any = None, 
    *, 
    lines: Collection[tuple[int, int]] = ()
) -> bool:
    """
    Format a file in place on disk.

    Parameters:
    - src: Path to source file to format
    - fast: Skip AST safety checks if True
    - mode: Mode configuration controlling formatting behavior
    - write_back: Output behavior (NO, YES, DIFF, CHECK, COLOR_DIFF)
    - lock: Optional threading lock for concurrent access
    - lines: Optional line ranges to format

    Returns:
    True if file was changed, False otherwise

    Note:
    Automatically detects .pyi and .ipynb file modes based on extension
    """
```

### Single File Formatting

Format a single file with full error handling and reporting integration.

```python { .api }
def reformat_one(
    src: Path,
    fast: bool,
    write_back: WriteBack,
    mode: Mode,
    report: Report,
    *,
    lines: Collection[tuple[int, int]] = ()
) -> None:
    """
    Reformat a single file under `src` without spawning child processes.

    Parameters:
    - src: Path to source file to format (supports stdin via "-")
    - fast: Skip AST safety checks if True  
    - write_back: Output behavior (NO, YES, DIFF, CHECK, COLOR_DIFF)
    - mode: Mode configuration controlling formatting behavior
    - report: Report object to track results and failures
    - lines: Optional line ranges to format

    Note:
    - Handles stdin input when src is "-" or starts with STDIN_PLACEHOLDER
    - Automatically detects .pyi and .ipynb modes from file extension
    - Integrates with cache system for performance optimization
    - Updates the provided Report object with results
    """
```

### AST Safety Validation

Functions to ensure formatted code maintains semantic equivalence and formatting stability.

```python { .api }
def assert_equivalent(src: str, dst: str) -> None:
    """
    Validate that formatted code is AST-equivalent to source.

    Parameters:
    - src: Original source code
    - dst: Formatted code

    Raises:
    - AssertionError: If ASTs are not equivalent
    """

def assert_stable(src: str, dst: str, mode: Mode, *, lines: Collection[tuple[int, int]] = ()) -> None:
    """
    Ensure formatting is stable (second pass produces same result).

    Parameters:
    - src: Original source code
    - dst: First formatting pass result  
    - mode: Mode configuration used for formatting
    - lines: Line ranges that were formatted

    Raises:
    - AssertionError: If second formatting pass differs
    """
```

### Feature Analysis

Functions for analyzing Python code to determine language features and compatible Python versions.

```python { .api }
def get_features_used(node: Node, *, future_imports: Optional[set[str]] = None) -> set[Feature]:
    """
    Analyze AST to determine Python language features used.

    Parameters:
    - node: AST node to analyze
    - future_imports: Set of __future__ import names

    Returns:
    Set of Feature enum values found in the code
    """

def detect_target_versions(node: Node, *, future_imports: Optional[set[str]] = None) -> set[TargetVersion]:
    """
    Determine compatible Python versions based on code features.

    Parameters:
    - node: AST node to analyze
    - future_imports: Set of __future__ import names

    Returns:
    Set of TargetVersion enums that support all detected features
    """

def get_future_imports(node: Node) -> set[str]:
    """
    Extract __future__ import statements from AST.

    Parameters:
    - node: AST node to analyze

    Returns:
    Set of __future__ import names found
    """
```

### Encoding Utilities

Utility functions for handling file encoding and line ending detection.

```python { .api }
def decode_bytes(src: bytes) -> tuple[str, str, str]:
    """
    Decode byte content to string with encoding and newline detection.

    Parameters:
    - src: Byte content to decode

    Returns:
    Tuple of (decoded_content, encoding, newline_type)
    """
```

## Usage Examples

### Basic String Formatting

```python
import black

# Simple formatting
code = "def f(arg:str='')->None:pass"
formatted = black.format_str(code, mode=black.Mode())
print(formatted)
# Output: def f(arg: str = "") -> None:
#     pass

# Custom line length
mode = black.Mode(line_length=79)
formatted = black.format_str(code, mode=mode)

# Format specific lines only
lines = [(1, 5), (10, 15)]  # Line ranges to format
formatted = black.format_str(code, mode=black.Mode(), lines=lines)
```

### File Formatting with Safety Checks

```python
from pathlib import Path

# Format file with full safety checks
try:
    changed = black.format_file_in_place(
        Path("script.py"),
        fast=False,  # Enable AST safety checks
        mode=black.Mode(),
        write_back=black.WriteBack.YES
    )
    if changed:
        print("File was reformatted")
    else:
        print("File was already formatted")
except black.NothingChanged:
    print("No changes needed")
except black.InvalidInput as e:
    print(f"Cannot format file: {e}")
```

### Single File Formatting with Reporting

```python
from pathlib import Path
import black

# Setup for single file formatting with reporting
report = black.Report(verbose=True)
mode = black.Mode(line_length=88)

# Format single file with full reporting
black.reformat_one(
    Path("example.py"),
    fast=False,
    write_back=black.WriteBack.YES,
    mode=mode,
    report=report
)

# Check results
print(f"Files changed: {report.change_count}")
print(f"Files failed: {report.failure_count}")
print(f"Exit code: {report.return_code}")
```

### Feature Detection

```python
import ast
import black

code = """
def func(x: int, /) -> int:  # Positional-only parameter
    return x | 2  # Union operator
"""

# Parse and analyze features
tree = ast.parse(code)
node = black.lib2to3_parse(code)
features = black.get_features_used(node)
compatible_versions = black.detect_target_versions(node)

print(f"Features used: {features}")
print(f"Compatible Python versions: {compatible_versions}")
```

## Types

```python { .api }
# Type aliases used by formatting functions
FileContent = str
Encoding = str  
NewLine = str

# From blib2to3 (AST processing)
Node = blib2to3.pytree.Node
Leaf = blib2to3.pytree.Leaf

# Collection type for line ranges
Collection = typing.Collection
```