pkg pprint
Reflection-driven pretty printer for Mojo structs.
Reflection-driven pretty printer for Mojo structs.
- Zero boilerplate: works on any struct without implementing traits
- Configurable: custom indentation, depth limits, item limits
- Type annotations: optional
show_typesmode - JSON-style output: booleans as
true/false, strings quoted
Why pprint?
Mojo's built-in print() requires types to implement the Writable trait:
@fieldwise_init
struct Person(Copyable, Movable):
var name: String
var age: Int
def main():
var p = Person("Ada", 36)
print(p) # ERROR: 'Person' does not implement 'Writable'
With pprint, no trait implementation is required - it uses reflection to
inspect and format any struct automatically:
from pprint import pprint
def main():
var p = Person("Ada", 36)
pprint(p) # Works! No Writable needed
Requirements
pixi package manager
Installation
Add pprint to your project's pixi.toml:
[workspace]
channels = ["https://conda.modular.com/max-nightly", "conda-forge"]
preview = ["pixi-build"]
[dependencies]
pprint = { git = "https://github.com/ehsanmok/pprint.git" }
Then run:
pixi install
Quick Start
from pprint import pprint, PrettyPrinter
@fieldwise_init
struct Person(Copyable, Movable):
var name: String
var age: Int
def main():
var p = Person("Ada", 36)
pprint(p)
Output:
{
name: "Ada",
age: 36
}
API Reference
pprint() - Print to stdout
Print any value to stdout with pretty formatting. Like Python's pprint.pprint.
from pprint import pprint, PrettyPrinter
# Default formatting
pprint(my_struct)
# With custom configuration
var pp = PrettyPrinter(indent=4, show_types=True)
pprint(my_struct, pp)
pformat() - Format as String
Return a pretty-formatted string instead of printing. Like Python's pprint.pformat.
Useful for logging, string concatenation, or storing formatted output.
from pprint import pformat, PrettyPrinter
# Get formatted string
var s = pformat(my_struct)
print("Debug: " + s)
# With custom configuration
var pp = PrettyPrinter(indent=4)
var s = pformat(my_struct, pp)
PrettyPrinter - Configuration
All formatting options are controlled through PrettyPrinter:
var pp = PrettyPrinter(
indent=2, # Spaces per indent level (default: 2)
max_depth=6, # Max nesting depth before "..." (default: 6)
max_items=64, # Max fields shown before "..." (default: 64)
show_types=False, # Show type annotations (default: False)
compact=False, # Reserved for future use
)
| Option | Default | Description |
|---|---|---|
indent |
2 | Spaces per indentation level |
max_depth |
6 | Maximum nesting depth before "..." |
max_items |
64 | Maximum fields shown per struct |
show_types |
False | Append type annotations like <Int> |
compact |
False | Reserved for future single-line output |
Supported Types
| Type | Output Format | Example |
|---|---|---|
String |
Quoted with double quotes | "Ada" |
Int |
Numeric | 42, -10, 0 |
Bool |
Lowercase JSON-style | true, false |
Float64 |
Decimal | 3.14, 95.5 |
Float32 |
Decimal | 1.5 |
Float16 |
Decimal | 0.5 |
| Nested structs | Recursive with braces | { inner: { ... } } |
| Empty structs | Empty braces | {} |
| Unknown types | Placeholder | <unknown> |
Examples
Scalars
pprint and pformat work directly on scalar values:
from pprint import pformat
print(pformat(42)) # 42
print(pformat(True)) # true
print(pformat(3.14)) # 3.14
print(pformat("hello world")) # "hello world"
Nested Structs
Nested structs are formatted recursively with proper indentation:
from pprint import pprint
@fieldwise_init
struct Address(Copyable, Movable):
var city: String
var zip: Int
@fieldwise_init
struct Person(Copyable, Movable):
var name: String
var age: Int
var active: Bool
var score: Float64
var address: Address
def main():
var p = Person("Ada", 36, True, 95.5, Address("London", 12345))
pprint(p)
Output:
{
name: "Ada",
age: 36,
active: true,
score: 95.5,
address: {
city: "London",
zip: 12345
}
}
Type Annotations
Enable show_types=True to see type information after each value:
from pprint import pprint, PrettyPrinter
var pp = PrettyPrinter(show_types=True)
pprint(my_struct, pp)
Output:
{
name: "Ada" <String>,
age: 36 <Int>,
active: true <Bool>,
score: 95.5 <Float64>,
address: {
city: "London" <String>,
zip: 12345 <Int>
} <Address>
}
Custom Indentation
Control indent width for different readability needs:
from pprint import pprint, PrettyPrinter
# 4-space indent
pprint(my_struct, PrettyPrinter(indent=4))
# Minimal indent
pprint(my_struct, PrettyPrinter(indent=1))
Depth Limiting
Prevent overly deep output for complex nested structures:
from pprint import pprint, PrettyPrinter
# Truncate at depth 2 (shows "..." for deeper levels)
pprint(deeply_nested, PrettyPrinter(max_depth=2))
Output:
{
inner: {
inner: ...
}
}
Field Limiting
Limit the number of fields shown for structs with many fields:
from pprint import pprint, PrettyPrinter
# Show only first 3 fields, then "..."
pprint(large_struct, PrettyPrinter(max_items=3))
Using pformat for Logging
from pprint import pformat
def log_state[T: AnyType](label: String, value: T):
print("[LOG] " + label + ": " + pformat(value))
def main():
var config = AppConfig(...)
log_state("startup config", config)
Re-exports
Structs
| struct PrettyPrinter | Configuration for pretty printing, similar to Python's pprint.PrettyPrinter. |