0
# Comments and Annotations
1
2
Functions for adding comments and annotations to pretty printed output. The comment system enables adding explanatory text and metadata to formatted output while maintaining proper layout and formatting.
3
4
## Capabilities
5
6
### Value Comments
7
8
Add comments to Python values that will be rendered alongside the value in the pretty printed output.
9
10
```python { .api }
11
def comment(value, comment_text):
12
"""
13
Annotate a value or Doc with a comment.
14
15
Parameters:
16
- value: Python value or Doc to annotate
17
- comment_text (str): Comment text to display
18
19
Returns:
20
- Annotated value or Doc with comment metadata
21
22
Notes:
23
- Comments are rendered next to the value in output
24
- Layout algorithm handles comment placement automatically
25
- Works with both Python values and Doc objects
26
"""
27
```
28
29
### Trailing Comments
30
31
Add trailing comments that appear after the last element in collections or function arguments, forcing multiline layout.
32
33
```python { .api }
34
def trailing_comment(value, comment_text):
35
"""
36
Annotate a value with trailing comment text.
37
38
Parameters:
39
- value: Python value to annotate
40
- comment_text (str): Comment text for trailing position
41
42
Returns:
43
- Annotated value with trailing comment metadata
44
45
Notes:
46
- Forces multiline layout as Python doesn't support inline comments
47
- Comment appears after last element in collections
48
- Particularly useful for indicating truncated or additional content
49
"""
50
```
51
52
## Usage Examples
53
54
### Basic Value Comments
55
56
```python
57
from prettyprinter import pprint, comment, trailing_comment
58
59
# Simple value comments
60
data = {
61
'version': comment('1.2.3', 'current release'),
62
'debug': comment(True, 'development mode'),
63
'max_connections': comment(100, 'production limit')
64
}
65
66
pprint(data)
67
# Output:
68
# {
69
# 'version': '1.2.3', # current release
70
# 'debug': True, # development mode
71
# 'max_connections': 100 # production limit
72
# }
73
```
74
75
### Collection Comments
76
77
```python
78
from prettyprinter import pprint, comment, trailing_comment
79
80
# List with comments
81
numbers = [
82
comment(42, 'the answer'),
83
comment(3.14159, 'pi approximation'),
84
comment(2.71828, 'e approximation')
85
]
86
87
pprint(numbers)
88
# Output:
89
# [
90
# 42, # the answer
91
# 3.14159, # pi approximation
92
# 2.71828 # e approximation
93
# ]
94
95
# Trailing comment for truncated data
96
large_dataset = trailing_comment(
97
list(range(10)),
98
'...and 990 more items'
99
)
100
101
pprint(large_dataset)
102
# Output:
103
# [
104
# 0,
105
# 1,
106
# 2,
107
# 3,
108
# 4,
109
# 5,
110
# 6,
111
# 7,
112
# 8,
113
# 9,
114
# # ...and 990 more items
115
# ]
116
```
117
118
### Dictionary Comments
119
120
```python
121
from prettyprinter import pprint, comment
122
123
# Comments on keys and values
124
config = {
125
comment('database_url', 'primary connection'): comment(
126
'postgresql://localhost/myapp',
127
'local development'
128
),
129
comment('redis_url', 'cache connection'): 'redis://localhost:6379',
130
'timeout': comment(30, 'seconds')
131
}
132
133
pprint(config, width=60)
134
# Output with comments on both keys and values
135
```
136
137
### Comments in Custom Pretty Printers
138
139
```python
140
from prettyprinter import register_pretty, pretty_call, comment
141
import datetime
142
143
class DatabaseConnection:
144
def __init__(self, host, port, database, connected=False):
145
self.host = host
146
self.port = port
147
self.database = database
148
self.connected = connected
149
self.last_used = datetime.datetime.now() if connected else None
150
151
@register_pretty(DatabaseConnection)
152
def pretty_db_connection(conn, ctx):
153
# Add status comments
154
if conn.connected:
155
status_comment = f'connected since {conn.last_used.strftime("%H:%M")}'
156
return comment(
157
pretty_call(ctx, DatabaseConnection,
158
conn.host, conn.port, conn.database,
159
connected=conn.connected),
160
status_comment
161
)
162
else:
163
return comment(
164
pretty_call(ctx, DatabaseConnection,
165
conn.host, conn.port, conn.database),
166
'disconnected'
167
)
168
169
# Usage
170
conn = DatabaseConnection('localhost', 5432, 'myapp', connected=True)
171
pprint(conn)
172
# DatabaseConnection('localhost', 5432, 'myapp', connected=True) # connected since 14:30
173
```
174
175
### Status and State Comments
176
177
```python
178
from prettyprinter import pprint, comment, trailing_comment
179
180
class Task:
181
def __init__(self, name, status='pending', priority=1):
182
self.name = name
183
self.status = status
184
self.priority = priority
185
186
# Add status-based comments
187
def commented_task(task):
188
status_comments = {
189
'pending': 'awaiting execution',
190
'running': 'in progress',
191
'completed': 'finished successfully',
192
'failed': 'execution failed'
193
}
194
195
return comment(task, status_comments.get(task.status, 'unknown status'))
196
197
tasks = [
198
commented_task(Task('backup_database', 'completed')),
199
commented_task(Task('send_emails', 'running')),
200
commented_task(Task('cleanup_logs', 'pending'))
201
]
202
203
pprint(tasks)
204
```
205
206
### Debug Information Comments
207
208
```python
209
from prettyprinter import pprint, comment
210
import sys
211
212
class DebugInfo:
213
def __init__(self, obj):
214
self.obj = obj
215
self.type_name = type(obj).__name__
216
self.memory_size = sys.getsizeof(obj)
217
self.object_id = id(obj)
218
219
def with_debug_info(obj):
220
"""Add debug information as comments."""
221
debug = DebugInfo(obj)
222
return comment(
223
obj,
224
f'{debug.type_name} id={debug.object_id} size={debug.memory_size}b'
225
)
226
227
# Debug output with memory and type info
228
data = with_debug_info([1, 2, 3, 4, 5])
229
pprint(data)
230
# [1, 2, 3, 4, 5] # list id=140123456789 size=104b
231
```
232
233
### Conditional Comments
234
235
```python
236
from prettyprinter import pprint, comment
237
import os
238
239
def conditional_comment(value, condition, comment_text):
240
"""Add comment only if condition is true."""
241
if condition:
242
return comment(value, comment_text)
243
return value
244
245
# Environment-based comments
246
config = {
247
'debug': conditional_comment(
248
True,
249
os.getenv('ENV') == 'development',
250
'development only'
251
),
252
'api_key': conditional_comment(
253
'sk-1234...',
254
os.getenv('SHOW_SECRETS') == 'true',
255
'sensitive data'
256
)
257
}
258
259
pprint(config)
260
```
261
262
### Multi-line Comments
263
264
```python
265
from prettyprinter import pprint, comment
266
267
# Long comments are automatically wrapped
268
data = comment(
269
{'complex': 'configuration'},
270
'This is a very long comment that describes complex configuration '
271
'options and will be automatically wrapped to multiple lines when '
272
'it exceeds the available width constraints during layout'
273
)
274
275
pprint(data, width=50)
276
# Output with properly wrapped multi-line comment
277
```
278
279
### Nested Comment Structures
280
281
```python
282
from prettyprinter import pprint, comment
283
284
# Comments within nested structures
285
project = {
286
'name': 'myproject',
287
'version': comment('2.1.0', 'latest stable'),
288
'dependencies': {
289
comment('requests', 'HTTP library'): comment('>=2.25.0', 'min version'),
290
comment('numpy', 'numerical computing'): '>=1.20.0',
291
'pytest': comment('>=6.0.0', 'testing framework')
292
},
293
'config': comment(
294
{
295
'timeout': 30,
296
'retries': comment(3, 'max attempts'),
297
'batch_size': comment(1000, 'optimized for memory')
298
},
299
'runtime configuration'
300
)
301
}
302
303
pprint(project, width=70)
304
# Nested structure with comments at multiple levels
305
```
306
307
### Comment Formatting Control
308
309
```python
310
from prettyprinter.doc import comment_doc, commentdoc
311
from prettyprinter import register_pretty
312
313
class AnnotatedValue:
314
def __init__(self, value, notes):
315
self.value = value
316
self.notes = notes
317
318
@register_pretty(AnnotatedValue)
319
def pretty_annotated_value(av, ctx):
320
# Custom comment formatting using low-level functions
321
value_doc = str(av.value)
322
323
# Create multi-line comment
324
comment_doc = commentdoc(' | '.join(av.notes))
325
326
return comment_doc(value_doc, comment_doc)
327
328
# Usage with custom comment formatting
329
annotated = AnnotatedValue(
330
42,
331
['the answer', 'to everything', 'according to Douglas Adams']
332
)
333
pprint(annotated)
334
```