CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-django-stubs-ext

Monkey-patching and extensions for django-stubs providing runtime type support for Django generic classes

Pending
Overview
Eval results
Files

monkey-patching.mddocs/

Runtime Monkey-Patching

The core functionality of django-stubs-ext that dynamically adds generic type support to Django classes at runtime. This system enables proper type parameterization for Django classes that don't natively support the __class_getitem__ method.

Capabilities

Main Patching Function

Applies runtime monkey-patches to Django classes for generic type support. This function should be called once in your Django application settings.

def monkeypatch(
    extra_classes: Optional[Iterable[type]] = None, 
    include_builtins: bool = True
) -> None:
    """
    Monkey patch Django as necessary to work properly with mypy.
    
    Parameters:
    - extra_classes: Optional iterable of additional classes to patch
    - include_builtins: Whether to add reveal_type and reveal_locals helpers
    
    Returns:
    None
    """

Usage Examples

Basic usage in Django settings:

# In your Django settings file
import django_stubs_ext

django_stubs_ext.monkeypatch()

With additional classes:

import django_stubs_ext
from my_app.models import CustomModel

# Patch additional classes
django_stubs_ext.monkeypatch(extra_classes=[CustomModel])

Without mypy helpers:

import django_stubs_ext

# Skip adding reveal_type and reveal_locals to builtins
django_stubs_ext.monkeypatch(include_builtins=False)

Supported Django Classes

The following Django classes are automatically patched when appropriate for the detected Django version:

Always Patched Classes

  • django.contrib.admin.ModelAdmin
  • django.views.generic.detail.SingleObjectMixin
  • django.views.generic.edit.FormMixin
  • django.views.generic.edit.DeletionMixin
  • django.views.generic.list.MultipleObjectMixin
  • django.contrib.admin.options.BaseModelAdmin
  • django.db.models.fields.Field
  • django.core.paginator.Paginator
  • django.forms.formsets.BaseFormSet
  • django.forms.models.BaseModelForm
  • django.forms.models.BaseModelFormSet
  • django.contrib.syndication.views.Feed
  • django.contrib.sitemaps.Sitemap
  • django.contrib.messages.views.SuccessMessageMixin
  • django.core.files.utils.FileProxyMixin
  • django.db.models.lookups.Lookup
  • django.utils.connection.BaseConnectionHandler
  • django.db.models.expressions.ExpressionWrapper

Version-Specific Classes

  • django.db.models.query.QuerySet (Django ≤ 3.1)
  • django.db.models.manager.BaseManager (Django ≤ 3.1)
  • django.db.models.fields.related.ForeignKey (Django ≤ 4.1)

Version Compatibility

The monkey-patching system automatically detects your Django version and only applies patches needed for your specific version:

from django import VERSION

# Only patch classes that need it for the current Django version
suited_for_this_version = filter(
    lambda spec: spec.version is None or VERSION[:2] <= spec.version,
    _need_generic,
)

Builtins Integration

When include_builtins=True (default), the following helpers are added to Python's builtins:

def reveal_type(obj: Any) -> None:
    """Mypy helper function for type inspection (no-op at runtime)."""

def reveal_locals() -> None:
    """Mypy helper function for local variable inspection (no-op at runtime)."""

Types

from typing import Any, Generic, Iterable, List, Optional, Tuple, Type, TypeVar

_T = TypeVar("_T")
_VersionSpec = Tuple[int, int]

class MPGeneric(Generic[_T]):
    """
    Metadata container for generic classes needing monkeypatching.
    
    The version param is optional, and None means version-independent patching.
    """
    
    def __init__(self, cls: Type[_T], version: Optional[_VersionSpec] = None) -> None:
        """Set the data fields, basic constructor."""
        
    def __repr__(self) -> str:
        """Better representation in tests and debug."""

Install with Tessl CLI

npx tessl i tessl/pypi-django-stubs-ext

docs

index.md

model-annotations.md

monkey-patching.md

protocols.md

queryset-types.md

string-types.md

tile.json