0
# Debug System
1
2
Enhanced debug printing system that automatically extracts variable names, displays types and metadata, shows source location, and provides syntax highlighting with intelligent pretty formatting. The debug system uses the `executing` library to inspect the call stack and extract variable names from the source code.
3
4
## Capabilities
5
6
### Debug Function
7
8
The main debug function automatically extracts variable names from source code and displays them with their values, types, and additional metadata.
9
10
```python { .api }
11
def debug(*args, file_=None, flush_=True, frame_depth_=2, **kwargs):
12
"""
13
Debug print with automatic variable name extraction and context.
14
15
Parameters:
16
- *args: Variables to debug print
17
- file_: Output file (default: stdout)
18
- flush_: Flush output buffer (default: True)
19
- frame_depth_: Stack frame depth for inspection (default: 2)
20
- **kwargs: Named variables to debug print
21
22
Returns:
23
Single arg: returns the argument itself
24
Multiple args: returns tuple of arguments
25
With kwargs: returns (*args, kwargs)
26
"""
27
```
28
29
Usage examples:
30
31
```python
32
from devtools import debug
33
34
# Basic variable debugging
35
name = "Alice"
36
age = 30
37
debug(name, age)
38
# Output: example.py:5 <module>:
39
# name: 'Alice' (str) len=5
40
# age: 30 (int)
41
42
# Debug complex data structures
43
data = {'users': [1, 2, 3], 'config': {'debug': True}}
44
debug(data)
45
# Output: example.py:9 <module>:
46
# data: {
47
# 'users': [1, 2, 3],
48
# 'config': {'debug': True},
49
# } (dict) len=2
50
51
# Debug with expressions
52
numbers = [1, 2, 3, 4, 5]
53
debug(len(numbers), sum(numbers))
54
# Output: example.py:13 <module>:
55
# len(numbers): 5 (int)
56
# sum(numbers): 15 (int)
57
58
# Named keyword arguments
59
debug(total=sum(numbers), average=sum(numbers)/len(numbers))
60
# Output: example.py:15 <module>:
61
# total: 15 (int)
62
# average: 3.0 (float)
63
```
64
65
### Debug Class
66
67
Configurable debug class that allows customization of warning display and syntax highlighting behavior.
68
69
```python { .api }
70
class Debug:
71
"""
72
Configurable debug print class.
73
"""
74
def __init__(self, warnings=None, highlight=None):
75
"""
76
Initialize Debug instance.
77
78
Parameters:
79
- warnings: Show warnings (None uses PY_DEVTOOLS_WARNINGS env var, default True)
80
- highlight: Enable syntax highlighting (None uses auto-detection)
81
"""
82
83
def __call__(self, *args, file_=None, flush_=True, frame_depth_=2, **kwargs):
84
"""
85
Debug print with automatic variable name extraction.
86
87
Parameters:
88
- *args: Variables to debug print
89
- file_: Output file (default: stdout)
90
- flush_: Flush output buffer (default: True)
91
- frame_depth_: Stack frame depth for inspection (default: 2)
92
- **kwargs: Named variables to debug print
93
94
Returns:
95
Single arg: the arg itself
96
Multiple args: tuple of args
97
With kwargs: (*args, kwargs)
98
"""
99
100
def format(self, *args, frame_depth_=2, **kwargs) -> DebugOutput:
101
"""
102
Format debug output without printing.
103
104
Parameters:
105
- *args: Variables to format
106
- frame_depth_: Stack frame depth for inspection (default: 2)
107
- **kwargs: Named variables to format
108
109
Returns:
110
DebugOutput object containing formatted debug information
111
"""
112
113
def breakpoint(self) -> None:
114
"""
115
Set a breakpoint using pdb, skipping devtools frames.
116
"""
117
118
def timer(self, name=None, verbose=True, file=None, dp=3) -> Timer:
119
"""
120
Create and return a Timer instance.
121
122
Parameters:
123
- name: Timer name (optional)
124
- verbose: Print timing results (default: True)
125
- file: Output file (default: stdout)
126
- dp: Decimal places for timing display (default: 3)
127
128
Returns:
129
Timer instance configured with the specified parameters
130
"""
131
```
132
133
Usage examples:
134
135
```python
136
from devtools import Debug
137
138
# Create custom debug instance without warnings
139
quiet_debug = Debug(warnings=False)
140
quiet_debug(some_variable)
141
142
# Create debug instance with forced highlighting
143
colored_debug = Debug(highlight=True)
144
colored_debug(data_structure)
145
146
# Format without printing
147
debug_output = debug.format(variable_name)
148
formatted_string = debug_output.str(highlight=True)
149
print(f"Custom prefix: {formatted_string}")
150
151
# Use integrated timer
152
with debug.timer('operation'):
153
# Some code to time
154
pass
155
```
156
157
### Debug Output Classes
158
159
Classes representing formatted debug output and individual arguments.
160
161
```python { .api }
162
class DebugOutput:
163
"""
164
Represents formatted debug output containing file context and arguments.
165
"""
166
def __init__(self, filename: str, lineno: int, frame: str, arguments: list[DebugArgument], warning: str | bool | None = None):
167
"""
168
Initialize DebugOutput.
169
170
Parameters:
171
- filename: Source file path
172
- lineno: Line number in source file
173
- frame: Function/method name
174
- arguments: List of DebugArgument instances
175
- warning: Warning message or None
176
"""
177
178
def str(self, highlight: bool = False) -> str:
179
"""
180
Format debug output as string.
181
182
Parameters:
183
- highlight: Apply syntax highlighting
184
185
Returns:
186
Formatted debug output string
187
"""
188
189
def __str__(self) -> str:
190
"""String representation of debug output."""
191
192
def __repr__(self) -> str:
193
"""Detailed representation for debugging."""
194
195
class DebugArgument:
196
"""
197
Represents a single debug argument with name, value, and metadata.
198
"""
199
def __init__(self, value, name: str | None = None, **extra):
200
"""
201
Initialize DebugArgument.
202
203
Parameters:
204
- value: The argument value
205
- name: Variable name (extracted from source)
206
- **extra: Additional metadata (e.g., length for sequences)
207
"""
208
209
def str(self, highlight: bool = False) -> str:
210
"""
211
Format argument as string.
212
213
Parameters:
214
- highlight: Apply syntax highlighting
215
216
Returns:
217
Formatted argument string with name, value, type, and metadata
218
"""
219
220
def __str__(self) -> str:
221
"""String representation of debug argument."""
222
```
223
224
### Integration with Pretty Printing
225
226
The debug system integrates seamlessly with devtools' pretty printing capabilities:
227
228
```python
229
# Debug automatically uses pretty printing for complex structures
230
nested_data = {
231
'level1': {
232
'level2': ['item1', 'item2', 'item3'],
233
'numbers': list(range(10))
234
}
235
}
236
debug(nested_data)
237
# Output shows nicely formatted nested structure with proper indentation
238
```
239
240
### Error Handling
241
242
The debug system gracefully handles various error conditions:
243
244
- **Call stack too shallow**: Falls back to basic argument display
245
- **Code inspection failure**: Shows warning and displays values without names
246
- **Pretty printing errors**: Shows repr() with error message
247
- **File access issues**: Uses absolute paths when relative paths fail
248
249
```python
250
# Debug works even when code inspection fails
251
debug(some_variable) # May show warning but still displays the value
252
```
253
254
### Environment Variables
255
256
Debug behavior can be customized via environment variables:
257
258
- `PY_DEVTOOLS_WARNINGS`: Show/hide warnings (default: True)
259
- `PY_DEVTOOLS_HIGHLIGHT`: Force highlighting on/off
260
- `PY_DEVTOOLS_INDENT`: Indentation for pretty printing (default: 4)
261
- `PY_DEVTOOLS_WIDTH`: Output width (default: 120)
262
263
## Types
264
265
```python { .api }
266
# Main debug instance - pre-configured Debug() instance
267
debug: Debug
268
269
# Type aliases used internally
270
StrType = str # String type alias for type hinting
271
```