Monkey-patching and extensions for django-stubs providing runtime type support for Django generic classes
—
Type aliases for Django's Promise-based string handling system, providing proper type safety for lazy string evaluation, internationalization, and template rendering. These types handle Django's deferred string evaluation system used throughout the framework.
Type alias for Django's Promise-based lazy string evaluation system, commonly used for internationalization and template rendering.
StrPromise = Promise
"""
Django Promise string type for lazy string evaluation.
In TYPE_CHECKING mode: Resolves to _StrPromise from django-stubs
At runtime: Django's Promise class for lazy string evaluation
"""Union type that handles both regular strings and Django Promise objects, providing flexibility for functions that accept either immediate or lazy string values.
StrOrPromise = Union[str, StrPromise]
"""
Union type for string or Promise types.
Accepts both:
- Regular Python strings (str)
- Django Promise objects for lazy evaluation
"""Internationalization with lazy strings:
from django_stubs_ext import StrOrPromise, StrPromise
from django.utils.translation import gettext_lazy as _
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=100)
def get_display_name(self) -> StrOrPromise:
"""Return localized category name."""
name_mapping = {
'electronics': _('Electronics'),
'clothing': _('Clothing & Fashion'),
'books': _('Books & Media')
}
return name_mapping.get(self.name, self.name)
# Usage with lazy strings
category = Category.objects.get(name='electronics')
display_name: StrOrPromise = category.get_display_name()
# Can be used in contexts expecting strings
print(f"Category: {display_name}") # Evaluates Promise at print timeTemplate context and form handling:
from django_stubs_ext import StrOrPromise
from django import forms
from django.utils.translation import gettext_lazy as _
class ContactForm(forms.Form):
name = forms.CharField(
label=_('Full Name'),
help_text=_('Enter your complete name')
)
email = forms.EmailField(
label=_('Email Address'),
help_text=_('We will not share your email')
)
def get_field_label(self, field_name: str) -> StrOrPromise:
"""Get the label for a form field."""
field = self.fields.get(field_name)
if field and field.label:
return field.label
return field_name.replace('_', ' ').title()
# Type-safe field label access
form = ContactForm()
name_label: StrOrPromise = form.get_field_label('name')Model verbose names and metadata:
from django_stubs_ext import StrOrPromise
from django.db import models
from django.utils.translation import gettext_lazy as _
class Article(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
class Meta:
verbose_name: StrOrPromise = _('Article')
verbose_name_plural: StrOrPromise = _('Articles')
def get_status_display(self) -> StrOrPromise:
"""Get human-readable status."""
status_choices = {
'draft': _('Draft'),
'published': _('Published'),
'archived': _('Archived')
}
return status_choices.get(self.status, _('Unknown'))
# Type-safe metadata access
article = Article()
verbose_name: StrOrPromise = article._meta.verbose_name
status_display: StrOrPromise = article.get_status_display()The string type aliases adapt their behavior based on the execution context:
import typing
from django.utils.functional import Promise
if typing.TYPE_CHECKING:
# Static type checking mode - use django-stubs definitions
from django.utils.functional import _StrPromise as StrPromise
from django.utils.functional import _StrOrPromise as StrOrPromise
else:
# Runtime mode - use actual Django classes
StrPromise = Promise
StrOrPromise = typing.Union[str, StrPromise]Use these types to properly annotate functions that work with Django's string system:
from django_stubs_ext import StrOrPromise
from django.utils.html import format_html
from django.utils.safestring import SafeString
def create_notification(
title: StrOrPromise,
message: StrOrPromise,
level: str = 'info'
) -> SafeString:
"""Create a formatted notification message."""
return format_html(
'<div class="alert alert-{level}"><h4>{title}</h4><p>{message}</p></div>',
level=level,
title=title,
message=message
)
# Works with both regular strings and lazy strings
from django.utils.translation import gettext_lazy as _
# Regular strings
notification1 = create_notification("Success", "Operation completed")
# Lazy strings for internationalization
notification2 = create_notification(
_("Error"),
_("An error occurred while processing your request")
)import typing
from typing import Union
from django.utils.functional import Promise
if typing.TYPE_CHECKING:
from django.utils.functional import _StrPromise as StrPromise
from django.utils.functional import _StrOrPromise as StrOrPromise
else:
StrPromise = Promise
StrOrPromise = Union[str, StrPromise]Install with Tessl CLI
npx tessl i tessl/pypi-django-stubs-ext