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

framework-integration.mddocs/

Framework Integration

Plugin system for framework-specific debugging support including Django templates, Jinja2 templates, and custom debugging extensions. This system provides specialized debugging capabilities for web frameworks, template engines, and other Python frameworks that require custom debugging behavior.

Capabilities

Django Framework Debugging

Specialized debugging support for Django web applications, including template debugging, view debugging, and Django-specific breakpoint handling.

# Django debugging functionality from pydevd_plugins.django_debug

def add_django_exception_breakpoint(exception_type, notify_on_handled, notify_on_unhandled):
    """
    Add Django-specific exception breakpoint.
    
    Parameters:
    - exception_type (str): Django exception type (e.g., 'Http404', 'ValidationError')
    - notify_on_handled (bool): Break on handled Django exceptions
    - notify_on_unhandled (bool): Break on unhandled Django exceptions
    
    Returns:
    None
    """

def enable_django_template_debugging():
    """
    Enable debugging for Django templates.
    
    Allows setting breakpoints and stepping through Django template rendering.
    
    Returns:
    None
    """

def get_django_frame_locals(frame):
    """
    Extract Django-specific local variables from frame context.
    
    Parameters:
    - frame: Python frame object from Django code
    
    Returns:
    dict: Django-specific context variables and request information
    """

Jinja2 Template Debugging

Support for debugging Jinja2 templates with template-specific breakpoints and variable inspection.

# Jinja2 debugging functionality from pydevd_plugins.jinja2_debug

def enable_jinja2_template_debugging():
    """
    Enable debugging for Jinja2 templates.
    
    Allows setting breakpoints within template rendering and inspecting
    template context variables.
    
    Returns:
    None
    """

def add_jinja2_template_breakpoint(template_name, line_number):
    """
    Add breakpoint to Jinja2 template.
    
    Parameters:
    - template_name (str): Name/path of the Jinja2 template
    - line_number (int): Line number within the template
    
    Returns:
    bool: True if breakpoint was added successfully
    """

def get_jinja2_template_context(frame):
    """
    Extract Jinja2 template context variables from debugging frame.
    
    Parameters:
    - frame: Python frame object from Jinja2 template rendering
    
    Returns:
    dict: Template context variables and rendering state
    """

Line Validation Utilities

Utilities for validating breakpoint locations within different types of Python code and framework contexts.

# Line validation from pydevd_plugins.pydevd_line_validation

def is_valid_breakpoint_line(filename, line_number, framework_type=None):
    """
    Validate if a line is suitable for breakpoint placement.
    
    Parameters:
    - filename (str): Source file path
    - line_number (int): Line number to validate
    - framework_type (str, optional): Framework type ('django', 'jinja2', 'flask', etc.)
    
    Returns:
    bool: True if line can have a breakpoint, False otherwise
    """

def get_valid_breakpoint_lines(filename, start_line=1, end_line=None):
    """
    Get all valid breakpoint lines in a file.
    
    Parameters:
    - filename (str): Source file path
    - start_line (int): Starting line number (default: 1)
    - end_line (int, optional): Ending line number (default: end of file)
    
    Returns:
    list: List of line numbers where breakpoints can be set
    """

def validate_template_breakpoint(template_path, line_number, template_type):
    """
    Validate breakpoint placement in template files.
    
    Parameters:
    - template_path (str): Path to template file
    - line_number (int): Line number in template
    - template_type (str): Template type ('django', 'jinja2', 'mako', etc.)
    
    Returns:
    dict: Validation result with success status and mapped Python line
    
    Example return:
    {
        'valid': True,
        'python_line': 42,  # Corresponding line in compiled template
        'context': 'template_block',
        'reason': None  # or error message if not valid
    }
    """

Plugin Extension Framework

Base classes and utilities for creating custom debugging plugins for other frameworks.

# Extension framework from pydevd_plugins.extensions

class FrameworkDebugPlugin:
    """
    Base class for framework-specific debugging plugins.
    """
    
    def get_plugin_name(self):
        """
        Get the name of this debugging plugin.
        
        Returns:
        str: Plugin name identifier
        """
    
    def can_handle_frame(self, frame):
        """
        Check if this plugin can handle debugging for the given frame.
        
        Parameters:
        - frame: Python frame object
        
        Returns:
        bool: True if plugin can handle this frame context
        """
    
    def get_frame_variables(self, frame):
        """
        Extract framework-specific variables from frame.
        
        Parameters:
        - frame: Python frame object
        
        Returns:
        dict: Framework-specific variables and context information
        """
    
    def handle_breakpoint(self, breakpoint, frame):
        """
        Handle breakpoint hit in framework-specific context.
        
        Parameters:
        - breakpoint: Breakpoint object
        - frame: Python frame where breakpoint was hit
        
        Returns:
        dict: Framework-specific breakpoint handling result
        """
    
    def get_exception_context(self, exception, frame):
        """
        Get framework-specific context for exception handling.
        
        Parameters:
        - exception: Exception instance
        - frame: Python frame where exception occurred
        
        Returns:
        dict: Framework-specific exception context
        """

class TemplateDebugPlugin(FrameworkDebugPlugin):
    """
    Base class for template engine debugging plugins.
    """
    
    def get_template_info(self, frame):
        """
        Extract template information from debugging frame.
        
        Parameters:
        - frame: Python frame from template rendering
        
        Returns:
        dict: Template information including name, line mapping, and context
        """
    
    def map_template_line_to_python(self, template_path, template_line):
        """
        Map template line number to corresponding Python code line.
        
        Parameters:
        - template_path (str): Path to template file
        - template_line (int): Line number in template
        
        Returns:
        int: Corresponding line number in compiled Python code
        """

Usage Examples

Django Application Debugging

import pydevd
from pydevd_plugins import django_debug

# Set up PyDevD for Django debugging
pydevd.settrace('localhost', port=5678)

# Enable Django-specific debugging features
django_debug.enable_django_template_debugging()

# Add Django exception breakpoints
django_debug.add_django_exception_breakpoint(
    'Http404',
    notify_on_handled=True,
    notify_on_unhandled=True
)

django_debug.add_django_exception_breakpoint(
    'ValidationError',
    notify_on_handled=False,
    notify_on_unhandled=True
)

# Your Django application code
from django.http import HttpResponse
from django.shortcuts import render

def my_view(request):
    # This breakpoint will work with Django context
    context = {'user': request.user, 'data': 'example'}
    return render(request, 'my_template.html', context)

Jinja2 Template Debugging

import pydevd
from pydevd_plugins import jinja2_debug
from jinja2 import Environment, FileSystemLoader

# Set up debugging
pydevd.settrace('localhost', port=5678)
jinja2_debug.enable_jinja2_template_debugging()

# Set up Jinja2 environment
env = Environment(loader=FileSystemLoader('templates'))

# Add template breakpoint
jinja2_debug.add_jinja2_template_breakpoint('user_profile.html', 15)

# Render template (will hit breakpoint on line 15)
template = env.get_template('user_profile.html')
result = template.render(user={'name': 'John', 'age': 30})

Custom Framework Plugin

from pydevd_plugins.extensions import FrameworkDebugPlugin

class FlaskDebugPlugin(FrameworkDebugPlugin):
    """
    Custom debugging plugin for Flask applications.
    """
    
    def get_plugin_name(self):
        return "flask_debug"
    
    def can_handle_frame(self, frame):
        """Check if frame is from Flask code."""
        # Look for Flask-specific variables in frame
        return 'flask' in frame.f_globals.get('__name__', '') or \
               'app' in frame.f_locals and hasattr(frame.f_locals['app'], 'config')
    
    def get_frame_variables(self, frame):
        """Extract Flask-specific variables."""
        flask_vars = {}
        
        # Extract Flask app context
        if 'app' in frame.f_locals:
            app = frame.f_locals['app']
            flask_vars['flask_app_name'] = getattr(app, 'name', 'unknown')
            flask_vars['flask_config'] = dict(app.config) if hasattr(app, 'config') else {}
        
        # Extract request context if available
        try:
            from flask import request, g, session
            flask_vars['request_method'] = request.method
            flask_vars['request_url'] = request.url
            flask_vars['request_args'] = dict(request.args)
            flask_vars['session_data'] = dict(session)
            flask_vars['g_data'] = dict(g.__dict__)
        except:
            pass  # Not in request context
        
        return flask_vars
    
    def handle_breakpoint(self, breakpoint, frame):
        """Handle Flask-specific breakpoint behavior."""
        flask_context = self.get_frame_variables(frame)
        
        return {
            'plugin': self.get_plugin_name(),
            'context': flask_context,
            'additional_info': {
                'route_info': self._get_route_info(frame),
                'middleware_stack': self._get_middleware_info(frame)
            }
        }
    
    def _get_route_info(self, frame):
        """Extract current route information."""
        try:
            from flask import request
            return {
                'endpoint': request.endpoint,
                'view_args': request.view_args,
                'url_rule': str(request.url_rule)
            }
        except:
            return {}
    
    def _get_middleware_info(self, frame):
        """Extract middleware information."""
        # Implementation would depend on Flask app structure
        return {}

# Register the custom plugin
flask_plugin = FlaskDebugPlugin()

# Use in debugging session
import pydevd
pydevd.settrace('localhost', port=5678)

# The plugin will automatically be used when debugging Flask code

Template Debugging with Line Validation

from pydevd_plugins.pydevd_line_validation import (
    is_valid_breakpoint_line,
    get_valid_breakpoint_lines,
    validate_template_breakpoint
)

# Validate breakpoints in Python files
python_file = '/path/to/views.py'
if is_valid_breakpoint_line(python_file, 42, framework_type='django'):
    print("Line 42 is valid for Django breakpoint")

# Get all valid breakpoint lines
valid_lines = get_valid_breakpoint_lines(python_file, start_line=1, end_line=100)
print(f"Valid breakpoint lines: {valid_lines}")

# Validate template breakpoints
template_file = '/path/to/template.html'
validation_result = validate_template_breakpoint(
    template_file, 
    line_number=25, 
    template_type='django'
)

if validation_result['valid']:
    print(f"Template breakpoint valid, maps to Python line: {validation_result['python_line']}")
else:
    print(f"Template breakpoint invalid: {validation_result['reason']}")

Advanced Framework Integration

import pydevd
from pydevd_plugins.extensions import TemplateDebugPlugin

class CustomTemplateEngine(TemplateDebugPlugin):
    """
    Plugin for a custom template engine.
    """
    
    def get_plugin_name(self):
        return "custom_template_engine"
    
    def can_handle_frame(self, frame):
        """Check if frame is from our template engine."""
        return 'CUSTOM_TEMPLATE_MARKER' in frame.f_globals
    
    def get_template_info(self, frame):
        """Extract template information."""
        return {
            'template_name': frame.f_globals.get('TEMPLATE_NAME', 'unknown'),
            'template_line': frame.f_globals.get('TEMPLATE_LINE', 0),
            'template_context': frame.f_globals.get('TEMPLATE_CONTEXT', {})
        }
    
    def map_template_line_to_python(self, template_path, template_line):
        """Map template line to Python line."""
        # Custom mapping logic based on template compilation
        mapping = self._load_line_mapping(template_path)
        return mapping.get(template_line, template_line)
    
    def _load_line_mapping(self, template_path):
        """Load line mapping from template compilation metadata."""
        # Implementation would load mapping from compiled template metadata
        return {}

# Set up comprehensive framework debugging
pydevd.settrace('localhost', port=5678, suspend=False)

# Enable multiple framework debugging plugins
from pydevd_plugins import django_debug, jinja2_debug

django_debug.enable_django_template_debugging()
jinja2_debug.enable_jinja2_template_debugging()

# Register custom plugin
custom_plugin = CustomTemplateEngine()

print("Multi-framework debugging enabled")
print("- Django template debugging: enabled")
print("- Jinja2 template debugging: enabled") 
print("- Custom template engine: enabled")

Plugin Development Guidelines

Creating Framework Plugins

  1. Inherit from FrameworkDebugPlugin: Use the base class for consistent interface
  2. Frame Detection: Implement robust can_handle_frame() logic
  3. Variable Extraction: Provide meaningful framework-specific variable extraction
  4. Error Handling: Handle framework-specific exceptions gracefully
  5. Performance: Minimize overhead in frame inspection code

Template Engine Plugins

  1. Inherit from TemplateDebugPlugin: Use template-specific base class
  2. Line Mapping: Implement accurate template-to-Python line mapping
  3. Context Extraction: Extract template context variables effectively
  4. Compilation Integration: Work with template compilation processes
  5. Multi-Template Support: Handle nested and included templates

Plugin Registration

Plugins are typically auto-discovered or manually registered depending on the framework detection logic implemented in the plugin's can_handle_frame() method.

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