or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-implementation.mdindex.mdipython-integration.mdoutput-capture.mdpermanent-redirection.mdsystem-integration.md

ipython-integration.mddocs/

0

# IPython Integration

1

2

Seamless integration with IPython and Jupyter notebooks through magic commands and extension loading, enabling automatic C-level output capture in interactive environments.

3

4

## Capabilities

5

6

### Extension Loading

7

8

Register wurlitzer as an IPython extension for automatic C output forwarding.

9

10

```python { .api }

11

def load_ipython_extension(ip):

12

"""Register wurlitzer as an IPython extension

13

14

Args:

15

ip: IPython instance

16

17

Note:

18

Captures all C output during execution and forwards to sys.

19

Does nothing on terminal IPython.

20

"""

21

```

22

23

Usage with magic command:

24

25

```python

26

# In IPython or Jupyter notebook

27

%load_ext wurlitzer

28

29

# All subsequent cell executions will capture C-level output

30

```

31

32

### Extension Unloading

33

34

Disable wurlitzer extension and restore original output behavior.

35

36

```python { .api }

37

def unload_ipython_extension(ip):

38

"""Unload wurlitzer IPython extension

39

40

Args:

41

ip: IPython instance

42

"""

43

```

44

45

Usage:

46

47

```python

48

# Disable the extension

49

%unload_ext wurlitzer

50

51

# C-level output is no longer captured

52

```

53

54

### Automatic Execution Hooks

55

56

The extension automatically hooks into IPython's execution cycle:

57

58

- **pre_execute**: Enables C output forwarding before each cell/command

59

- **post_execute**: Disables C output forwarding after each cell/command

60

61

This ensures C-level output appears in notebook cells without manual context managers.

62

63

## Usage Patterns

64

65

### Jupyter Notebook Setup

66

67

Enable wurlitzer in a notebook for the entire session:

68

69

```python

70

# First cell - setup

71

%load_ext wurlitzer

72

73

# Verify it's working

74

import ctypes

75

libc = ctypes.CDLL(None)

76

libc.printf(b"Hello from C!\n") # This will appear in cell output

77

```

78

79

### Scientific Computing Workflows

80

81

Capture output from scientific libraries with C extensions:

82

83

```python

84

# With wurlitzer extension loaded

85

import numpy as np

86

import scipy

87

88

# NumPy/SciPy C-level warnings and output appear in cells

89

result = np.linalg.solve(large_matrix, vector)

90

scipy_result = scipy.optimize.minimize(objective_function, initial_guess)

91

```

92

93

### Data Analysis Notebooks

94

95

Clean output capture for data processing pipelines:

96

97

```python

98

# Extension enabled at notebook start

99

%load_ext wurlitzer

100

101

import pandas as pd

102

import matplotlib.pyplot as plt

103

from some_c_library import process_data

104

105

# All C-level output from data processing appears inline

106

processed_data = process_data(raw_dataframe)

107

plt.plot(processed_data) # Any C output from matplotlib backends captured

108

```

109

110

### Development and Debugging

111

112

Interactive development with C extensions:

113

114

```python

115

# Debug session in Jupyter

116

%load_ext wurlitzer

117

118

# Test C extension interactively

119

import my_c_extension

120

121

# C debug output, warnings, and errors appear in notebook

122

my_c_extension.debug_function()

123

my_c_extension.test_algorithm(test_data)

124

```

125

126

## Environment Detection

127

128

The extension includes smart environment detection:

129

130

### Jupyter Kernel Detection

131

132

Only activates in Jupyter environments, not terminal IPython:

133

134

```python

135

# This code runs automatically when extension loads

136

if not getattr(ip, 'kernel', None):

137

warnings.warn("wurlitzer extension doesn't do anything in terminal IPython")

138

return

139

140

# Extension only works in Jupyter kernels

141

```

142

143

### Stream Validation

144

145

Validates that sys streams are available for forwarding:

146

147

```python

148

# Automatic validation during extension loading

149

for name in ("__stdout__", "__stderr__"):

150

if getattr(sys, name) is None:

151

warnings.warn(f"sys.{name} is None. Wurlitzer can't capture output without it.")

152

return

153

```

154

155

## Advanced Integration Patterns

156

157

### Conditional Loading

158

159

Load the extension based on environment or configuration:

160

161

```python

162

import os

163

164

# Load only in specific environments

165

if os.getenv('JUPYTER_ENABLE_WURLITZER', '').lower() == 'true':

166

%load_ext wurlitzer

167

print("Wurlitzer enabled for C output capture")

168

```

169

170

### Notebook Configuration

171

172

Add to IPython profile for automatic loading:

173

174

```python

175

# In ~/.ipython/profile_default/ipython_config.py

176

c.InteractiveShellApp.extensions = ['wurlitzer']

177

178

# Or in startup files

179

# ~/.ipython/profile_default/startup/00-wurlitzer.py

180

get_ipython().magic('load_ext wurlitzer')

181

```

182

183

### Custom Extension Integration

184

185

Combine with other IPython extensions:

186

187

```python

188

# Custom extension that includes wurlitzer

189

from IPython.core.magic import Magics, line_magic, magics_class

190

from wurlitzer import load_ipython_extension, unload_ipython_extension

191

192

@magics_class

193

class CustomMagics(Magics):

194

195

@line_magic

196

def enable_c_capture(self, line):

197

"""Enable C output capture"""

198

load_ipython_extension(self.shell)

199

print("C output capture enabled")

200

201

@line_magic

202

def disable_c_capture(self, line):

203

"""Disable C output capture"""

204

unload_ipython_extension(self.shell)

205

print("C output capture disabled")

206

207

# Register the custom extension

208

get_ipython().register_magic_function(CustomMagics)

209

```

210

211

### Widget Integration

212

213

Use with Jupyter widgets for interactive applications:

214

215

```python

216

import ipywidgets as widgets

217

from IPython.display import display

218

219

# Extension loaded

220

%load_ext wurlitzer

221

222

def on_button_click(b):

223

with widgets.Output():

224

# C output appears in widget output area

225

c_processing_function()

226

display("Processing complete")

227

228

button = widgets.Button(description="Run C Function")

229

button.on_click(on_button_click)

230

output = widgets.Output()

231

232

display(button, output)

233

```

234

235

## Error Handling

236

237

### Extension Loading Failures

238

239

Handle cases where extension cannot be loaded:

240

241

```python

242

try:

243

%load_ext wurlitzer

244

print("Wurlitzer extension loaded successfully")

245

except Exception as e:

246

print(f"Failed to load wurlitzer extension: {e}")

247

print("C output may not be captured in this environment")

248

```

249

250

### Fallback Strategies

251

252

Provide fallbacks when extension is not available:

253

254

```python

255

def setup_c_output_capture():

256

try:

257

get_ipython().magic('load_ext wurlitzer')

258

return True

259

except:

260

# Fallback to manual context managers

261

print("Using manual wurlitzer context managers")

262

return False

263

264

# Usage

265

auto_capture = setup_c_output_capture()

266

267

if not auto_capture:

268

# Manual capture when extension not available

269

from wurlitzer import sys_pipes

270

with sys_pipes():

271

c_function_call()

272

else:

273

# Extension handles capture automatically

274

c_function_call()

275

```

276

277

### State Management

278

279

Track extension state for complex notebooks:

280

281

```python

282

import wurlitzer

283

284

def check_extension_state():

285

"""Check if wurlitzer extension is currently active"""

286

return wurlitzer._extension_enabled

287

288

# Usage

289

if check_extension_state():

290

print("Wurlitzer extension is active")

291

# C output will be automatically captured

292

else:

293

print("Wurlitzer extension is not active")

294

# Need manual capture or load extension

295

```