A formatter for Python code that applies consistent formatting rules based on configurable style guidelines
YAPF provides comprehensive command-line tools for formatting Python code, including the main yapf formatter and the yapf-diff utility for formatting only changed lines in patches. The CLI supports various options for batch processing, parallel execution, and integration with development workflows.
The primary YAPF command-line interface for formatting Python files and directories.
def main(argv):
"""
Main command-line entry point for YAPF.
Args:
argv (list): Command-line arguments including program name
Returns:
int: Exit code (0 for success, non-zero for error)
With --diff: 0 if no changes, non-zero if changes found
Raises:
YapfError: If none of the supplied files were Python files
"""
def run_main():
"""
Console script entry point with exception handling.
Calls main() with sys.argv and handles YapfError exceptions
by printing error messages and exiting with code 1.
"""Format multiple files with various processing options.
def FormatFiles(filenames, lines, style_config=None, no_local_style=False,
in_place=False, print_diff=False, parallel=False,
quiet=False, verbose=False, print_modified=False):
"""
Format multiple files with comprehensive options.
Args:
filenames (list): List of file paths to reformat
lines (list): List of (start, end) tuples for line ranges to format
style_config (str): Style name or path to configuration file
no_local_style (bool): Don't search for directory-local style config
in_place (bool): Modify files in place
print_diff (bool): Show diff instead of formatted code
parallel (bool): Use parallel processing for multiple files
quiet (bool): Output nothing and set return value only
verbose (bool): Print filenames while processing
print_modified (bool): Print names of modified files
Returns:
bool: True if any source code was changed
"""# Format a single file to stdout
yapf my_script.py
# Format multiple files to stdout
yapf file1.py file2.py module.py
# Read from stdin
cat my_script.py | yapf
# Format all .py files in current directory
yapf *.py# Format file in place
yapf -i my_script.py
yapf --in-place my_script.py
# Format multiple files in place
yapf -i *.py
# Format all Python files in a directory recursively
yapf -r -i my_project/
yapf --recursive --in-place my_project/# Show diff of changes
yapf -d my_script.py
yapf --diff my_script.py
# Show diff for multiple files
yapf -d *.py
# Use with git to see changes
git diff --name-only | xargs yapf -d# Use specific predefined style
yapf --style=pep8 my_script.py
yapf --style=google my_script.py
yapf --style=facebook my_script.py
yapf --style=yapf my_script.py
# Use custom style file
yapf --style=/path/to/.style.yapf my_script.py
yapf --style=./pyproject.toml my_script.py
# Disable local style discovery
yapf --no-local-style --style=pep8 my_script.py# Format specific lines (1-indexed)
yapf -l 1-10 my_script.py # Lines 1 to 10
yapf -l 5-5 my_script.py # Line 5 only
yapf -l 1-10 -l 20-30 my_script.py # Multiple ranges
# Cannot use line ranges with multiple files
yapf -l 1-10 file1.py file2.py # ERROR# Parallel processing for multiple files
yapf -p *.py
yapf --parallel -i my_project/*.py
# Quiet mode (only set exit code)
yapf -q my_script.py
yapf --quiet -i *.py
# Verbose mode (show filenames being processed)
yapf -vv -i my_project/
yapf --verbose --in-place my_project/
# Print names of modified files
yapf -m -i *.py
yapf --print-modified --in-place *.py# Exclude specific patterns
yapf -r -i --exclude='*_pb2.py' my_project/
yapf -r -i --exclude='test_*.py' --exclude='*_test.py' src/
# Multiple exclusion patterns
yapf -r -i \
--exclude='*_pb2.py' \
--exclude='*_test.py' \
--exclude='vendor/*' \
my_project/# Show version
yapf -v
yapf --version
# Show help
yapf -h
yapf --help
# Show style help with current settings
yapf --style-help
yapf --style=google --style-helpFormat only changed lines in diff patches, useful for formatting code in pull requests or commits.
# Format lines changed in git diff
git diff -U0 --no-color HEAD^ | yapf-diff -i
# Format lines changed in current working directory
git diff -U0 --no-color | yapf-diff -i
# Format staged changes
git diff -U0 --no-color --cached | yapf-diff -i
# Format changes in SVN
svn diff --diff-cmd=diff -x-U0 | yapf-diff -p0 -i
# Show diff instead of applying changes
git diff -U0 --no-color HEAD^ | yapf-diff
# Specify number of prefix components to strip
git diff -U0 --no-color HEAD^ | yapf-diff -p1 -i# Pre-commit hook
#!/bin/bash
git diff -U0 --no-color --cached | yapf-diff -i -p1
# Format current branch changes
git diff -U0 --no-color main... | yapf-diff -i
# Format specific commit
git show --format="" -U0 --no-color <commit> | yapf-diff -p1 -iimport yapf
import sys
# Call main function directly
exit_code = yapf.main(['yapf', '-i', 'my_script.py'])
# Use run_main for console script behavior
sys.argv = ['yapf', '--style=google', '-d', 'my_script.py']
yapf.run_main() # Will print diff and exitfrom yapf import FormatFiles
# Format multiple files
files = ['file1.py', 'file2.py', 'module.py']
changed = FormatFiles(
filenames=files,
lines=None,
style_config='google',
in_place=True,
verbose=True
)
print(f"Modified files: {changed}")
# Format with parallel processing
changed = FormatFiles(
filenames=files,
lines=None,
style_config='pep8',
in_place=True,
parallel=True,
print_modified=True
)
# Format specific line ranges
lines = [(1, 10), (20, 30)] # Format lines 1-10 and 20-30
changed = FormatFiles(
filenames=['single_file.py'],
lines=lines,
style_config='facebook',
print_diff=True
)import argparse
from yapf import FormatFiles
from yapf.yapflib import file_resources
def custom_formatter():
"""Custom formatting tool with project-specific defaults."""
parser = argparse.ArgumentParser(description='Custom Python formatter')
parser.add_argument('files', nargs='+', help='Files to format')
parser.add_argument('--style', default='google', help='Formatting style')
parser.add_argument('--check', action='store_true',
help='Check if files need formatting')
args = parser.parse_args()
# Get all Python files
python_files = file_resources.GetCommandLineFiles(
args.files,
recursive=True,
exclude_patterns=['*_pb2.py', 'test_*.py']
)
# Format files
changed = FormatFiles(
filenames=python_files,
lines=None,
style_config=args.style,
in_place=not args.check,
print_diff=args.check,
verbose=True
)
if args.check and changed:
print("Files need formatting!")
return 1
return 0
if __name__ == '__main__':
exit(custom_formatter())#!/bin/bash
# .git/hooks/pre-commit
# Format staged Python files
git diff --cached --name-only --diff-filter=ACMR | \
grep '\.py$' | \
xargs yapf -i
# Add formatted files back to staging
git diff --cached --name-only --diff-filter=ACMR | \
grep '\.py$' | \
xargs git add# .pre-commit-config.yaml
repos:
- repo: https://github.com/google/yapf
rev: v0.43.0
hooks:
- id: yapf
args: [--style=google]
- id: yapf
name: yapf-diff
entry: yapf-diff
language: python
files: \.py$
minimum_pre_commit_version: 0.15.0# Check formatting in CI
yapf -r -d my_project/
if [ $? -ne 0 ]; then
echo "Code is not properly formatted"
exit 1
fi
# Format check with specific style
yapf -r -d --style=google src/{
"python.formatting.provider": "yapf",
"python.formatting.yapfArgs": ["--style=google"],
"editor.formatOnSave": true
}" Format current file with YAPF
nnoremap <leader>f :!yapf -i %<CR>
" Format selection
vnoremap <leader>f :!yapf<CR>0: Success (no errors)1: Error occurred (syntax error, file not found, etc.)--diff or --quiet: 0 if no changes needed, non-zero if changes found# Initial formatting
yapf -r -i --style=google my_project/
# Check if formatting needed
yapf -r -d my_project/
echo "Exit code: $?"# Format files modified in last commit
git diff --name-only HEAD~1 | grep '\.py$' | xargs yapf -i
# Format unstaged changes
git diff --name-only | grep '\.py$' | xargs yapf -i# Exclude generated and test files
yapf -r -i \
--exclude='*_pb2.py' \
--exclude='*_test.py' \
--exclude='test_*.py' \
--exclude='migrations/*.py' \
my_project/Install with Tessl CLI
npx tessl i tessl/pypi-yapf