CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pydevd

Comprehensive Python debugger backend for IDEs with remote debugging, breakpoints, variable inspection, and performance optimizations

Pending
Overview
Eval results
Files

ipython-integration.mddocs/

IPython Integration

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.

Capabilities

IPython Kernel Integration

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
    """

GUI Toolkit Event Loop Integration

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
    """

Qt Integration

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
    """

Matplotlib Integration

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
    """

Toolkit-Specific Input Hooks

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."""

Usage Examples

Basic IPython Debugging Setup

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)

Qt Application Debugging

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_()

Matplotlib Debugging

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()

Advanced IPython Integration

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)

Multi-GUI Toolkit Support

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')

Jupyter Notebook Debugging

# 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)

Configuration Options

GUI Backend Configuration

# 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'
}

Performance Considerations

  • Event Loop Integration: Minimal overhead added to GUI event loops
  • Input Hook Efficiency: Optimized input hooks for different toolkits
  • Matplotlib Backend: Some backends perform better than others for debugging
  • Memory Usage: IPython integration may increase memory usage during debugging
  • Threading: Proper thread safety for multi-threaded GUI applications

Install with Tessl CLI

npx tessl i tessl/pypi-pydevd

docs

core-debugging.md

file-system.md

framework-integration.md

index.md

interactive-console.md

ipython-integration.md

process-attachment.md

programmatic-api.md

tile.json