The uncompromising code formatter.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Specialized formatting functions for Jupyter notebooks and individual notebook cells, with support for IPython magics, cell-specific formatting rules, and notebook JSON structure handling.
Format individual Jupyter notebook cells with special handling for IPython magics and trailing semicolons.
def format_cell(src: str, *, fast: bool, mode: Mode) -> str:
"""
Format individual Jupyter notebook cell content.
Parameters:
- src: Cell source code to format
- fast: Skip AST safety checks if True
- mode: Mode configuration with is_ipynb=True recommended
Returns:
Formatted cell source code
Note:
- Handles IPython magics (%, %%, !, !!)
- Preserves trailing semicolons for output suppression
- Recognizes python_cell_magics configured in mode
Raises:
- InvalidInput: If cell source cannot be parsed
- NothingChanged: If no formatting changes needed
"""Format complete Jupyter notebook JSON strings, processing only Python code cells while preserving notebook structure.
def format_ipynb_string(src_contents: str, *, fast: bool, mode: Mode) -> str:
"""
Format complete Jupyter notebook JSON string.
Parameters:
- src_contents: Complete notebook JSON as string
- fast: Skip AST safety checks if True
- mode: Mode configuration controlling formatting
Returns:
Formatted notebook JSON string
Note:
- Only processes cells with Python kernels
- Preserves all notebook metadata and structure
- Handles cell magics and IPython-specific syntax
Raises:
- InvalidInput: If notebook JSON is invalid
- NothingChanged: If no formatting changes needed
"""Constants and utilities for handling IPython magic commands in notebook cells.
# Set of recognized Python cell magic commands
PYTHON_CELL_MAGICS: set[str]Common Python cell magics include:
%%time - Time execution of cell%%timeit - Benchmark cell execution%%capture - Capture cell output%%writefile - Write cell contents to file%%bash - Execute cell as bash script (when containing Python)%%python - Explicit Python execution%%script python - Script executionimport black
# Configure mode for Jupyter
mode = black.Mode(is_ipynb=True)
# Format a simple cell
cell_code = """
def calculate(x,y):
return x+y
result=calculate(5,3)
print(result)
"""
formatted_cell = black.format_cell(cell_code, fast=False, mode=mode)
print(formatted_cell)
# Output:
# def calculate(x, y):
# return x + y
#
# result = calculate(5, 3)
# print(result)# Cell with magic commands
magic_cell = """
%%time
import numpy as np
data=np.random.rand(1000,1000)
result=data.sum()
print(f"Sum: {result}")
"""
# Configure with custom cell magics
mode = black.Mode(
is_ipynb=True,
python_cell_magics={'%%time', '%%timeit', '%%capture', '%%writefile'}
)
formatted = black.format_cell(magic_cell, fast=False, mode=mode)
print(formatted)
# Output:
# %%time
# import numpy as np
#
# data = np.random.rand(1000, 1000)
# result = data.sum()
# print(f"Sum: {result}")# Cell with output suppression
suppressed_cell = """
import matplotlib.pyplot as plt
plt.plot([1,2,3],[4,5,6]);
plt.show();
"""
formatted = black.format_cell(suppressed_cell, fast=False, mode=mode)
print(formatted)
# Output:
# import matplotlib.pyplot as plt
#
# plt.plot([1, 2, 3], [4, 5, 6]);
# plt.show();
# Note: Semicolons preserved for output suppressionimport json
# Example notebook content
notebook_json = '''
{
"cells": [
{
"cell_type": "code",
"source": ["def hello(name):print(f'Hello {name}!')"],
"metadata": {},
"execution_count": null,
"outputs": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 4
}
'''
# Format the entire notebook
mode = black.Mode(is_ipynb=True, line_length=79)
try:
formatted_notebook = black.format_ipynb_string(notebook_json, fast=False, mode=mode)
# Parse to verify formatting
notebook_data = json.loads(formatted_notebook)
print("Formatted cell source:")
for cell in notebook_data['cells']:
if cell['cell_type'] == 'code':
print(''.join(cell['source']))
except black.NothingChanged:
print("Notebook already properly formatted")from pathlib import Path
# Format .ipynb file in place
notebook_path = Path("analysis.ipynb")
# Mode automatically detected from .ipynb extension
changed = black.format_file_in_place(
notebook_path,
fast=False,
mode=black.Mode(line_length=88), # is_ipynb set automatically
write_back=black.WriteBack.YES
)
if changed:
print(f"Formatted {notebook_path}")
else:
print(f"No changes needed for {notebook_path}")# Complex cell with multiple magics
complex_cell = '''
%load_ext autoreload
%autoreload 2
import pandas as pd
%%time
df = pd.read_csv("data.csv")
processed = df.groupby("category").sum()
!ls -la processed_data/
%%writefile output.py
print("Results saved")
'''
mode = black.Mode(
is_ipynb=True,
python_cell_magics={'%%time', '%%writefile'}
)
formatted = black.format_cell(complex_cell, fast=False, mode=mode)
print(formatted)
# Line magics (%) preserved, cell magics (%%) in python_cell_magics formatted# Define custom set of Python cell magics
custom_magics = {
'%%time',
'%%timeit',
'%%capture',
'%%writefile',
'%%bash', # If containing Python code
'%%script python',
'%%cython', # For Cython cells with Python syntax
}
mode = black.Mode(
is_ipynb=True,
python_cell_magics=custom_magics,
line_length=100 # Longer lines often preferred in notebooks
)
# Format with custom magic handling
formatted = black.format_cell(notebook_cell, fast=False, mode=mode)try:
# Cell with syntax errors
bad_cell = "def incomplete_function("
formatted = black.format_cell(bad_cell, fast=False, mode=mode)
except black.InvalidInput as e:
print(f"Cannot format cell: {e}")
# Handle syntax errors gracefullytry:
# Malformed notebook JSON
bad_notebook = '{"cells": invalid json}'
formatted = black.format_ipynb_string(bad_notebook, fast=False, mode=mode)
except (json.JSONDecodeError, black.InvalidInput) as e:
print(f"Invalid notebook format: {e}")# For use in IPython/Jupyter environments
def format_current_cell():
"""Format the current cell in Jupyter notebook."""
from IPython import get_ipython
ip = get_ipython()
if ip is None:
return "Not running in IPython"
# Get current cell content (implementation depends on Jupyter version)
cell_content = ip.user_ns.get('_i', '') # Last input
mode = black.Mode(is_ipynb=True)
try:
formatted = black.format_cell(cell_content, fast=False, mode=mode)
return formatted
except Exception as e:
return f"Formatting error: {e}"
# Use as magic command
%load_ext black # If black provides IPython extension
%black # Format current cell# Cell magic type
CellMagic = str
# Notebook cell content
CellSource = str | list[str]
# Complete notebook structure (simplified)
NotebookDict = dict[str, Any]Install with Tessl CLI
npx tessl i tessl/pypi-black