Refs #27795 -- Replaced many force_text() with str()

Thanks Tim Graham for the review.
This commit is contained in:
Claude Paroz 2017-04-21 19:52:26 +02:00
parent 8ab7ce8558
commit 301de774c2
47 changed files with 135 additions and 181 deletions

View File

@ -8,7 +8,6 @@ from django.contrib.admin.utils import get_deleted_objects, model_ngettext
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.db import router from django.db import router
from django.template.response import TemplateResponse from django.template.response import TemplateResponse
from django.utils.encoding import force_text
from django.utils.translation import gettext as _, gettext_lazy from django.utils.translation import gettext as _, gettext_lazy
@ -44,7 +43,7 @@ def delete_selected(modeladmin, request, queryset):
n = queryset.count() n = queryset.count()
if n: if n:
for obj in queryset: for obj in queryset:
obj_display = force_text(obj) obj_display = str(obj)
modeladmin.log_deletion(request, obj, obj_display) modeladmin.log_deletion(request, obj, obj_display)
queryset.delete() queryset.delete()
modeladmin.message_user(request, _("Successfully deleted %(count)d %(items)s.") % { modeladmin.message_user(request, _("Successfully deleted %(count)d %(items)s.") % {
@ -63,7 +62,7 @@ def delete_selected(modeladmin, request, queryset):
context = dict( context = dict(
modeladmin.admin_site.each_context(request), modeladmin.admin_site.each_context(request),
title=title, title=title,
objects_name=objects_name, objects_name=str(objects_name),
deletable_objects=[deletable_objects], deletable_objects=[deletable_objects],
model_count=dict(model_count).items(), model_count=dict(model_count).items(),
queryset=queryset, queryset=queryset,

View File

@ -14,7 +14,6 @@ from django.contrib.admin.utils import (
from django.core.exceptions import ImproperlyConfigured, ValidationError from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import force_text
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -107,7 +106,7 @@ class SimpleListFilter(ListFilter):
} }
for lookup, title in self.lookup_choices: for lookup, title in self.lookup_choices:
yield { yield {
'selected': self.value() == force_text(lookup), 'selected': self.value() == str(lookup),
'query_string': changelist.get_query_string({self.parameter_name: lookup}, []), 'query_string': changelist.get_query_string({self.parameter_name: lookup}, []),
'display': title, 'display': title,
} }
@ -204,7 +203,7 @@ class RelatedFieldListFilter(FieldListFilter):
} }
for pk_val, val in self.lookup_choices: for pk_val, val in self.lookup_choices:
yield { yield {
'selected': self.lookup_val == force_text(pk_val), 'selected': self.lookup_val == str(pk_val),
'query_string': changelist.get_query_string({ 'query_string': changelist.get_query_string({
self.lookup_kwarg: pk_val, self.lookup_kwarg: pk_val,
}, [self.lookup_kwarg_isnull]), }, [self.lookup_kwarg_isnull]),
@ -290,7 +289,7 @@ class ChoicesFieldListFilter(FieldListFilter):
none_title = title none_title = title
continue continue
yield { yield {
'selected': force_text(lookup) == self.lookup_val, 'selected': str(lookup) == self.lookup_val,
'query_string': changelist.get_query_string( 'query_string': changelist.get_query_string(
{self.lookup_kwarg: lookup}, [self.lookup_kwarg_isnull] {self.lookup_kwarg: lookup}, [self.lookup_kwarg_isnull]
), ),
@ -415,7 +414,7 @@ class AllValuesFieldListFilter(FieldListFilter):
if val is None: if val is None:
include_none = True include_none = True
continue continue
val = force_text(val) val = str(val)
yield { yield {
'selected': self.lookup_val == val, 'selected': self.lookup_val == val,
'query_string': changelist.get_query_string({ 'query_string': changelist.get_query_string({

View File

@ -6,7 +6,6 @@ from django.contrib.contenttypes.models import ContentType
from django.db import models from django.db import models
from django.urls import NoReverseMatch, reverse from django.urls import NoReverseMatch, reverse
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import force_text
from django.utils.text import get_text_list from django.utils.text import get_text_list
from django.utils.translation import gettext, gettext_lazy as _ from django.utils.translation import gettext, gettext_lazy as _
@ -24,7 +23,7 @@ class LogEntryManager(models.Manager):
return self.model.objects.create( return self.model.objects.create(
user_id=user_id, user_id=user_id,
content_type_id=content_type_id, content_type_id=content_type_id,
object_id=force_text(object_id), object_id=str(object_id),
object_repr=object_repr[:200], object_repr=object_repr[:200],
action_flag=action_flag, action_flag=action_flag,
change_message=change_message, change_message=change_message,
@ -64,7 +63,7 @@ class LogEntry(models.Model):
ordering = ('-action_time',) ordering = ('-action_time',)
def __repr__(self): def __repr__(self):
return force_text(self.action_time) return str(self.action_time)
def __str__(self): def __str__(self):
if self.is_addition(): if self.is_addition():

View File

@ -38,7 +38,6 @@ from django.http.response import HttpResponseBase
from django.template.response import SimpleTemplateResponse, TemplateResponse from django.template.response import SimpleTemplateResponse, TemplateResponse
from django.urls import reverse from django.urls import reverse
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.utils.encoding import force_text
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.http import urlencode from django.utils.http import urlencode
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -722,7 +721,7 @@ class ModelAdmin(BaseModelAdmin):
user_id=request.user.pk, user_id=request.user.pk,
content_type_id=get_content_type_for_model(object).pk, content_type_id=get_content_type_for_model(object).pk,
object_id=object.pk, object_id=object.pk,
object_repr=force_text(object), object_repr=str(object),
action_flag=ADDITION, action_flag=ADDITION,
change_message=message, change_message=message,
) )
@ -738,7 +737,7 @@ class ModelAdmin(BaseModelAdmin):
user_id=request.user.pk, user_id=request.user.pk,
content_type_id=get_content_type_for_model(object).pk, content_type_id=get_content_type_for_model(object).pk,
object_id=object.pk, object_id=object.pk,
object_repr=force_text(object), object_repr=str(object),
action_flag=CHANGE, action_flag=CHANGE,
change_message=message, change_message=message,
) )
@ -763,7 +762,7 @@ class ModelAdmin(BaseModelAdmin):
""" """
A list_display column containing a checkbox widget. A list_display column containing a checkbox widget.
""" """
return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, force_text(obj.pk)) return helpers.checkbox.render(helpers.ACTION_CHECKBOX_NAME, str(obj.pk))
action_checkbox.short_description = mark_safe('<input type="checkbox" id="action-toggle" />') action_checkbox.short_description = mark_safe('<input type="checkbox" id="action-toggle" />')
def get_actions(self, request): def get_actions(self, request):
@ -1056,7 +1055,7 @@ class ModelAdmin(BaseModelAdmin):
if self.has_change_permission(request, obj): if self.has_change_permission(request, obj):
obj_repr = format_html('<a href="{}">{}</a>', urlquote(obj_url), obj) obj_repr = format_html('<a href="{}">{}</a>', urlquote(obj_url), obj)
else: else:
obj_repr = force_text(obj) obj_repr = str(obj)
msg_dict = { msg_dict = {
'name': opts.verbose_name, 'name': opts.verbose_name,
'obj': obj_repr, 'obj': obj_repr,
@ -1652,7 +1651,7 @@ class ModelAdmin(BaseModelAdmin):
context = dict( context = dict(
self.admin_site.each_context(request), self.admin_site.each_context(request),
module_name=force_text(opts.verbose_name_plural), module_name=str(opts.verbose_name_plural),
selection_note=_('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)}, selection_note=_('0 of %(cnt)s selected') % {'cnt': len(cl.result_list)},
selection_note_all=selection_note_all % {'total_count': cl.result_count}, selection_note_all=selection_note_all % {'total_count': cl.result_count},
title=cl.title, title=cl.title,
@ -1710,7 +1709,7 @@ class ModelAdmin(BaseModelAdmin):
if request.POST and not protected: # The user has confirmed the deletion. if request.POST and not protected: # The user has confirmed the deletion.
if perms_needed: if perms_needed:
raise PermissionDenied raise PermissionDenied
obj_display = force_text(obj) obj_display = str(obj)
attr = str(to_field) if to_field else opts.pk.attname attr = str(to_field) if to_field else opts.pk.attname
obj_id = obj.serializable_value(attr) obj_id = obj.serializable_value(attr)
self.log_deletion(request, obj, obj_display) self.log_deletion(request, obj, obj_display)
@ -1718,7 +1717,7 @@ class ModelAdmin(BaseModelAdmin):
return self.response_delete(request, obj_display, obj_id) return self.response_delete(request, obj_display, obj_id)
object_name = force_text(opts.verbose_name) object_name = str(opts.verbose_name)
if perms_needed or protected: if perms_needed or protected:
title = _("Cannot delete %(name)s") % {"name": object_name} title = _("Cannot delete %(name)s") % {"name": object_name}
@ -1769,7 +1768,7 @@ class ModelAdmin(BaseModelAdmin):
self.admin_site.each_context(request), self.admin_site.each_context(request),
title=_('Change history: %s') % obj, title=_('Change history: %s') % obj,
action_list=action_list, action_list=action_list,
module_name=capfirst(force_text(opts.verbose_name_plural)), module_name=str(capfirst(opts.verbose_name_plural)),
object=obj, object=obj,
opts=opts, opts=opts,
preserved_filters=self.get_preserved_filters(request), preserved_filters=self.get_preserved_filters(request),

View File

@ -14,7 +14,6 @@ from django.template.loader import get_template
from django.templatetags.static import static from django.templatetags.static import static
from django.urls import NoReverseMatch from django.urls import NoReverseMatch
from django.utils import formats from django.utils import formats
from django.utils.encoding import force_text
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.text import capfirst from django.utils.text import capfirst
@ -233,7 +232,7 @@ def items_for_result(cl, result, form):
result_repr = display_for_field(value, f, empty_value_display) result_repr = display_for_field(value, f, empty_value_display)
if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)): if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)):
row_classes.append('nowrap') row_classes.append('nowrap')
if force_text(result_repr) == '': if str(result_repr) == '':
result_repr = mark_safe('&nbsp;') result_repr = mark_safe('&nbsp;')
row_class = mark_safe(' class="%s"' % ' '.join(row_classes)) row_class = mark_safe(' class="%s"' % ' '.join(row_classes))
# If list_display_links not defined, add the link tag to the first field # If list_display_links not defined, add the link tag to the first field
@ -277,7 +276,7 @@ def items_for_result(cl, result, form):
field_name == cl.model._meta.pk.name and field_name == cl.model._meta.pk.name and
form[cl.model._meta.pk.name].is_hidden)): form[cl.model._meta.pk.name].is_hidden)):
bf = form[field_name] bf = form[field_name]
result_repr = mark_safe(force_text(bf.errors) + force_text(bf)) result_repr = mark_safe(str(bf.errors) + str(bf))
yield format_html('<td{}>{}</td>', row_class, result_repr) yield format_html('<td{}>{}</td>', row_class, result_repr)
if form and not form[cl.model._meta.pk.name].is_hidden: if form and not form[cl.model._meta.pk.name].is_hidden:
yield format_html('<td>{}</td>', form[cl.model._meta.pk.name]) yield format_html('<td>{}</td>', form[cl.model._meta.pk.name])

View File

@ -11,7 +11,6 @@ from django.db.models.sql.constants import QUERY_TERMS
from django.forms.utils import pretty_name from django.forms.utils import pretty_name
from django.urls import NoReverseMatch, reverse from django.urls import NoReverseMatch, reverse
from django.utils import formats, timezone from django.utils import formats, timezone
from django.utils.encoding import force_text
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.text import capfirst from django.utils.text import capfirst
from django.utils.translation import ngettext, override as translation_override from django.utils.translation import ngettext, override as translation_override
@ -338,7 +337,7 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
label = field.related_model._meta.verbose_name label = field.related_model._meta.verbose_name
except FieldDoesNotExist: except FieldDoesNotExist:
if name == "__str__": if name == "__str__":
label = force_text(model._meta.verbose_name) label = str(model._meta.verbose_name)
attr = str attr = str
else: else:
if callable(name): if callable(name):
@ -427,9 +426,9 @@ def display_for_value(value, empty_value_display, boolean=False):
elif isinstance(value, (int, decimal.Decimal, float)): elif isinstance(value, (int, decimal.Decimal, float)):
return formats.number_format(value) return formats.number_format(value)
elif isinstance(value, (list, tuple)): elif isinstance(value, (list, tuple)):
return ', '.join(force_text(v) for v in value) return ', '.join(str(v) for v in value)
else: else:
return force_text(value) return str(value)
class NotRelationField(Exception): class NotRelationField(Exception):
@ -512,23 +511,23 @@ def construct_change_message(form, formsets, add):
for added_object in formset.new_objects: for added_object in formset.new_objects:
change_message.append({ change_message.append({
'added': { 'added': {
'name': force_text(added_object._meta.verbose_name), 'name': str(added_object._meta.verbose_name),
'object': force_text(added_object), 'object': str(added_object),
} }
}) })
for changed_object, changed_fields in formset.changed_objects: for changed_object, changed_fields in formset.changed_objects:
change_message.append({ change_message.append({
'changed': { 'changed': {
'name': force_text(changed_object._meta.verbose_name), 'name': str(changed_object._meta.verbose_name),
'object': force_text(changed_object), 'object': str(changed_object),
'fields': changed_fields, 'fields': changed_fields,
} }
}) })
for deleted_object in formset.deleted_objects: for deleted_object in formset.deleted_objects:
change_message.append({ change_message.append({
'deleted': { 'deleted': {
'name': force_text(deleted_object._meta.verbose_name), 'name': str(deleted_object._meta.verbose_name),
'object': force_text(deleted_object), 'object': str(deleted_object),
} }
}) })
return change_message return change_message

View File

@ -7,7 +7,6 @@ from django import forms
from django.db.models.deletion import CASCADE from django.db.models.deletion import CASCADE
from django.urls import reverse from django.urls import reverse
from django.urls.exceptions import NoReverseMatch from django.urls.exceptions import NoReverseMatch
from django.utils.encoding import force_text
from django.utils.html import smart_urlquote from django.utils.html import smart_urlquote
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.text import Truncator from django.utils.text import Truncator
@ -215,7 +214,7 @@ class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
return value.split(',') return value.split(',')
def format_value(self, value): def format_value(self, value):
return ','.join(force_text(v) for v in value) if value else '' return ','.join(str(v) for v in value) if value else ''
class RelatedFieldWidgetWrapper(forms.Widget): class RelatedFieldWidgetWrapper(forms.Widget):

View File

@ -2,7 +2,6 @@ from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.views import redirect_to_login from django.contrib.auth.views import redirect_to_login
from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.utils.encoding import force_text
class AccessMixin: class AccessMixin:
@ -25,7 +24,7 @@ class AccessMixin:
'{0} is missing the login_url attribute. Define {0}.login_url, settings.LOGIN_URL, or override ' '{0} is missing the login_url attribute. Define {0}.login_url, settings.LOGIN_URL, or override '
'{0}.get_login_url().'.format(self.__class__.__name__) '{0}.get_login_url().'.format(self.__class__.__name__)
) )
return force_text(login_url) return str(login_url)
def get_permission_denied_message(self): def get_permission_denied_message(self):
""" """

View File

@ -8,7 +8,6 @@ from django.conf import settings
from django.core.exceptions import ( from django.core.exceptions import (
FieldDoesNotExist, ImproperlyConfigured, ValidationError, FieldDoesNotExist, ImproperlyConfigured, ValidationError,
) )
from django.utils.encoding import force_text
from django.utils.functional import lazy from django.utils.functional import lazy
from django.utils.html import format_html from django.utils.html import format_html
from django.utils.module_loading import import_string from django.utils.module_loading import import_string
@ -145,7 +144,7 @@ class UserAttributeSimilarityValidator:
for value_part in value_parts: for value_part in value_parts:
if SequenceMatcher(a=password.lower(), b=value_part.lower()).quick_ratio() >= self.max_similarity: if SequenceMatcher(a=password.lower(), b=value_part.lower()).quick_ratio() >= self.max_similarity:
try: try:
verbose_name = force_text(user._meta.get_field(attribute_name).verbose_name) verbose_name = str(user._meta.get_field(attribute_name).verbose_name)
except FieldDoesNotExist: except FieldDoesNotExist:
verbose_name = attribute_name verbose_name = attribute_name
raise ValidationError( raise ValidationError(

View File

@ -11,7 +11,6 @@ from django.db.models.fields.related import (
lazy_related_operation, lazy_related_operation,
) )
from django.db.models.query_utils import PathInfo from django.db.models.query_utils import PathInfo
from django.utils.encoding import force_text
from django.utils.functional import cached_property from django.utils.functional import cached_property
@ -398,7 +397,7 @@ class GenericRelation(ForeignObject):
def value_to_string(self, obj): def value_to_string(self, obj):
qs = getattr(obj, self.name).all() qs = getattr(obj, self.name).all()
return force_text([instance._get_pk_val() for instance in qs]) return str([instance._get_pk_val() for instance in qs])
def contribute_to_class(self, cls, name, **kwargs): def contribute_to_class(self, cls, name, **kwargs):
kwargs['private_only'] = True kwargs['private_only'] = True

View File

@ -2,7 +2,6 @@ from collections import defaultdict
from django.apps import apps from django.apps import apps
from django.db import models from django.db import models
from django.utils.encoding import force_text
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@ -151,7 +150,7 @@ class ContentType(models.Model):
model = self.model_class() model = self.model_class()
if not model: if not model:
return self.model return self.model
return force_text(model._meta.verbose_name) return str(model._meta.verbose_name)
def model_class(self): def model_class(self):
"""Return the model class for this type of content.""" """Return the model class for this type of content."""

View File

@ -4,7 +4,6 @@ from django.contrib.postgres import forms, lookups
from django.contrib.postgres.fields.array import ArrayField from django.contrib.postgres.fields.array import ArrayField
from django.core import exceptions from django.core import exceptions
from django.db.models import Field, TextField, Transform from django.db.models import Field, TextField, Transform
from django.utils.encoding import force_text
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
__all__ = ['HStoreField'] __all__ = ['HStoreField']
@ -57,14 +56,14 @@ class HStoreField(Field):
if isinstance(value, dict): if isinstance(value, dict):
prep_value = {} prep_value = {}
for key, val in value.items(): for key, val in value.items():
key = force_text(key) key = str(key)
if val is not None: if val is not None:
val = force_text(val) val = str(val)
prep_value[key] = val prep_value[key] = val
value = prep_value value = prep_value
if isinstance(value, list): if isinstance(value, list):
value = [force_text(item) for item in value] value = [str(item) for item in value]
return value return value

View File

@ -1,5 +1,4 @@
from django.db.models import Lookup, Transform from django.db.models import Lookup, Transform
from django.utils.encoding import force_text
from .search import SearchVector, SearchVectorExact, SearchVectorField from .search import SearchVector, SearchVectorExact, SearchVectorField
@ -38,7 +37,7 @@ class HasKeys(PostgresSimpleLookup):
operator = '?&' operator = '?&'
def get_prep_lookup(self): def get_prep_lookup(self):
return [force_text(item) for item in self.rhs] return [str(item) for item in self.rhs]
class HasAnyKeys(HasKeys): class HasAnyKeys(HasKeys):

View File

@ -10,7 +10,7 @@ from django.utils import timezone
from django.utils.crypto import ( from django.utils.crypto import (
constant_time_compare, get_random_string, salted_hmac, constant_time_compare, get_random_string, salted_hmac,
) )
from django.utils.encoding import force_bytes, force_text from django.utils.encoding import force_bytes
from django.utils.module_loading import import_string from django.utils.module_loading import import_string
# session_key should not be case sensitive because some backends can store it # session_key should not be case sensitive because some backends can store it
@ -112,7 +112,7 @@ class SessionBase:
# these happen, just return an empty dictionary (an empty session). # these happen, just return an empty dictionary (an empty session).
if isinstance(e, SuspiciousOperation): if isinstance(e, SuspiciousOperation):
logger = logging.getLogger('django.security.%s' % e.__class__.__name__) logger = logging.getLogger('django.security.%s' % e.__class__.__name__)
logger.warning(force_text(e)) logger.warning(str(e))
return {} return {}
def update(self, dict_): def update(self, dict_):

View File

@ -9,7 +9,6 @@ from django.contrib.sessions.backends.db import SessionStore as DBStore
from django.core.cache import caches from django.core.cache import caches
from django.core.exceptions import SuspiciousOperation from django.core.exceptions import SuspiciousOperation
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import force_text
KEY_PREFIX = "django.contrib.sessions.cached_db" KEY_PREFIX = "django.contrib.sessions.cached_db"
@ -49,7 +48,7 @@ class SessionStore(DBStore):
except (self.model.DoesNotExist, SuspiciousOperation) as e: except (self.model.DoesNotExist, SuspiciousOperation) as e:
if isinstance(e, SuspiciousOperation): if isinstance(e, SuspiciousOperation):
logger = logging.getLogger('django.security.%s' % e.__class__.__name__) logger = logging.getLogger('django.security.%s' % e.__class__.__name__)
logger.warning(force_text(e)) logger.warning(str(e))
self._session_key = None self._session_key = None
data = {} data = {}
return data return data

View File

@ -6,7 +6,6 @@ from django.contrib.sessions.backends.base import (
from django.core.exceptions import SuspiciousOperation from django.core.exceptions import SuspiciousOperation
from django.db import DatabaseError, IntegrityError, router, transaction from django.db import DatabaseError, IntegrityError, router, transaction
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import force_text
from django.utils.functional import cached_property from django.utils.functional import cached_property
@ -38,7 +37,7 @@ class SessionStore(SessionBase):
except (self.model.DoesNotExist, SuspiciousOperation) as e: except (self.model.DoesNotExist, SuspiciousOperation) as e:
if isinstance(e, SuspiciousOperation): if isinstance(e, SuspiciousOperation):
logger = logging.getLogger('django.security.%s' % e.__class__.__name__) logger = logging.getLogger('django.security.%s' % e.__class__.__name__)
logger.warning(force_text(e)) logger.warning(str(e))
self._session_key = None self._session_key = None
return {} return {}

View File

@ -11,7 +11,6 @@ from django.contrib.sessions.backends.base import (
from django.contrib.sessions.exceptions import InvalidSessionKey from django.contrib.sessions.exceptions import InvalidSessionKey
from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import force_text
class SessionStore(SessionBase): class SessionStore(SessionBase):
@ -92,7 +91,7 @@ class SessionStore(SessionBase):
except (EOFError, SuspiciousOperation) as e: except (EOFError, SuspiciousOperation) as e:
if isinstance(e, SuspiciousOperation): if isinstance(e, SuspiciousOperation):
logger = logging.getLogger('django.security.%s' % e.__class__.__name__) logger = logging.getLogger('django.security.%s' % e.__class__.__name__)
logger.warning(force_text(e)) logger.warning(str(e))
self.create() self.create()
# Remove expired sessions. # Remove expired sessions.

View File

@ -6,7 +6,7 @@ from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
from django.http import Http404, HttpResponse from django.http import Http404, HttpResponse
from django.template import TemplateDoesNotExist, loader from django.template import TemplateDoesNotExist, loader
from django.utils import feedgenerator from django.utils import feedgenerator
from django.utils.encoding import force_text, iri_to_uri from django.utils.encoding import iri_to_uri
from django.utils.html import escape from django.utils.html import escape
from django.utils.http import http_date from django.utils.http import http_date
from django.utils.timezone import get_default_timezone, is_naive, make_aware from django.utils.timezone import get_default_timezone, is_naive, make_aware
@ -48,10 +48,10 @@ class Feed:
def item_title(self, item): def item_title(self, item):
# Titles should be double escaped by default (see #6533) # Titles should be double escaped by default (see #6533)
return escape(force_text(item)) return escape(str(item))
def item_description(self, item): def item_description(self, item):
return force_text(item) return str(item)
def item_link(self, item): def item_link(self, item):
try: try:
@ -66,9 +66,9 @@ class Feed:
enc_url = self._get_dynamic_attr('item_enclosure_url', item) enc_url = self._get_dynamic_attr('item_enclosure_url', item)
if enc_url: if enc_url:
enc = feedgenerator.Enclosure( enc = feedgenerator.Enclosure(
url=force_text(enc_url), url=str(enc_url),
length=force_text(self._get_dynamic_attr('item_enclosure_length', item)), length=str(self._get_dynamic_attr('item_enclosure_length', item)),
mime_type=force_text(self._get_dynamic_attr('item_enclosure_mime_type', item)), mime_type=str(self._get_dynamic_attr('item_enclosure_mime_type', item)),
) )
return [enc] return [enc]
return [] return []

View File

@ -1,5 +1,3 @@
from django.utils.encoding import force_text
# Levels # Levels
DEBUG = 10 DEBUG = 10
INFO = 20 INFO = 20
@ -35,7 +33,7 @@ class CheckMessage:
# method doesn't return "applabel.modellabel" and cannot be changed. # method doesn't return "applabel.modellabel" and cannot be changed.
obj = self.obj._meta.label obj = self.obj._meta.label
else: else:
obj = force_text(self.obj) obj = str(self.obj)
id = "(%s) " % self.id if self.id else "" id = "(%s) " % self.id if self.id else ""
hint = "\n\tHINT: %s" % self.hint if self.hint else '' hint = "\n\tHINT: %s" % self.hint if self.hint else ''
return "%s: %s%s%s" % (obj, id, self.msg, hint) return "%s: %s%s%s" % (obj, id, self.msg, hint)

View File

@ -1,7 +1,6 @@
""" """
Global Django exception and warning classes. Global Django exception and warning classes.
""" """
from django.utils.encoding import force_text
class FieldDoesNotExist(Exception): class FieldDoesNotExist(Exception):
@ -174,7 +173,7 @@ class ValidationError(Exception):
message = error.message message = error.message
if error.params: if error.params:
message %= error.params message %= error.params
yield force_text(message) yield str(message)
def __str__(self): def __str__(self):
if hasattr(self, 'error_dict'): if hasattr(self, 'error_dict'):

View File

@ -11,7 +11,6 @@ from django.core.exceptions import (
from django.http import Http404 from django.http import Http404
from django.http.multipartparser import MultiPartParserError from django.http.multipartparser import MultiPartParserError
from django.urls import get_resolver, get_urlconf from django.urls import get_resolver, get_urlconf
from django.utils.encoding import force_text
from django.views import debug from django.views import debug
logger = logging.getLogger('django.request') logger = logging.getLogger('django.request')
@ -71,7 +70,7 @@ def response_for_exception(request, exc):
# The security logger receives events for all SuspiciousOperations # The security logger receives events for all SuspiciousOperations
security_logger = logging.getLogger('django.security.%s' % exc.__class__.__name__) security_logger = logging.getLogger('django.security.%s' % exc.__class__.__name__)
security_logger.error( security_logger.error(
force_text(exc), str(exc),
extra={'status_code': 400, 'request': request}, extra={'status_code': 400, 'request': request},
) )
if settings.DEBUG: if settings.DEBUG:

View File

@ -55,7 +55,7 @@ ADDRESS_HEADERS = {
def forbid_multi_line_headers(name, val, encoding): def forbid_multi_line_headers(name, val, encoding):
"""Forbid multi-line headers to prevent header injection.""" """Forbid multi-line headers to prevent header injection."""
encoding = encoding or settings.DEFAULT_CHARSET encoding = encoding or settings.DEFAULT_CHARSET
val = force_text(val) val = str(val) # val may be lazy
if '\n' in val or '\r' in val: if '\n' in val or '\r' in val:
raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name)) raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name))
try: try:
@ -100,7 +100,7 @@ def sanitize_address(addr, encoding):
Format a pair of (name, address) or an email address string. Format a pair of (name, address) or an email address string.
""" """
if not isinstance(addr, tuple): if not isinstance(addr, tuple):
addr = parseaddr(force_text(addr)) addr = parseaddr(addr)
nm, addr = addr nm, addr = addr
localpart, domain = None, None localpart, domain = None, None
nm = Header(nm, encoding).encode() nm = Header(nm, encoding).encode()
@ -258,11 +258,11 @@ class EmailMessage:
msg = self._create_message(msg) msg = self._create_message(msg)
msg['Subject'] = self.subject msg['Subject'] = self.subject
msg['From'] = self.extra_headers.get('From', self.from_email) msg['From'] = self.extra_headers.get('From', self.from_email)
msg['To'] = self.extra_headers.get('To', ', '.join(map(force_text, self.to))) msg['To'] = self.extra_headers.get('To', ', '.join(map(str, self.to)))
if self.cc: if self.cc:
msg['Cc'] = ', '.join(map(force_text, self.cc)) msg['Cc'] = ', '.join(map(str, self.cc))
if self.reply_to: if self.reply_to:
msg['Reply-To'] = self.extra_headers.get('Reply-To', ', '.join(map(force_text, self.reply_to))) msg['Reply-To'] = self.extra_headers.get('Reply-To', ', '.join(map(str, self.reply_to)))
# Email header names are case-insensitive (RFC 2045), so we have to # Email header names are case-insensitive (RFC 2045), so we have to
# accommodate that when doing comparisons. # accommodate that when doing comparisons.

View File

@ -11,7 +11,6 @@ from django.apps import apps
from django.conf import settings from django.conf import settings
from django.core.serializers import base from django.core.serializers import base
from django.db import DEFAULT_DB_ALIAS, models from django.db import DEFAULT_DB_ALIAS, models
from django.utils.encoding import force_text
from django.utils.xmlutils import ( from django.utils.xmlutils import (
SimplerXMLGenerator, UnserializableContentError, SimplerXMLGenerator, UnserializableContentError,
) )
@ -48,11 +47,11 @@ class Serializer(base.Serializer):
raise base.SerializationError("Non-model object (%s) encountered during serialization" % type(obj)) raise base.SerializationError("Non-model object (%s) encountered during serialization" % type(obj))
self.indent(1) self.indent(1)
attrs = OrderedDict([("model", force_text(obj._meta))]) attrs = OrderedDict([("model", str(obj._meta))])
if not self.use_natural_primary_keys or not hasattr(obj, 'natural_key'): if not self.use_natural_primary_keys or not hasattr(obj, 'natural_key'):
obj_pk = obj._get_pk_val() obj_pk = obj._get_pk_val()
if obj_pk is not None: if obj_pk is not None:
attrs['pk'] = force_text(obj_pk) attrs['pk'] = str(obj_pk)
self.xml.startElement("object", attrs) self.xml.startElement("object", attrs)
@ -101,10 +100,10 @@ class Serializer(base.Serializer):
# Iterable natural keys are rolled out as subelements # Iterable natural keys are rolled out as subelements
for key_value in related: for key_value in related:
self.xml.startElement("natural", {}) self.xml.startElement("natural", {})
self.xml.characters(force_text(key_value)) self.xml.characters(str(key_value))
self.xml.endElement("natural") self.xml.endElement("natural")
else: else:
self.xml.characters(force_text(related_att)) self.xml.characters(str(related_att))
else: else:
self.xml.addQuickElement("None") self.xml.addQuickElement("None")
self.xml.endElement("field") self.xml.endElement("field")
@ -125,13 +124,13 @@ class Serializer(base.Serializer):
self.xml.startElement("object", {}) self.xml.startElement("object", {})
for key_value in natural: for key_value in natural:
self.xml.startElement("natural", {}) self.xml.startElement("natural", {})
self.xml.characters(force_text(key_value)) self.xml.characters(str(key_value))
self.xml.endElement("natural") self.xml.endElement("natural")
self.xml.endElement("object") self.xml.endElement("object")
else: else:
def handle_m2m(value): def handle_m2m(value):
self.xml.addQuickElement("object", attrs={ self.xml.addQuickElement("object", attrs={
'pk': force_text(value._get_pk_val()) 'pk': str(value._get_pk_val())
}) })
for relobj in getattr(obj, field.name).iterator(): for relobj in getattr(obj, field.name).iterator():
handle_m2m(relobj) handle_m2m(relobj)
@ -144,7 +143,7 @@ class Serializer(base.Serializer):
self.xml.startElement("field", OrderedDict([ self.xml.startElement("field", OrderedDict([
("name", field.name), ("name", field.name),
("rel", field.remote_field.__class__.__name__), ("rel", field.remote_field.__class__.__name__),
("to", force_text(field.remote_field.model._meta)), ("to", str(field.remote_field.model._meta)),
])) ]))

View File

@ -5,7 +5,6 @@ from urllib.parse import urlsplit, urlunsplit
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.utils.deconstruct import deconstructible from django.utils.deconstruct import deconstructible
from django.utils.encoding import force_text
from django.utils.functional import SimpleLazyObject from django.utils.functional import SimpleLazyObject
from django.utils.ipv6 import is_valid_ipv6_address from django.utils.ipv6 import is_valid_ipv6_address
from django.utils.translation import gettext_lazy as _, ngettext_lazy from django.utils.translation import gettext_lazy as _, ngettext_lazy
@ -55,8 +54,7 @@ class RegexValidator:
Validate that the input contains a match for the regular expression Validate that the input contains a match for the regular expression
if inverse_match is False, otherwise raise ValidationError. if inverse_match is False, otherwise raise ValidationError.
""" """
if not (self.inverse_match is not bool(self.regex.search( if not (self.inverse_match is not bool(self.regex.search(str(value)))):
force_text(value)))):
raise ValidationError(self.message, code=self.code) raise ValidationError(self.message, code=self.code)
def __eq__(self, other): def __eq__(self, other):

View File

@ -410,7 +410,7 @@ class BaseDatabaseOperations:
def prep_for_like_query(self, x): def prep_for_like_query(self, x):
"""Prepare a value for use in a LIKE query.""" """Prepare a value for use in a LIKE query."""
return force_text(x).replace("\\", "\\\\").replace("%", r"\%").replace("_", r"\_") return str(x).replace("\\", "\\\\").replace("%", r"\%").replace("_", r"\_")
# Same as prep_for_like_query(), but called for "iexact" matches, which # Same as prep_for_like_query(), but called for "iexact" matches, which
# need not necessarily be implemented using "LIKE" in the backend. # need not necessarily be implemented using "LIKE" in the backend.

View File

@ -16,7 +16,6 @@ from django.utils import timezone
from django.utils.dateparse import ( from django.utils.dateparse import (
parse_date, parse_datetime, parse_duration, parse_time, parse_date, parse_datetime, parse_duration, parse_time,
) )
from django.utils.encoding import force_text
from .client import DatabaseClient # isort:skip from .client import DatabaseClient # isort:skip
from .creation import DatabaseCreation # isort:skip from .creation import DatabaseCreation # isort:skip
@ -456,7 +455,7 @@ def _sqlite_timestamp_diff(lhs, rhs):
def _sqlite_regexp(re_pattern, re_string): def _sqlite_regexp(re_pattern, re_string):
return bool(re.search(re_pattern, force_text(re_string))) if re_string is not None else False return bool(re.search(re_pattern, str(re_string))) if re_string is not None else False
def _sqlite_power(x, y): def _sqlite_power(x, y):

View File

@ -13,7 +13,6 @@ from django.db import models
from django.db.migrations.operations.base import Operation from django.db.migrations.operations.base import Operation
from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject from django.db.migrations.utils import COMPILED_REGEX_TYPE, RegexObject
from django.utils import datetime_safe from django.utils import datetime_safe
from django.utils.encoding import force_text
from django.utils.functional import LazyObject, Promise from django.utils.functional import LazyObject, Promise
from django.utils.timezone import utc from django.utils.timezone import utc
from django.utils.version import get_docs_version from django.utils.version import get_docs_version
@ -303,7 +302,7 @@ class UUIDSerializer(BaseSerializer):
def serializer_factory(value): def serializer_factory(value):
from django.db.migrations.writer import SettingsReference from django.db.migrations.writer import SettingsReference
if isinstance(value, Promise): if isinstance(value, Promise):
value = force_text(value) value = str(value)
elif isinstance(value, LazyObject): elif isinstance(value, LazyObject):
# The unwrapped value is returned as the first item of the arguments # The unwrapped value is returned as the first item of the arguments
# tuple. # tuple.

View File

@ -25,7 +25,7 @@ from django.utils.dateparse import (
parse_date, parse_datetime, parse_duration, parse_time, parse_date, parse_datetime, parse_duration, parse_time,
) )
from django.utils.duration import duration_string from django.utils.duration import duration_string
from django.utils.encoding import force_bytes, force_text, smart_text from django.utils.encoding import force_bytes, smart_text
from django.utils.functional import Promise, cached_property, curry from django.utils.functional import Promise, cached_property, curry
from django.utils.ipv6 import clean_ipv6_address from django.utils.ipv6 import clean_ipv6_address
from django.utils.itercompat import is_iterable from django.utils.itercompat import is_iterable
@ -805,7 +805,7 @@ class Field(RegisterLookupMixin):
Return a string value of this field from the passed obj. Return a string value of this field from the passed obj.
This is used by the serialization framework. This is used by the serialization framework.
""" """
return force_text(self.value_from_object(obj)) return str(self.value_from_object(obj))
def _get_flatchoices(self): def _get_flatchoices(self):
"""Flattened version of choices tuple.""" """Flattened version of choices tuple."""
@ -1058,7 +1058,7 @@ class CharField(Field):
def to_python(self, value): def to_python(self, value):
if isinstance(value, str) or value is None: if isinstance(value, str) or value is None:
return value return value
return force_text(value) return str(value)
def get_prep_value(self, value): def get_prep_value(self, value):
value = super().get_prep_value(value) value = super().get_prep_value(value)
@ -1920,7 +1920,7 @@ class GenericIPAddressField(Field):
if value is None: if value is None:
return None return None
if not isinstance(value, str): if not isinstance(value, str):
value = force_text(value) value = str(value)
value = value.strip() value = value.strip()
if ':' in value: if ':' in value:
return clean_ipv6_address(value, self.unpack_ipv4, self.error_messages['invalid']) return clean_ipv6_address(value, self.unpack_ipv4, self.error_messages['invalid'])
@ -2089,7 +2089,7 @@ class TextField(Field):
def to_python(self, value): def to_python(self, value):
if isinstance(value, str) or value is None: if isinstance(value, str) or value is None:
return value return value
return force_text(value) return str(value)
def get_prep_value(self, value): def get_prep_value(self, value):
value = super().get_prep_value(value) value = super().get_prep_value(value)

View File

@ -10,7 +10,6 @@ they're the closest concept currently available.
""" """
from django.core import exceptions from django.core import exceptions
from django.utils.encoding import force_text
from django.utils.functional import cached_property from django.utils.functional import cached_property
from . import BLANK_CHOICE_DASH from . import BLANK_CHOICE_DASH
@ -123,7 +122,7 @@ class ForeignObjectRel:
initially for utilization by RelatedFieldListFilter. initially for utilization by RelatedFieldListFilter.
""" """
return (blank_choice if include_blank else []) + [ return (blank_choice if include_blank else []) + [
(x._get_pk_val(), force_text(x)) for x in self.related_model._default_manager.all() (x._get_pk_val(), str(x)) for x in self.related_model._default_manager.all()
] ]
def is_hidden(self): def is_hidden(self):

View File

@ -14,7 +14,6 @@ from django.db.models.fields.proxy import OrderWrt
from django.db.models.query_utils import PathInfo from django.db.models.query_utils import PathInfo
from django.utils.datastructures import ImmutableList, OrderedSet from django.utils.datastructures import ImmutableList, OrderedSet
from django.utils.deprecation import RemovedInDjango21Warning from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.encoding import force_text
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.text import camel_case_to_spaces, format_lazy from django.utils.text import camel_case_to_spaces, format_lazy
from django.utils.translation import override from django.utils.translation import override
@ -317,7 +316,7 @@ class Options:
def verbose_name_raw(self): def verbose_name_raw(self):
"""Return the untranslated verbose name.""" """Return the untranslated verbose name."""
with override(None): with override(None):
return force_text(self.verbose_name) return str(self.verbose_name)
@property @property
def swapped(self): def swapped(self):

View File

@ -4,7 +4,6 @@ import warnings
from django.forms.utils import flatatt, pretty_name from django.forms.utils import flatatt, pretty_name
from django.forms.widgets import Textarea, TextInput from django.forms.widgets import Textarea, TextInput
from django.utils.deprecation import RemovedInDjango21Warning from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.encoding import force_text
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.html import conditional_escape, format_html, html_safe from django.utils.html import conditional_escape, format_html, html_safe
from django.utils.inspect import func_supports_parameter from django.utils.inspect import func_supports_parameter
@ -213,9 +212,9 @@ class BoundField:
Calculate and return the ID attribute for this BoundField, if the Calculate and return the ID attribute for this BoundField, if the
associated Form has specified auto_id. Return an empty string otherwise. associated Form has specified auto_id. Return an empty string otherwise.
""" """
auto_id = self.form.auto_id auto_id = self.form.auto_id # Boolean or string
if auto_id and '%s' in force_text(auto_id): if auto_id and '%s' in str(auto_id):
return force_text(auto_id) % self.html_name return auto_id % self.html_name
elif auto_id: elif auto_id:
return self.html_name return self.html_name
return '' return ''

View File

@ -28,7 +28,6 @@ from django.forms.widgets import (
from django.utils import formats from django.utils import formats
from django.utils.dateparse import parse_duration from django.utils.dateparse import parse_duration
from django.utils.duration import duration_string from django.utils.duration import duration_string
from django.utils.encoding import force_text
from django.utils.ipv6 import clean_ipv6_address from django.utils.ipv6 import clean_ipv6_address
from django.utils.translation import gettext_lazy as _, ngettext_lazy from django.utils.translation import gettext_lazy as _, ngettext_lazy
@ -221,7 +220,7 @@ class CharField(Field):
"""Return a string.""" """Return a string."""
if value in self.empty_values: if value in self.empty_values:
return self.empty_value return self.empty_value
value = force_text(value) value = str(value)
if self.strip: if self.strip:
value = value.strip() value = value.strip()
return value return value
@ -268,7 +267,7 @@ class IntegerField(Field):
value = formats.sanitize_separators(value) value = formats.sanitize_separators(value)
# Strip trailing decimal and zeros. # Strip trailing decimal and zeros.
try: try:
value = int(self.re_decimal.sub('', force_text(value))) value = int(self.re_decimal.sub('', str(value)))
except (ValueError, TypeError): except (ValueError, TypeError):
raise ValidationError(self.error_messages['invalid'], code='invalid') raise ValidationError(self.error_messages['invalid'], code='invalid')
return value return value
@ -341,7 +340,7 @@ class DecimalField(IntegerField):
return None return None
if self.localize: if self.localize:
value = formats.sanitize_separators(value) value = formats.sanitize_separators(value)
value = force_text(value).strip() value = str(value).strip()
try: try:
value = Decimal(value) value = Decimal(value)
except DecimalException: except DecimalException:
@ -484,7 +483,7 @@ class DurationField(Field):
return None return None
if isinstance(value, datetime.timedelta): if isinstance(value, datetime.timedelta):
return value return value
value = parse_duration(force_text(value)) value = parse_duration(str(value))
if value is None: if value is None:
raise ValidationError(self.error_messages['invalid'], code='invalid') raise ValidationError(self.error_messages['invalid'], code='invalid')
return value return value
@ -784,7 +783,7 @@ class ChoiceField(Field):
"""Return a string.""" """Return a string."""
if value in self.empty_values: if value in self.empty_values:
return '' return ''
return force_text(value) return str(value)
def validate(self, value): def validate(self, value):
"""Validate that the input is in self.choices.""" """Validate that the input is in self.choices."""
@ -798,15 +797,15 @@ class ChoiceField(Field):
def valid_value(self, value): def valid_value(self, value):
"""Check to see if the provided value is a valid choice.""" """Check to see if the provided value is a valid choice."""
text_value = force_text(value) text_value = str(value)
for k, v in self.choices: for k, v in self.choices:
if isinstance(v, (list, tuple)): if isinstance(v, (list, tuple)):
# This is an optgroup, so look inside the group for options # This is an optgroup, so look inside the group for options
for k2, v2 in v: for k2, v2 in v:
if value == k2 or text_value == force_text(k2): if value == k2 or text_value == str(k2):
return True return True
else: else:
if value == k or text_value == force_text(k): if value == k or text_value == str(k):
return True return True
return False return False
@ -851,7 +850,7 @@ class MultipleChoiceField(ChoiceField):
return [] return []
elif not isinstance(value, (list, tuple)): elif not isinstance(value, (list, tuple)):
raise ValidationError(self.error_messages['invalid_list'], code='invalid_list') raise ValidationError(self.error_messages['invalid_list'], code='invalid_list')
return [force_text(val) for val in value] return [str(val) for val in value]
def validate(self, value): def validate(self, value):
"""Validate that the input is a list or tuple.""" """Validate that the input is a list or tuple."""
@ -873,8 +872,8 @@ class MultipleChoiceField(ChoiceField):
data = [] data = []
if len(initial) != len(data): if len(initial) != len(data):
return True return True
initial_set = set(force_text(value) for value in initial) initial_set = set(str(value) for value in initial)
data_set = set(force_text(value) for value in data) data_set = set(str(value) for value in data)
return data_set != initial_set return data_set != initial_set

View File

@ -12,7 +12,6 @@ from django.forms.fields import Field, FileField
# pretty_name is imported for backwards compatibility in Django 1.9 # pretty_name is imported for backwards compatibility in Django 1.9
from django.forms.utils import ErrorDict, ErrorList, pretty_name # NOQA from django.forms.utils import ErrorDict, ErrorList, pretty_name # NOQA
from django.forms.widgets import Media, MediaDefiningClass from django.forms.widgets import Media, MediaDefiningClass
from django.utils.encoding import force_text
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.html import conditional_escape, html_safe from django.utils.html import conditional_escape, html_safe
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -205,7 +204,7 @@ class BaseForm:
if bf.is_hidden: if bf.is_hidden:
if bf_errors: if bf_errors:
top_errors.extend( top_errors.extend(
[_('(Hidden field %(name)s) %(error)s') % {'name': name, 'error': force_text(e)} [_('(Hidden field %(name)s) %(error)s') % {'name': name, 'error': str(e)}
for e in bf_errors]) for e in bf_errors])
hidden_fields.append(str(bf)) hidden_fields.append(str(bf))
else: else:
@ -216,10 +215,10 @@ class BaseForm:
html_class_attr = ' class="%s"' % css_classes html_class_attr = ' class="%s"' % css_classes
if errors_on_separate_row and bf_errors: if errors_on_separate_row and bf_errors:
output.append(error_row % force_text(bf_errors)) output.append(error_row % str(bf_errors))
if bf.label: if bf.label:
label = conditional_escape(force_text(bf.label)) label = conditional_escape(bf.label)
label = bf.label_tag(label) or '' label = bf.label_tag(label) or ''
else: else:
label = '' label = ''

View File

@ -16,7 +16,6 @@ from django.forms.utils import ErrorList
from django.forms.widgets import ( from django.forms.widgets import (
HiddenInput, MultipleHiddenInput, SelectMultiple, HiddenInput, MultipleHiddenInput, SelectMultiple,
) )
from django.utils.encoding import force_text
from django.utils.text import capfirst, get_text_list from django.utils.text import capfirst, get_text_list
from django.utils.translation import gettext, gettext_lazy as _ from django.utils.translation import gettext, gettext_lazy as _
@ -1085,7 +1084,7 @@ class InlineForeignKeyField(Field):
orig = getattr(self.parent_instance, self.to_field) orig = getattr(self.parent_instance, self.to_field)
else: else:
orig = self.parent_instance.pk orig = self.parent_instance.pk
if force_text(value) != force_text(orig): if str(value) != str(orig):
raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice') raise ValidationError(self.error_messages['invalid_choice'], code='invalid_choice')
return self.parent_instance return self.parent_instance
@ -1176,7 +1175,7 @@ class ModelChoiceField(ChoiceField):
presented by this object. Subclasses can override this method to presented by this object. Subclasses can override this method to
customize the display of the choices. customize the display of the choices.
""" """
return force_text(obj) return str(obj)
def _get_choices(self): def _get_choices(self):
# If self._choices is set, then somebody must have manually set # If self._choices is set, then somebody must have manually set
@ -1219,7 +1218,7 @@ class ModelChoiceField(ChoiceField):
def has_changed(self, initial, data): def has_changed(self, initial, data):
initial_value = initial if initial is not None else '' initial_value = initial if initial is not None else ''
data_value = data if data is not None else '' data_value = data if data is not None else ''
return force_text(self.prepare_value(initial_value)) != force_text(data_value) return str(self.prepare_value(initial_value)) != str(data_value)
class ModelMultipleChoiceField(ModelChoiceField): class ModelMultipleChoiceField(ModelChoiceField):
@ -1286,9 +1285,9 @@ class ModelMultipleChoiceField(ModelChoiceField):
params={'pk': pk}, params={'pk': pk},
) )
qs = self.queryset.filter(**{'%s__in' % key: value}) qs = self.queryset.filter(**{'%s__in' % key: value})
pks = set(force_text(getattr(o, key)) for o in qs) pks = set(str(getattr(o, key)) for o in qs)
for val in value: for val in value:
if force_text(val) not in pks: if str(val) not in pks:
raise ValidationError( raise ValidationError(
self.error_messages['invalid_choice'], self.error_messages['invalid_choice'],
code='invalid_choice', code='invalid_choice',
@ -1310,8 +1309,8 @@ class ModelMultipleChoiceField(ModelChoiceField):
data = [] data = []
if len(initial) != len(data): if len(initial) != len(data):
return True return True
initial_set = set(force_text(value) for value in self.prepare_value(initial)) initial_set = set(str(value) for value in self.prepare_value(initial))
data_set = set(force_text(value) for value in data) data_set = set(str(value) for value in data)
return data_set != initial_set return data_set != initial_set

View File

@ -12,7 +12,6 @@ from django.forms.utils import to_current_timezone
from django.templatetags.static import static from django.templatetags.static import static
from django.utils import datetime_safe, formats from django.utils import datetime_safe, formats
from django.utils.dates import MONTHS from django.utils.dates import MONTHS
from django.utils.encoding import force_text
from django.utils.formats import get_format from django.utils.formats import get_format
from django.utils.html import format_html, html_safe from django.utils.html import format_html, html_safe
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
@ -184,7 +183,7 @@ class Widget(metaclass=MediaDefiningClass):
return None return None
if self.is_localized: if self.is_localized:
return formats.localize_input(value) return formats.localize_input(value)
return force_text(value) return str(value)
def get_context(self, name, value, attrs): def get_context(self, name, value, attrs):
context = {} context = {}
@ -483,7 +482,7 @@ class CheckboxInput(Input):
"""Only return the 'value' attribute if value isn't empty.""" """Only return the 'value' attribute if value isn't empty."""
if value is True or value is False or value is None or value == '': if value is True or value is False or value is None or value == '':
return return
return force_text(value) return str(value)
def get_context(self, name, value, attrs): def get_context(self, name, value, attrs):
if self.check_test(value): if self.check_test(value):
@ -570,7 +569,7 @@ class ChoiceWidget(Widget):
for subvalue, sublabel in choices: for subvalue, sublabel in choices:
selected = ( selected = (
force_text(subvalue) in value and str(subvalue) in value and
(not has_selected or self.allow_multiple_selected) (not has_selected or self.allow_multiple_selected)
) )
if selected and not has_selected: if selected and not has_selected:

View File

@ -13,7 +13,7 @@ from django.core.exceptions import DisallowedRedirect
from django.core.serializers.json import DjangoJSONEncoder from django.core.serializers.json import DjangoJSONEncoder
from django.http.cookie import SimpleCookie from django.http.cookie import SimpleCookie
from django.utils import timezone from django.utils import timezone
from django.utils.encoding import force_bytes, force_text, iri_to_uri from django.utils.encoding import force_bytes, iri_to_uri
from django.utils.http import cookie_date from django.utils.http import cookie_date
_charset_from_content_type_re = re.compile(r';\s*charset=(?P<charset>[^\s;]+)', re.I) _charset_from_content_type_re = re.compile(r';\s*charset=(?P<charset>[^\s;]+)', re.I)
@ -405,7 +405,7 @@ class HttpResponseRedirectBase(HttpResponse):
def __init__(self, redirect_to, *args, **kwargs): def __init__(self, redirect_to, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self['Location'] = iri_to_uri(redirect_to) self['Location'] = iri_to_uri(redirect_to)
parsed = urlparse(force_text(redirect_to)) parsed = urlparse(str(redirect_to))
if parsed.scheme and parsed.scheme not in self.allowed_schemes: if parsed.scheme and parsed.scheme not in self.allowed_schemes:
raise DisallowedRedirect("Unsafe redirect to URL with protocol '%s'" % parsed.scheme) raise DisallowedRedirect("Unsafe redirect to URL with protocol '%s'" % parsed.scheme)

View File

@ -11,7 +11,6 @@ from django.http import (
from django.template import loader from django.template import loader
from django.urls import NoReverseMatch, reverse from django.urls import NoReverseMatch, reverse
from django.utils.deprecation import RemovedInDjango30Warning from django.utils.deprecation import RemovedInDjango30Warning
from django.utils.encoding import force_text
from django.utils.functional import Promise from django.utils.functional import Promise
@ -138,7 +137,7 @@ def resolve_url(to, *args, **kwargs):
if isinstance(to, Promise): if isinstance(to, Promise):
# Expand the lazy instance, as it can cause issues when it is passed # Expand the lazy instance, as it can cause issues when it is passed
# further to some Python functions like urlparse. # further to some Python functions like urlparse.
to = force_text(to) to = str(to)
if isinstance(to, str): if isinstance(to, str):
# Handle relative URLs # Handle relative URLs

View File

@ -16,7 +16,6 @@ from django.core.checks import Warning
from django.core.checks.urls import check_resolver from django.core.checks.urls import check_resolver
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.utils.datastructures import MultiValueDict from django.utils.datastructures import MultiValueDict
from django.utils.encoding import force_text
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.http import RFC3986_SUBDELIMS from django.utils.http import RFC3986_SUBDELIMS
from django.utils.regex_helper import normalize from django.utils.regex_helper import normalize
@ -92,7 +91,7 @@ class LocaleRegexDescriptor:
return instance.__dict__['regex'] return instance.__dict__['regex']
language_code = get_language() language_code = get_language()
if language_code not in instance._regex_dict: if language_code not in instance._regex_dict:
instance._regex_dict[language_code] = self._compile(force_text(instance._regex)) instance._regex_dict[language_code] = self._compile(str(instance._regex))
return instance._regex_dict[language_code] return instance._regex_dict[language_code]
def _compile(self, regex): def _compile(self, regex):
@ -347,7 +346,7 @@ class RegexURLResolver(LocaleRegexProvider):
return name in self._callback_strs return name in self._callback_strs
def resolve(self, path): def resolve(self, path):
path = force_text(path) # path may be a reverse_lazy object path = str(path) # path may be a reverse_lazy object
tried = [] tried = []
match = self.regex.search(path) match = self.regex.search(path)
if match: if match:
@ -422,8 +421,8 @@ class RegexURLResolver(LocaleRegexProvider):
def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs): def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs):
if args and kwargs: if args and kwargs:
raise ValueError("Don't mix *args and **kwargs in call to reverse()!") raise ValueError("Don't mix *args and **kwargs in call to reverse()!")
text_args = [force_text(v) for v in args] text_args = [str(v) for v in args]
text_kwargs = {k: force_text(v) for (k, v) in kwargs.items()} text_kwargs = {k: str(v) for (k, v) in kwargs.items()}
if not self._populated: if not self._populated:
self._populate() self._populate()

View File

@ -18,7 +18,6 @@ import time
from django.utils.dates import ( from django.utils.dates import (
MONTHS, MONTHS_3, MONTHS_ALT, MONTHS_AP, WEEKDAYS, WEEKDAYS_ABBR, MONTHS, MONTHS_3, MONTHS_ALT, MONTHS_AP, WEEKDAYS, WEEKDAYS_ABBR,
) )
from django.utils.encoding import force_text
from django.utils.timezone import get_default_timezone, is_aware, is_naive from django.utils.timezone import get_default_timezone, is_aware, is_naive
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
@ -29,14 +28,14 @@ re_escaped = re.compile(r'\\(.)')
class Formatter: class Formatter:
def format(self, formatstr): def format(self, formatstr):
pieces = [] pieces = []
for i, piece in enumerate(re_formatchars.split(force_text(formatstr))): for i, piece in enumerate(re_formatchars.split(str(formatstr))):
if i % 2: if i % 2:
if type(self.data) is datetime.date and hasattr(TimeFormat, piece): if type(self.data) is datetime.date and hasattr(TimeFormat, piece):
raise TypeError( raise TypeError(
"The format for date objects may not contain " "The format for date objects may not contain "
"time-related format specifiers (found '%s')." % piece "time-related format specifiers (found '%s')." % piece
) )
pieces.append(force_text(getattr(self, piece)())) pieces.append(str(getattr(self, piece)()))
elif piece: elif piece:
pieces.append(re_escaped.sub(r'\1', piece)) pieces.append(re_escaped.sub(r'\1', piece))
return ''.join(pieces) return ''.join(pieces)

View File

@ -43,7 +43,7 @@ def escape(text):
conditional_escape() instead. conditional_escape() instead.
""" """
return mark_safe( return mark_safe(
force_text(text).replace('&', '&amp;').replace('<', '&lt;') str(text).replace('&', '&amp;').replace('<', '&lt;')
.replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;') .replace('>', '&gt;').replace('"', '&quot;').replace("'", '&#39;')
) )
@ -70,7 +70,7 @@ _js_escapes.update((ord('%c' % z), '\\u%04X' % z) for z in range(32))
@keep_lazy(str, SafeText) @keep_lazy(str, SafeText)
def escapejs(value): def escapejs(value):
"""Hex encode characters for use in JavaScript strings.""" """Hex encode characters for use in JavaScript strings."""
return mark_safe(force_text(value).translate(_js_escapes)) return mark_safe(str(value).translate(_js_escapes))
def conditional_escape(text): def conditional_escape(text):
@ -121,8 +121,8 @@ def format_html_join(sep, format_string, args_generator):
@keep_lazy_text @keep_lazy_text
def linebreaks(value, autoescape=False): def linebreaks(value, autoescape=False):
"""Convert newlines into <p> and <br />s.""" """Convert newlines into <p> and <br />s."""
value = normalize_newlines(force_text(value)) value = normalize_newlines(value)
paras = re.split('\n{2,}', value) paras = re.split('\n{2,}', str(value))
if autoescape: if autoescape:
paras = ['<p>%s</p>' % escape(p).replace('\n', '<br />') for p in paras] paras = ['<p>%s</p>' % escape(p).replace('\n', '<br />') for p in paras]
else: else:

View File

@ -4,7 +4,6 @@ import unicodedata
from gzip import GzipFile from gzip import GzipFile
from io import BytesIO from io import BytesIO
from django.utils.encoding import force_text
from django.utils.functional import ( from django.utils.functional import (
SimpleLazyObject, keep_lazy, keep_lazy_text, lazy, SimpleLazyObject, keep_lazy, keep_lazy_text, lazy,
) )
@ -15,7 +14,7 @@ from django.utils.translation import gettext as _, gettext_lazy, pgettext
@keep_lazy_text @keep_lazy_text
def capfirst(x): def capfirst(x):
"""Capitalize the first letter of a string.""" """Capitalize the first letter of a string."""
return x and force_text(x)[0].upper() + force_text(x)[1:] return x and str(x)[0].upper() + str(x)[1:]
# Set up regular expressions # Set up regular expressions
@ -62,7 +61,7 @@ class Truncator(SimpleLazyObject):
An object used to truncate text, either by characters or words. An object used to truncate text, either by characters or words.
""" """
def __init__(self, text): def __init__(self, text):
super().__init__(lambda: force_text(text)) super().__init__(lambda: str(text))
def add_truncation_text(self, text, truncate=None): def add_truncation_text(self, text, truncate=None):
if truncate is None: if truncate is None:
@ -230,7 +229,7 @@ def get_valid_filename(s):
>>> get_valid_filename("john's portrait in 2004.jpg") >>> get_valid_filename("john's portrait in 2004.jpg")
'johns_portrait_in_2004.jpg' 'johns_portrait_in_2004.jpg'
""" """
s = force_text(s).strip().replace(' ', '_') s = str(s).strip().replace(' ', '_')
return re.sub(r'(?u)[^-\w.]', '', s) return re.sub(r'(?u)[^-\w.]', '', s)
@ -251,18 +250,17 @@ def get_text_list(list_, last_word=gettext_lazy('or')):
if len(list_) == 0: if len(list_) == 0:
return '' return ''
if len(list_) == 1: if len(list_) == 1:
return force_text(list_[0]) return str(list_[0])
return '%s %s %s' % ( return '%s %s %s' % (
# Translators: This string is used as a separator between list elements # Translators: This string is used as a separator between list elements
_(', ').join(force_text(i) for i in list_[:-1]), _(', ').join(str(i) for i in list_[:-1]), str(last_word), str(list_[-1])
force_text(last_word), force_text(list_[-1])) )
@keep_lazy_text @keep_lazy_text
def normalize_newlines(text): def normalize_newlines(text):
"""Normalize CRLF and CR newlines to just LF.""" """Normalize CRLF and CR newlines to just LF."""
text = force_text(text) return re_newlines.sub('\n', str(text))
return re_newlines.sub('\n', text)
@keep_lazy_text @keep_lazy_text
@ -349,8 +347,7 @@ def smart_split(text):
>>> list(smart_split(r'A "\"funky\" style" test.')) >>> list(smart_split(r'A "\"funky\" style" test.'))
['A', '"\\"funky\\" style"', 'test.'] ['A', '"\\"funky\\" style"', 'test.']
""" """
text = force_text(text) for bit in smart_split_re.finditer(str(text)):
for bit in smart_split_re.finditer(text):
yield bit.group(0) yield bit.group(0)
@ -378,7 +375,7 @@ _entity_re = re.compile(r"&(#?[xX]?(?:[0-9a-fA-F]+|\w{1,8}));")
@keep_lazy_text @keep_lazy_text
def unescape_entities(text): def unescape_entities(text):
return _entity_re.sub(_replace_entity, force_text(text)) return _entity_re.sub(_replace_entity, str(text))
@keep_lazy_text @keep_lazy_text
@ -409,7 +406,7 @@ def slugify(value, allow_unicode=False):
Remove characters that aren't alphanumerics, underscores, or hyphens. Remove characters that aren't alphanumerics, underscores, or hyphens.
Convert to lowercase. Also strip leading and trailing whitespace. Convert to lowercase. Also strip leading and trailing whitespace.
""" """
value = force_text(value) value = str(value)
if allow_unicode: if allow_unicode:
value = unicodedata.normalize('NFKC', value) value = unicodedata.normalize('NFKC', value)
else: else:

View File

@ -6,7 +6,6 @@ import warnings
from contextlib import ContextDecorator from contextlib import ContextDecorator
from django.utils.deprecation import RemovedInDjango21Warning from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.encoding import force_text
from django.utils.functional import lazy from django.utils.functional import lazy
__all__ = [ __all__ = [
@ -226,7 +225,7 @@ def _string_concat(*strings):
'django.utils.translate.string_concat() is deprecated in ' 'django.utils.translate.string_concat() is deprecated in '
'favor of django.utils.text.format_lazy().', 'favor of django.utils.text.format_lazy().',
RemovedInDjango21Warning, stacklevel=2) RemovedInDjango21Warning, stacklevel=2)
return ''.join(force_text(s) for s in strings) return ''.join(str(s) for s in strings)
string_concat = lazy(_string_concat, str) string_concat = lazy(_string_concat, str)

View File

@ -287,7 +287,7 @@ class ExceptionReporter:
user_str = None user_str = None
else: else:
try: try:
user_str = force_text(self.request.user) user_str = str(self.request.user)
except Exception: except Exception:
# request.user may raise OperationalError if the database is # request.user may raise OperationalError if the database is
# unavailable, for example. # unavailable, for example.
@ -318,7 +318,7 @@ class ExceptionReporter:
if self.exc_type: if self.exc_type:
c['exception_type'] = self.exc_type.__name__ c['exception_type'] = self.exc_type.__name__
if self.exc_value: if self.exc_value:
c['exception_value'] = force_text(self.exc_value, errors='replace') c['exception_value'] = str(self.exc_value)
if frames: if frames:
c['lastframe'] = frames[-1] c['lastframe'] = frames[-1]
return c return c

View File

@ -3,7 +3,6 @@ from django.http import (
HttpResponseServerError, HttpResponseServerError,
) )
from django.template import Context, Engine, TemplateDoesNotExist, loader from django.template import Context, Engine, TemplateDoesNotExist, loader
from django.utils.encoding import force_text
from django.views.decorators.csrf import requires_csrf_token from django.views.decorators.csrf import requires_csrf_token
ERROR_404_TEMPLATE_NAME = '404.html' ERROR_404_TEMPLATE_NAME = '404.html'
@ -117,5 +116,5 @@ def permission_denied(request, exception, template_name=ERROR_403_TEMPLATE_NAME)
raise raise
return HttpResponseForbidden('<h1>403 Forbidden</h1>', content_type='text/html') return HttpResponseForbidden('<h1>403 Forbidden</h1>', content_type='text/html')
return HttpResponseForbidden( return HttpResponseForbidden(
template.render(request=request, context={'exception': force_text(exception)}) template.render(request=request, context={'exception': str(exception)})
) )

View File

@ -1,7 +1,6 @@
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.forms import models as model_forms from django.forms import models as model_forms
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.utils.encoding import force_text
from django.views.generic.base import ContextMixin, TemplateResponseMixin, View from django.views.generic.base import ContextMixin, TemplateResponseMixin, View
from django.views.generic.detail import ( from django.views.generic.detail import (
BaseDetailView, SingleObjectMixin, SingleObjectTemplateResponseMixin, BaseDetailView, SingleObjectMixin, SingleObjectTemplateResponseMixin,
@ -49,13 +48,9 @@ class FormMixin(ContextMixin):
def get_success_url(self): def get_success_url(self):
"""Return the URL to redirect to after processing a valid form.""" """Return the URL to redirect to after processing a valid form."""
if self.success_url: if not self.success_url:
# Forcing possible reverse_lazy evaluation raise ImproperlyConfigured("No URL to redirect to. Provide a success_url.")
url = force_text(self.success_url) return str(self.success_url) # success_url may be lazy
else:
raise ImproperlyConfigured(
"No URL to redirect to. Provide a success_url.")
return url
def form_valid(self, form): def form_valid(self, form):
"""If the form is valid, redirect to the supplied URL.""" """If the form is valid, redirect to the supplied URL."""

View File

@ -706,10 +706,10 @@ smoothly:
2. Put a ``__str__()`` method on the class you're wrapping up as a field. There 2. Put a ``__str__()`` method on the class you're wrapping up as a field. There
are a lot of places where the default behavior of the field code is to call are a lot of places where the default behavior of the field code is to call
:func:`~django.utils.encoding.force_text` on the value. (In our ``str()`` on the value. (In our examples in this document, ``value`` would
examples in this document, ``value`` would be a ``Hand`` instance, not a be a ``Hand`` instance, not a ``HandField``). So if your ``__str__()``
``HandField``). So if your ``__str__()`` method automatically converts to method automatically converts to the string form of your Python object, you
the string form of your Python object, you can save yourself a lot of work. can save yourself a lot of work.
Writing a ``FileField`` subclass Writing a ``FileField`` subclass
================================ ================================

View File

@ -256,13 +256,12 @@ For example, if you have some custom type in an object to be serialized, you'll
have to write a custom :mod:`json` encoder for it. Something like this will have to write a custom :mod:`json` encoder for it. Something like this will
work:: work::
from django.utils.encoding import force_text
from django.core.serializers.json import DjangoJSONEncoder from django.core.serializers.json import DjangoJSONEncoder
class LazyEncoder(DjangoJSONEncoder): class LazyEncoder(DjangoJSONEncoder):
def default(self, obj): def default(self, obj):
if isinstance(obj, YourCustomType): if isinstance(obj, YourCustomType):
return force_text(obj) return str(obj)
return super().default(obj) return super().default(obj)
You can then pass ``cls=LazyEncoder`` to the ``serializers.serialize()`` You can then pass ``cls=LazyEncoder`` to the ``serializers.serialize()``