Comprehensive Python debugger backend for IDEs with remote debugging, breakpoints, variable inspection, and performance optimizations
—
Integration with IPython kernels and GUI toolkits for debugging interactive computing environments. This module supports matplotlib, Qt applications, and other GUI frameworks commonly used in scientific computing, data analysis, and interactive development workflows.
Core functionality for integrating PyDevD with IPython kernels and Jupyter notebooks.
# IPython kernel integration utilities
def setup_ipython_debugging(kernel=None):
"""
Set up debugging support for IPython kernel.
Parameters:
- kernel: IPython kernel instance (auto-detected if None)
Returns:
None
"""
def enable_ipython_breakpoints():
"""
Enable breakpoint support in IPython environments.
Allows using debugger breakpoints within IPython cells and notebooks.
Returns:
None
"""
def get_ipython_frame_context(frame):
"""
Extract IPython-specific context from debugging frame.
Parameters:
- frame: Python frame object from IPython execution
Returns:
dict: IPython context including cell information, magic commands, and variables
"""Input hook management for various GUI toolkits to ensure proper event loop integration during debugging.
# GUI toolkit integration from pydev_ipython.inputhook
def enable_gui(gui=None):
"""
Enable GUI event loop integration for debugging.
Parameters:
- gui (str, optional): GUI toolkit ('qt', 'qt4', 'qt5', 'tk', 'gtk', 'wx', 'osx')
Returns:
None
"""
def disable_gui():
"""
Disable GUI event loop integration.
Returns:
None
"""
def set_inputhook(callback):
"""
Set custom input hook for GUI integration.
Parameters:
- callback: Function to call during input waiting
Returns:
None
"""
def clear_inputhook():
"""
Clear the current input hook.
Returns:
None
"""Specialized support for Qt applications (PyQt4, PyQt5, PySide, PySide2) in debugging environments.
# Qt integration from pydev_ipython.qt and pydev_ipython.qt_for_kernel
def create_qapp_for_debugging():
"""
Create QApplication instance suitable for debugging.
Returns:
QApplication: Qt application instance configured for debugging
"""
def setup_qt_debugging(app=None):
"""
Set up Qt application for debugging integration.
Parameters:
- app: QApplication instance (created if None)
Returns:
None
"""
def enable_qt_inputhook():
"""
Enable Qt input hook for event loop integration.
Returns:
None
"""
def process_qt_events():
"""
Process pending Qt events during debugging.
Returns:
None
"""Tools for debugging matplotlib-based plotting and visualization code.
# Matplotlib integration from pydev_ipython.matplotlibtools
def configure_matplotlib_backend(backend='Qt5Agg'):
"""
Configure matplotlib backend for debugging compatibility.
Parameters:
- backend (str): Matplotlib backend name
Returns:
None
"""
def enable_matplotlib_debugging():
"""
Enable debugging support for matplotlib plotting.
Ensures plots remain interactive during debugging sessions.
Returns:
None
"""
def show_plot_in_debugger(figure=None):
"""
Display matplotlib plot in debugging-compatible mode.
Parameters:
- figure: Matplotlib figure instance (current figure if None)
Returns:
None
"""
def get_matplotlib_figures():
"""
Get all active matplotlib figures for debugging inspection.
Returns:
list: List of active matplotlib figure objects
"""Individual input hook implementations for different GUI toolkits.
# Toolkit-specific hooks from pydev_ipython.inputhook*
def inputhook_qt4():
"""Qt4/PyQt4 input hook implementation."""
def inputhook_qt5():
"""Qt5/PyQt5 input hook implementation."""
def inputhook_tk():
"""Tkinter input hook implementation."""
def inputhook_gtk():
"""GTK input hook implementation."""
def inputhook_wx():
"""wxPython input hook implementation."""
def inputhook_osx():
"""macOS Cocoa input hook implementation."""import pydevd
from pydev_ipython import setup_ipython_debugging, enable_ipython_breakpoints
# Set up PyDevD for IPython
pydevd.settrace('localhost', port=5678, suspend=False)
# Enable IPython-specific debugging features
setup_ipython_debugging()
enable_ipython_breakpoints()
# Now you can use breakpoints in IPython cells
def analyze_data(data):
import pandas as pd
df = pd.DataFrame(data)
# This breakpoint will work in Jupyter notebook
breakpoint() # or pydevd.set_trace()
result = df.describe()
return result
# Example usage in notebook cell
data = {'x': [1, 2, 3, 4, 5], 'y': [2, 4, 6, 8, 10]}
analysis = analyze_data(data)import sys
import pydevd
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton
from pydev_ipython.qt import setup_qt_debugging, enable_qt_inputhook
# Set up debugging first
pydevd.settrace('localhost', port=5678, suspend=False)
class DebugMainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.setWindowTitle('Qt Debugging Example')
self.setGeometry(300, 300, 300, 200)
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout()
central_widget.setLayout(layout)
button = QPushButton('Click me for debugging')
button.clicked.connect(self.on_button_click)
layout.addWidget(button)
def on_button_click(self):
# This breakpoint will work with Qt event loop
print("Button clicked - setting breakpoint")
import pydevd; pydevd.set_trace()
# Debug Qt application state
print(f"Window title: {self.windowTitle()}")
print(f"Window size: {self.size()}")
# Create Qt application
app = QApplication(sys.argv)
# Set up Qt debugging integration
setup_qt_debugging(app)
enable_qt_inputhook()
# Create and show main window
window = DebugMainWindow()
window.show()
# Start event loop (debugging will work properly)
app.exec_()import numpy as np
import matplotlib.pyplot as plt
import pydevd
from pydev_ipython.matplotlibtools import (
configure_matplotlib_backend,
enable_matplotlib_debugging,
show_plot_in_debugger
)
# Set up debugging
pydevd.settrace('localhost', port=5678, suspend=False)
# Configure matplotlib for debugging
configure_matplotlib_backend('Qt5Agg')
enable_matplotlib_debugging()
def debug_plot_creation():
# Generate sample data
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.cos(x)
# Set breakpoint before plotting
import pydevd; pydevd.set_trace()
# Create plots (debugger can inspect data here)
plt.figure(figsize=(10, 6))
plt.subplot(2, 1, 1)
plt.plot(x, y1, 'b-', label='sin(x)')
plt.legend()
plt.grid(True)
plt.subplot(2, 1, 2)
plt.plot(x, y2, 'r-', label='cos(x)')
plt.legend()
plt.grid(True)
# Show plot in debugging-compatible mode
show_plot_in_debugger()
return plt.gcf() # Return current figure
# Create and debug plots
figure = debug_plot_creation()import pydevd
from pydev_ipython import (
setup_ipython_debugging,
enable_ipython_breakpoints,
get_ipython_frame_context
)
class IPythonDebugManager:
def __init__(self, debugger_port=5678):
self.debugger_port = debugger_port
self.debugging_active = False
def start_debugging(self):
"""Start IPython debugging session."""
try:
# Set up basic debugging
pydevd.settrace(
'localhost',
port=self.debugger_port,
suspend=False,
trace_only_current_thread=False
)
# Enable IPython-specific features
setup_ipython_debugging()
enable_ipython_breakpoints()
self.debugging_active = True
print(f"✓ IPython debugging started on port {self.debugger_port}")
except Exception as e:
print(f"Failed to start IPython debugging: {e}")
def debug_cell_execution(self, cell_code):
"""Debug IPython cell execution with context inspection."""
if not self.debugging_active:
print("Debugging not active. Call start_debugging() first.")
return
print(f"Executing cell with debugging:\n{cell_code}")
# Add debugging context
debug_wrapper = f"""
import pydevd
import sys
from pydev_ipython import get_ipython_frame_context
def debug_cell():
frame = sys._getframe()
context = get_ipython_frame_context(frame)
print(f"IPython context: {{context}}")
# Set breakpoint before user code
pydevd.set_trace()
# User cell code
{cell_code}
debug_cell()
"""
# Execute wrapped code
try:
exec(debug_wrapper, globals())
except Exception as e:
print(f"Cell execution error: {e}")
def stop_debugging(self):
"""Stop debugging session."""
if self.debugging_active:
pydevd.stoptrace()
self.debugging_active = False
print("Debugging stopped")
# Usage example
debug_manager = IPythonDebugManager(debugger_port=5678)
debug_manager.start_debugging()
# Example cell to debug
sample_cell = """
import pandas as pd
import numpy as np
# Create sample data
data = {
'name': ['Alice', 'Bob', 'Charlie'],
'age': [25, 30, 35],
'score': [95, 87, 92]
}
df = pd.DataFrame(data)
print("DataFrame created:")
print(df)
# Perform analysis
mean_age = df['age'].mean()
max_score = df['score'].max()
print(f"Mean age: {mean_age}")
print(f"Max score: {max_score}")
"""
# Debug the cell
debug_manager.debug_cell_execution(sample_cell)import pydevd
from pydev_ipython.inputhook import enable_gui, disable_gui
def setup_multi_gui_debugging():
"""Set up debugging for multiple GUI toolkits."""
# Start debugging
pydevd.settrace('localhost', port=5678, suspend=False)
# Detect and configure available GUI toolkits
available_guis = []
try:
import PyQt5
available_guis.append('qt5')
except ImportError:
pass
try:
import tkinter
available_guis.append('tk')
except ImportError:
pass
try:
import matplotlib
available_guis.append('matplotlib')
except ImportError:
pass
print(f"Available GUI toolkits: {available_guis}")
# Enable primary GUI (Qt5 preferred)
if 'qt5' in available_guis:
enable_gui('qt5')
print("Qt5 GUI integration enabled")
elif 'tk' in available_guis:
enable_gui('tk')
print("Tkinter GUI integration enabled")
return available_guis
def switch_gui_backend(gui_name):
"""Switch to different GUI backend during debugging."""
try:
disable_gui()
enable_gui(gui_name)
print(f"Switched to {gui_name} GUI backend")
except Exception as e:
print(f"Failed to switch to {gui_name}: {e}")
# Set up multi-GUI debugging
available = setup_multi_gui_debugging()
# Example: Switch between GUI backends
if 'qt5' in available and 'tk' in available:
# Start with Qt5
print("Starting with Qt5...")
# Switch to Tkinter
switch_gui_backend('tk')
# Switch back to Qt5
switch_gui_backend('qt5')# Cell 1: Setup debugging
import pydevd
from pydev_ipython import setup_ipython_debugging, enable_ipython_breakpoints
pydevd.settrace('localhost', port=5678, suspend=False)
setup_ipython_debugging()
enable_ipython_breakpoints()
print("Debugging enabled for Jupyter notebook")
# Cell 2: Debug data processing
def process_notebook_data():
import pandas as pd
import numpy as np
# Create sample dataset
np.random.seed(42)
data = {
'feature1': np.random.normal(0, 1, 1000),
'feature2': np.random.normal(0, 1, 1000),
'target': np.random.choice([0, 1], 1000)
}
df = pd.DataFrame(data)
# Set breakpoint for data inspection
import pydevd; pydevd.set_trace()
# Data analysis (debugger can inspect here)
correlation = df.corr()
summary_stats = df.describe()
return df, correlation, summary_stats
# Execute with debugging
df, corr, stats = process_notebook_data()
# Cell 3: Debug visualization
import matplotlib.pyplot as plt
from pydev_ipython.matplotlibtools import enable_matplotlib_debugging
enable_matplotlib_debugging()
def create_debug_plots(dataframe):
# Set breakpoint before plotting
import pydevd; pydevd.set_trace()
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2, figsize=(12, 10))
# Plot 1: Feature distribution
ax1.hist(dataframe['feature1'], bins=30, alpha=0.7)
ax1.set_title('Feature 1 Distribution')
# Plot 2: Feature correlation
ax2.scatter(dataframe['feature1'], dataframe['feature2'], alpha=0.5)
ax2.set_title('Feature Correlation')
# Plot 3: Target distribution
target_counts = dataframe['target'].value_counts()
ax3.bar(target_counts.index, target_counts.values)
ax3.set_title('Target Distribution')
# Plot 4: Box plot
ax4.boxplot([dataframe['feature1'], dataframe['feature2']],
labels=['Feature 1', 'Feature 2'])
ax4.set_title('Feature Box Plots')
plt.tight_layout()
plt.show()
return fig
# Create plots with debugging
figure = create_debug_plots(df)# Available GUI backends
GUI_BACKENDS = {
'qt4': 'PyQt4/PySide',
'qt5': 'PyQt5/PySide2',
'tk': 'Tkinter',
'gtk': 'GTK+',
'wx': 'wxPython',
'osx': 'macOS Cocoa'
}
# Matplotlib backend mapping
MATPLOTLIB_BACKENDS = {
'qt4': 'Qt4Agg',
'qt5': 'Qt5Agg',
'tk': 'TkAgg',
'gtk': 'GTK3Agg',
'wx': 'WXAgg',
'osx': 'MacOSX'
}Install with Tessl CLI
npx tessl i tessl/pypi-pydevd