or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# PySnooper

1

2

A poor man's debugger for Python that provides elegant tracing without print statements. PySnooper offers an alternative to traditional debugging with breakpoints by decorating functions or wrapping code blocks to get detailed execution logs showing line-by-line execution, variable changes, and timing information.

3

4

## Package Information

5

6

- **Package Name**: PySnooper

7

- **Language**: Python

8

- **Installation**: `pip install pysnooper`

9

10

## Core Imports

11

12

```python

13

import pysnooper

14

```

15

16

## Basic Usage

17

18

```python

19

import pysnooper

20

21

# Decorator usage - trace entire function

22

@pysnooper.snoop()

23

def number_to_bits(number):

24

if number:

25

bits = []

26

while number:

27

number, remainder = divmod(number, 2)

28

bits.insert(0, remainder)

29

return bits

30

else:

31

return [0]

32

33

# Context manager usage - trace code block

34

def analyze_data():

35

data = [1, 2, 3, 4, 5]

36

37

with pysnooper.snoop():

38

minimum = min(data)

39

maximum = max(data)

40

average = sum(data) / len(data)

41

42

return minimum, maximum, average

43

44

# Output redirection to file

45

@pysnooper.snoop('/tmp/debug.log')

46

def process_data(items):

47

result = []

48

for item in items:

49

result.append(item * 2)

50

return result

51

```

52

53

## Capabilities

54

55

### Main Tracing Decorator

56

57

The primary debugging interface that can be used as both a decorator and context manager.

58

59

```python { .api }

60

class snoop:

61

def __init__(

62

self,

63

output=None,

64

watch=(),

65

watch_explode=(),

66

depth=1,

67

prefix='',

68

overwrite=False,

69

thread_info=False,

70

custom_repr=(),

71

max_variable_length=100,

72

normalize=False,

73

relative_time=False,

74

color=True

75

):

76

"""

77

Snoop on function execution, writing detailed logs to output.

78

79

Args:

80

output: Output destination - None (stderr), file path, stream, or callable

81

watch (tuple): Expressions to watch that aren't local variables

82

watch_explode (tuple): Expressions to expand/explode (show attributes/items)

83

depth (int): Tracing depth for nested function calls (default: 1)

84

prefix (str): Prefix string for all snoop output lines

85

overwrite (bool): Whether to overwrite output file (default: False)

86

thread_info (bool): Include thread information in output

87

custom_repr (tuple): Custom representation functions for objects

88

max_variable_length (int): Maximum length for variable representations (default: 100)

89

normalize (bool): Remove machine-specific data (paths, addresses, timestamps)

90

relative_time (bool): Show timestamps relative to start time

91

color (bool): Enable colored output (default: True on Linux/macOS)

92

"""

93

94

def __call__(self, function_or_class):

95

"""Use as decorator on functions or classes."""

96

97

def __enter__(self):

98

"""Use as context manager - enter tracing block."""

99

100

def __exit__(self, exc_type, exc_value, exc_traceback):

101

"""Use as context manager - exit tracing block."""

102

```

103

104

### Variable Helper Classes

105

106

Helper classes for advanced variable watching and expansion.

107

108

```python { .api }

109

class Attrs:

110

def __init__(self, source, exclude=()):

111

"""

112

Watch object attributes.

113

114

Args:

115

source (str): Variable expression to watch

116

exclude (tuple): Attribute names to exclude from watching

117

"""

118

119

class Keys:

120

def __init__(self, source, exclude=()):

121

"""

122

Watch dictionary/mapping keys and values.

123

124

Args:

125

source (str): Variable expression to watch

126

exclude (tuple): Keys to exclude from watching

127

"""

128

129

class Indices:

130

def __init__(self, source, exclude=()):

131

"""

132

Watch sequence indices and values with optional slicing.

133

134

Args:

135

source (str): Variable expression to watch

136

exclude (tuple): Indices to exclude from watching

137

"""

138

139

def __getitem__(self, slice_obj):

140

"""

141

Enable slicing syntax like Indices('list_var')[1:5].

142

143

Args:

144

slice_obj (slice): Slice object for limiting indices

145

146

Returns:

147

Indices: New Indices instance with slice applied

148

"""

149

150

class Exploding:

151

def __init__(self, source, exclude=()):

152

"""

153

Smart variable expander - automatically determines expansion method.

154

155

Args:

156

source (str): Variable expression to watch

157

exclude (tuple): Items to exclude from watching

158

159

Behavior:

160

- Uses Keys for mappings (dict-like objects)

161

- Uses Indices for sequences (list-like objects)

162

- Uses Attrs for other objects

163

"""

164

```

165

166

### Module Metadata

167

168

Version information for the package.

169

170

```python { .api }

171

__version__: str

172

# Version string (e.g., '1.2.3')

173

174

__version_info__: NamedTuple

175

# Structured version information with major, minor, micro fields

176

```

177

178

## Usage Examples

179

180

### File Output

181

182

Redirect tracing output to a file:

183

184

```python

185

@pysnooper.snoop('/my/log/file.log')

186

def process_data(data):

187

return [x * 2 for x in data]

188

```

189

190

### Watching Expressions

191

192

Monitor specific expressions that aren't local variables:

193

194

```python

195

@pysnooper.snoop(watch=('len(data)', 'data[0]', 'self.status'))

196

def analyze_list(self, data):

197

# Will show values of watched expressions

198

result = sum(data)

199

return result

200

```

201

202

### Variable Expansion

203

204

Expand objects to see their attributes or items:

205

206

```python

207

# Automatic expansion

208

@pysnooper.snoop(watch_explode=('obj', 'data_dict'))

209

def process_object(obj, data_dict):

210

return obj.process(data_dict)

211

212

# Specific expansion types

213

@pysnooper.snoop(watch=(

214

pysnooper.Attrs('obj'), # Object attributes

215

pysnooper.Keys('data_dict'), # Dictionary keys/values

216

pysnooper.Indices('items')[2:5], # List items with slicing

217

))

218

def detailed_processing(obj, data_dict, items):

219

return obj.transform(data_dict, items)

220

```

221

222

### Deep Tracing

223

224

Show snoop lines for functions called within traced functions:

225

226

```python

227

@pysnooper.snoop(depth=2)

228

def main_function():

229

helper_function() # This will also be traced

230

return "done"

231

232

def helper_function():

233

x = 42

234

return x * 2

235

```

236

237

### Multi-threading Support

238

239

Identify threads in multi-threaded applications:

240

241

```python

242

@pysnooper.snoop(thread_info=True)

243

def worker_function(task_id):

244

# Output will include thread information

245

return process_task(task_id)

246

```

247

248

### Custom Output Formatting

249

250

Customize how values are displayed:

251

252

```python

253

def custom_list_repr(obj):

254

if isinstance(obj, list) and len(obj) > 10:

255

return f'list(len={len(obj)})'

256

return repr(obj)

257

258

@pysnooper.snoop(

259

custom_repr=((lambda x: isinstance(x, list), custom_list_repr),),

260

max_variable_length=200,

261

prefix='DEBUG: ',

262

color=False

263

)

264

def process_large_data(big_list):

265

return sum(big_list)

266

```

267

268

### Class Decoration

269

270

Trace all methods in a class:

271

272

```python

273

@pysnooper.snoop()

274

class DataProcessor:

275

def __init__(self, data):

276

self.data = data

277

278

def process(self):

279

return [x * 2 for x in self.data]

280

281

def analyze(self):

282

return sum(self.data)

283

```

284

285

## Environment Variables

286

287

### PYSNOOPER_DISABLED

288

289

Disable all PySnooper tracing globally:

290

291

```bash

292

export PYSNOOPER_DISABLED=1

293

```

294

295

When set, all `@pysnooper.snoop()` decorators and context managers become no-ops.

296

297

## Error Handling

298

299

PySnooper is designed to be non-intrusive. If tracing encounters errors:

300

301

- Variable evaluation failures are silently ignored

302

- File output errors fall back to stderr

303

- Internal exceptions don't interrupt program execution

304

305

The traced code continues running normally even if tracing fails.

306

307

## Advanced Features

308

309

### Generator Support

310

311

PySnooper automatically detects and properly handles generator functions:

312

313

```python

314

@pysnooper.snoop()

315

def fibonacci_generator(n):

316

a, b = 0, 1

317

for _ in range(n):

318

yield a

319

a, b = b, a + b

320

```

321

322

### Lambda and Inline Function Support

323

324

Works with lambda functions and dynamically created functions:

325

326

```python

327

# Trace lambda execution

328

traced_lambda = pysnooper.snoop()(lambda x: x * 2)

329

result = traced_lambda(5)

330

```

331

332

### Context Manager Timing

333

334

Context manager usage shows elapsed time for code blocks:

335

336

```python

337

def analyze_performance():

338

data = list(range(1000))

339

340

with pysnooper.snoop():

341

# This block will show execution time

342

result = sum(x * x for x in data)

343

344

return result

345

```