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

View File

@ -14,7 +14,6 @@ from django.contrib.admin.utils import (
from django.core.exceptions import ImproperlyConfigured, ValidationError
from django.db import models
from django.utils import timezone
from django.utils.encoding import force_text
from django.utils.translation import gettext_lazy as _
@ -107,7 +106,7 @@ class SimpleListFilter(ListFilter):
}
for lookup, title in self.lookup_choices:
yield {
'selected': self.value() == force_text(lookup),
'selected': self.value() == str(lookup),
'query_string': changelist.get_query_string({self.parameter_name: lookup}, []),
'display': title,
}
@ -204,7 +203,7 @@ class RelatedFieldListFilter(FieldListFilter):
}
for pk_val, val in self.lookup_choices:
yield {
'selected': self.lookup_val == force_text(pk_val),
'selected': self.lookup_val == str(pk_val),
'query_string': changelist.get_query_string({
self.lookup_kwarg: pk_val,
}, [self.lookup_kwarg_isnull]),
@ -290,7 +289,7 @@ class ChoicesFieldListFilter(FieldListFilter):
none_title = title
continue
yield {
'selected': force_text(lookup) == self.lookup_val,
'selected': str(lookup) == self.lookup_val,
'query_string': changelist.get_query_string(
{self.lookup_kwarg: lookup}, [self.lookup_kwarg_isnull]
),
@ -415,7 +414,7 @@ class AllValuesFieldListFilter(FieldListFilter):
if val is None:
include_none = True
continue
val = force_text(val)
val = str(val)
yield {
'selected': self.lookup_val == val,
'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.urls import NoReverseMatch, reverse
from django.utils import timezone
from django.utils.encoding import force_text
from django.utils.text import get_text_list
from django.utils.translation import gettext, gettext_lazy as _
@ -24,7 +23,7 @@ class LogEntryManager(models.Manager):
return self.model.objects.create(
user_id=user_id,
content_type_id=content_type_id,
object_id=force_text(object_id),
object_id=str(object_id),
object_repr=object_repr[:200],
action_flag=action_flag,
change_message=change_message,
@ -64,7 +63,7 @@ class LogEntry(models.Model):
ordering = ('-action_time',)
def __repr__(self):
return force_text(self.action_time)
return str(self.action_time)
def __str__(self):
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.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.encoding import force_text
from django.utils.html import format_html
from django.utils.http import urlencode
from django.utils.safestring import mark_safe
@ -722,7 +721,7 @@ class ModelAdmin(BaseModelAdmin):
user_id=request.user.pk,
content_type_id=get_content_type_for_model(object).pk,
object_id=object.pk,
object_repr=force_text(object),
object_repr=str(object),
action_flag=ADDITION,
change_message=message,
)
@ -738,7 +737,7 @@ class ModelAdmin(BaseModelAdmin):
user_id=request.user.pk,
content_type_id=get_content_type_for_model(object).pk,
object_id=object.pk,
object_repr=force_text(object),
object_repr=str(object),
action_flag=CHANGE,
change_message=message,
)
@ -763,7 +762,7 @@ class ModelAdmin(BaseModelAdmin):
"""
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" />')
def get_actions(self, request):
@ -1056,7 +1055,7 @@ class ModelAdmin(BaseModelAdmin):
if self.has_change_permission(request, obj):
obj_repr = format_html('<a href="{}">{}</a>', urlquote(obj_url), obj)
else:
obj_repr = force_text(obj)
obj_repr = str(obj)
msg_dict = {
'name': opts.verbose_name,
'obj': obj_repr,
@ -1652,7 +1651,7 @@ class ModelAdmin(BaseModelAdmin):
context = dict(
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_all=selection_note_all % {'total_count': cl.result_count},
title=cl.title,
@ -1710,7 +1709,7 @@ class ModelAdmin(BaseModelAdmin):
if request.POST and not protected: # The user has confirmed the deletion.
if perms_needed:
raise PermissionDenied
obj_display = force_text(obj)
obj_display = str(obj)
attr = str(to_field) if to_field else opts.pk.attname
obj_id = obj.serializable_value(attr)
self.log_deletion(request, obj, obj_display)
@ -1718,7 +1717,7 @@ class ModelAdmin(BaseModelAdmin):
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:
title = _("Cannot delete %(name)s") % {"name": object_name}
@ -1769,7 +1768,7 @@ class ModelAdmin(BaseModelAdmin):
self.admin_site.each_context(request),
title=_('Change history: %s') % obj,
action_list=action_list,
module_name=capfirst(force_text(opts.verbose_name_plural)),
module_name=str(capfirst(opts.verbose_name_plural)),
object=obj,
opts=opts,
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.urls import NoReverseMatch
from django.utils import formats
from django.utils.encoding import force_text
from django.utils.html import format_html
from django.utils.safestring import mark_safe
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)
if isinstance(f, (models.DateField, models.TimeField, models.ForeignKey)):
row_classes.append('nowrap')
if force_text(result_repr) == '':
if str(result_repr) == '':
result_repr = mark_safe('&nbsp;')
row_class = mark_safe(' class="%s"' % ' '.join(row_classes))
# 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
form[cl.model._meta.pk.name].is_hidden)):
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)
if form and not form[cl.model._meta.pk.name].is_hidden:
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.urls import NoReverseMatch, reverse
from django.utils import formats, timezone
from django.utils.encoding import force_text
from django.utils.html import format_html
from django.utils.text import capfirst
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
except FieldDoesNotExist:
if name == "__str__":
label = force_text(model._meta.verbose_name)
label = str(model._meta.verbose_name)
attr = str
else:
if callable(name):
@ -427,9 +426,9 @@ def display_for_value(value, empty_value_display, boolean=False):
elif isinstance(value, (int, decimal.Decimal, float)):
return formats.number_format(value)
elif isinstance(value, (list, tuple)):
return ', '.join(force_text(v) for v in value)
return ', '.join(str(v) for v in value)
else:
return force_text(value)
return str(value)
class NotRelationField(Exception):
@ -512,23 +511,23 @@ def construct_change_message(form, formsets, add):
for added_object in formset.new_objects:
change_message.append({
'added': {
'name': force_text(added_object._meta.verbose_name),
'object': force_text(added_object),
'name': str(added_object._meta.verbose_name),
'object': str(added_object),
}
})
for changed_object, changed_fields in formset.changed_objects:
change_message.append({
'changed': {
'name': force_text(changed_object._meta.verbose_name),
'object': force_text(changed_object),
'name': str(changed_object._meta.verbose_name),
'object': str(changed_object),
'fields': changed_fields,
}
})
for deleted_object in formset.deleted_objects:
change_message.append({
'deleted': {
'name': force_text(deleted_object._meta.verbose_name),
'object': force_text(deleted_object),
'name': str(deleted_object._meta.verbose_name),
'object': str(deleted_object),
}
})
return change_message

View File

@ -7,7 +7,6 @@ from django import forms
from django.db.models.deletion import CASCADE
from django.urls import reverse
from django.urls.exceptions import NoReverseMatch
from django.utils.encoding import force_text
from django.utils.html import smart_urlquote
from django.utils.safestring import mark_safe
from django.utils.text import Truncator
@ -215,7 +214,7 @@ class ManyToManyRawIdWidget(ForeignKeyRawIdWidget):
return value.split(',')
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):

View File

@ -2,7 +2,6 @@ from django.conf import settings
from django.contrib.auth import REDIRECT_FIELD_NAME
from django.contrib.auth.views import redirect_to_login
from django.core.exceptions import ImproperlyConfigured, PermissionDenied
from django.utils.encoding import force_text
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}.get_login_url().'.format(self.__class__.__name__)
)
return force_text(login_url)
return str(login_url)
def get_permission_denied_message(self):
"""

View File

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

View File

@ -11,7 +11,6 @@ from django.db.models.fields.related import (
lazy_related_operation,
)
from django.db.models.query_utils import PathInfo
from django.utils.encoding import force_text
from django.utils.functional import cached_property
@ -398,7 +397,7 @@ class GenericRelation(ForeignObject):
def value_to_string(self, obj):
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):
kwargs['private_only'] = True

View File

@ -2,7 +2,6 @@ from collections import defaultdict
from django.apps import apps
from django.db import models
from django.utils.encoding import force_text
from django.utils.translation import gettext_lazy as _
@ -151,7 +150,7 @@ class ContentType(models.Model):
model = self.model_class()
if not model:
return self.model
return force_text(model._meta.verbose_name)
return str(model._meta.verbose_name)
def model_class(self):
"""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.core import exceptions
from django.db.models import Field, TextField, Transform
from django.utils.encoding import force_text
from django.utils.translation import gettext_lazy as _
__all__ = ['HStoreField']
@ -57,14 +56,14 @@ class HStoreField(Field):
if isinstance(value, dict):
prep_value = {}
for key, val in value.items():
key = force_text(key)
key = str(key)
if val is not None:
val = force_text(val)
val = str(val)
prep_value[key] = val
value = prep_value
if isinstance(value, list):
value = [force_text(item) for item in value]
value = [str(item) for item in value]
return value

View File

@ -1,5 +1,4 @@
from django.db.models import Lookup, Transform
from django.utils.encoding import force_text
from .search import SearchVector, SearchVectorExact, SearchVectorField
@ -38,7 +37,7 @@ class HasKeys(PostgresSimpleLookup):
operator = '?&'
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):

View File

@ -10,7 +10,7 @@ from django.utils import timezone
from django.utils.crypto import (
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
# 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).
if isinstance(e, SuspiciousOperation):
logger = logging.getLogger('django.security.%s' % e.__class__.__name__)
logger.warning(force_text(e))
logger.warning(str(e))
return {}
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.exceptions import SuspiciousOperation
from django.utils import timezone
from django.utils.encoding import force_text
KEY_PREFIX = "django.contrib.sessions.cached_db"
@ -49,7 +48,7 @@ class SessionStore(DBStore):
except (self.model.DoesNotExist, SuspiciousOperation) as e:
if isinstance(e, SuspiciousOperation):
logger = logging.getLogger('django.security.%s' % e.__class__.__name__)
logger.warning(force_text(e))
logger.warning(str(e))
self._session_key = None
data = {}
return data

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -55,7 +55,7 @@ ADDRESS_HEADERS = {
def forbid_multi_line_headers(name, val, encoding):
"""Forbid multi-line headers to prevent header injection."""
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:
raise BadHeaderError("Header values can't contain newlines (got %r for header %r)" % (val, name))
try:
@ -100,7 +100,7 @@ def sanitize_address(addr, encoding):
Format a pair of (name, address) or an email address string.
"""
if not isinstance(addr, tuple):
addr = parseaddr(force_text(addr))
addr = parseaddr(addr)
nm, addr = addr
localpart, domain = None, None
nm = Header(nm, encoding).encode()
@ -258,11 +258,11 @@ class EmailMessage:
msg = self._create_message(msg)
msg['Subject'] = self.subject
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:
msg['Cc'] = ', '.join(map(force_text, self.cc))
msg['Cc'] = ', '.join(map(str, self.cc))
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
# accommodate that when doing comparisons.

View File

@ -11,7 +11,6 @@ from django.apps import apps
from django.conf import settings
from django.core.serializers import base
from django.db import DEFAULT_DB_ALIAS, models
from django.utils.encoding import force_text
from django.utils.xmlutils import (
SimplerXMLGenerator, UnserializableContentError,
)
@ -48,11 +47,11 @@ class Serializer(base.Serializer):
raise base.SerializationError("Non-model object (%s) encountered during serialization" % type(obj))
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'):
obj_pk = obj._get_pk_val()
if obj_pk is not None:
attrs['pk'] = force_text(obj_pk)
attrs['pk'] = str(obj_pk)
self.xml.startElement("object", attrs)
@ -101,10 +100,10 @@ class Serializer(base.Serializer):
# Iterable natural keys are rolled out as subelements
for key_value in related:
self.xml.startElement("natural", {})
self.xml.characters(force_text(key_value))
self.xml.characters(str(key_value))
self.xml.endElement("natural")
else:
self.xml.characters(force_text(related_att))
self.xml.characters(str(related_att))
else:
self.xml.addQuickElement("None")
self.xml.endElement("field")
@ -125,13 +124,13 @@ class Serializer(base.Serializer):
self.xml.startElement("object", {})
for key_value in 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("object")
else:
def handle_m2m(value):
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():
handle_m2m(relobj)
@ -144,7 +143,7 @@ class Serializer(base.Serializer):
self.xml.startElement("field", OrderedDict([
("name", field.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.utils.deconstruct import deconstructible
from django.utils.encoding import force_text
from django.utils.functional import SimpleLazyObject
from django.utils.ipv6 import is_valid_ipv6_address
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
if inverse_match is False, otherwise raise ValidationError.
"""
if not (self.inverse_match is not bool(self.regex.search(
force_text(value)))):
if not (self.inverse_match is not bool(self.regex.search(str(value)))):
raise ValidationError(self.message, code=self.code)
def __eq__(self, other):

View File

@ -410,7 +410,7 @@ class BaseDatabaseOperations:
def prep_for_like_query(self, x):
"""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
# 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 (
parse_date, parse_datetime, parse_duration, parse_time,
)
from django.utils.encoding import force_text
from .client import DatabaseClient # 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):
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):

View File

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

View File

@ -25,7 +25,7 @@ from django.utils.dateparse import (
parse_date, parse_datetime, parse_duration, parse_time,
)
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.ipv6 import clean_ipv6_address
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.
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):
"""Flattened version of choices tuple."""
@ -1058,7 +1058,7 @@ class CharField(Field):
def to_python(self, value):
if isinstance(value, str) or value is None:
return value
return force_text(value)
return str(value)
def get_prep_value(self, value):
value = super().get_prep_value(value)
@ -1920,7 +1920,7 @@ class GenericIPAddressField(Field):
if value is None:
return None
if not isinstance(value, str):
value = force_text(value)
value = str(value)
value = value.strip()
if ':' in value:
return clean_ipv6_address(value, self.unpack_ipv4, self.error_messages['invalid'])
@ -2089,7 +2089,7 @@ class TextField(Field):
def to_python(self, value):
if isinstance(value, str) or value is None:
return value
return force_text(value)
return str(value)
def get_prep_value(self, 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.utils.encoding import force_text
from django.utils.functional import cached_property
from . import BLANK_CHOICE_DASH
@ -123,7 +122,7 @@ class ForeignObjectRel:
initially for utilization by RelatedFieldListFilter.
"""
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):

View File

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

View File

@ -4,7 +4,6 @@ import warnings
from django.forms.utils import flatatt, pretty_name
from django.forms.widgets import Textarea, TextInput
from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.encoding import force_text
from django.utils.functional import cached_property
from django.utils.html import conditional_escape, format_html, html_safe
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
associated Form has specified auto_id. Return an empty string otherwise.
"""
auto_id = self.form.auto_id
if auto_id and '%s' in force_text(auto_id):
return force_text(auto_id) % self.html_name
auto_id = self.form.auto_id # Boolean or string
if auto_id and '%s' in str(auto_id):
return auto_id % self.html_name
elif auto_id:
return self.html_name
return ''

View File

@ -28,7 +28,6 @@ from django.forms.widgets import (
from django.utils import formats
from django.utils.dateparse import parse_duration
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.translation import gettext_lazy as _, ngettext_lazy
@ -221,7 +220,7 @@ class CharField(Field):
"""Return a string."""
if value in self.empty_values:
return self.empty_value
value = force_text(value)
value = str(value)
if self.strip:
value = value.strip()
return value
@ -268,7 +267,7 @@ class IntegerField(Field):
value = formats.sanitize_separators(value)
# Strip trailing decimal and zeros.
try:
value = int(self.re_decimal.sub('', force_text(value)))
value = int(self.re_decimal.sub('', str(value)))
except (ValueError, TypeError):
raise ValidationError(self.error_messages['invalid'], code='invalid')
return value
@ -341,7 +340,7 @@ class DecimalField(IntegerField):
return None
if self.localize:
value = formats.sanitize_separators(value)
value = force_text(value).strip()
value = str(value).strip()
try:
value = Decimal(value)
except DecimalException:
@ -484,7 +483,7 @@ class DurationField(Field):
return None
if isinstance(value, datetime.timedelta):
return value
value = parse_duration(force_text(value))
value = parse_duration(str(value))
if value is None:
raise ValidationError(self.error_messages['invalid'], code='invalid')
return value
@ -784,7 +783,7 @@ class ChoiceField(Field):
"""Return a string."""
if value in self.empty_values:
return ''
return force_text(value)
return str(value)
def validate(self, value):
"""Validate that the input is in self.choices."""
@ -798,15 +797,15 @@ class ChoiceField(Field):
def valid_value(self, value):
"""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:
if isinstance(v, (list, tuple)):
# This is an optgroup, so look inside the group for options
for k2, v2 in v:
if value == k2 or text_value == force_text(k2):
if value == k2 or text_value == str(k2):
return True
else:
if value == k or text_value == force_text(k):
if value == k or text_value == str(k):
return True
return False
@ -851,7 +850,7 @@ class MultipleChoiceField(ChoiceField):
return []
elif not isinstance(value, (list, tuple)):
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):
"""Validate that the input is a list or tuple."""
@ -873,8 +872,8 @@ class MultipleChoiceField(ChoiceField):
data = []
if len(initial) != len(data):
return True
initial_set = set(force_text(value) for value in initial)
data_set = set(force_text(value) for value in data)
initial_set = set(str(value) for value in initial)
data_set = set(str(value) for value in data)
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
from django.forms.utils import ErrorDict, ErrorList, pretty_name # NOQA
from django.forms.widgets import Media, MediaDefiningClass
from django.utils.encoding import force_text
from django.utils.functional import cached_property
from django.utils.html import conditional_escape, html_safe
from django.utils.safestring import mark_safe
@ -205,7 +204,7 @@ class BaseForm:
if bf.is_hidden:
if bf_errors:
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])
hidden_fields.append(str(bf))
else:
@ -216,10 +215,10 @@ class BaseForm:
html_class_attr = ' class="%s"' % css_classes
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:
label = conditional_escape(force_text(bf.label))
label = conditional_escape(bf.label)
label = bf.label_tag(label) or ''
else:
label = ''

View File

@ -16,7 +16,6 @@ from django.forms.utils import ErrorList
from django.forms.widgets import (
HiddenInput, MultipleHiddenInput, SelectMultiple,
)
from django.utils.encoding import force_text
from django.utils.text import capfirst, get_text_list
from django.utils.translation import gettext, gettext_lazy as _
@ -1085,7 +1084,7 @@ class InlineForeignKeyField(Field):
orig = getattr(self.parent_instance, self.to_field)
else:
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')
return self.parent_instance
@ -1176,7 +1175,7 @@ class ModelChoiceField(ChoiceField):
presented by this object. Subclasses can override this method to
customize the display of the choices.
"""
return force_text(obj)
return str(obj)
def _get_choices(self):
# If self._choices is set, then somebody must have manually set
@ -1219,7 +1218,7 @@ class ModelChoiceField(ChoiceField):
def has_changed(self, initial, data):
initial_value = initial if initial 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):
@ -1286,9 +1285,9 @@ class ModelMultipleChoiceField(ModelChoiceField):
params={'pk': pk},
)
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:
if force_text(val) not in pks:
if str(val) not in pks:
raise ValidationError(
self.error_messages['invalid_choice'],
code='invalid_choice',
@ -1310,8 +1309,8 @@ class ModelMultipleChoiceField(ModelChoiceField):
data = []
if len(initial) != len(data):
return True
initial_set = set(force_text(value) for value in self.prepare_value(initial))
data_set = set(force_text(value) for value in data)
initial_set = set(str(value) for value in self.prepare_value(initial))
data_set = set(str(value) for value in data)
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.utils import datetime_safe, formats
from django.utils.dates import MONTHS
from django.utils.encoding import force_text
from django.utils.formats import get_format
from django.utils.html import format_html, html_safe
from django.utils.safestring import mark_safe
@ -184,7 +183,7 @@ class Widget(metaclass=MediaDefiningClass):
return None
if self.is_localized:
return formats.localize_input(value)
return force_text(value)
return str(value)
def get_context(self, name, value, attrs):
context = {}
@ -483,7 +482,7 @@ class CheckboxInput(Input):
"""Only return the 'value' attribute if value isn't empty."""
if value is True or value is False or value is None or value == '':
return
return force_text(value)
return str(value)
def get_context(self, name, value, attrs):
if self.check_test(value):
@ -570,7 +569,7 @@ class ChoiceWidget(Widget):
for subvalue, sublabel in choices:
selected = (
force_text(subvalue) in value and
str(subvalue) in value and
(not has_selected or self.allow_multiple_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.http.cookie import SimpleCookie
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
_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):
super().__init__(*args, **kwargs)
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:
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.urls import NoReverseMatch, reverse
from django.utils.deprecation import RemovedInDjango30Warning
from django.utils.encoding import force_text
from django.utils.functional import Promise
@ -138,7 +137,7 @@ def resolve_url(to, *args, **kwargs):
if isinstance(to, Promise):
# Expand the lazy instance, as it can cause issues when it is passed
# further to some Python functions like urlparse.
to = force_text(to)
to = str(to)
if isinstance(to, str):
# 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.exceptions import ImproperlyConfigured
from django.utils.datastructures import MultiValueDict
from django.utils.encoding import force_text
from django.utils.functional import cached_property
from django.utils.http import RFC3986_SUBDELIMS
from django.utils.regex_helper import normalize
@ -92,7 +91,7 @@ class LocaleRegexDescriptor:
return instance.__dict__['regex']
language_code = get_language()
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]
def _compile(self, regex):
@ -347,7 +346,7 @@ class RegexURLResolver(LocaleRegexProvider):
return name in self._callback_strs
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 = []
match = self.regex.search(path)
if match:
@ -422,8 +421,8 @@ class RegexURLResolver(LocaleRegexProvider):
def _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs):
if args and kwargs:
raise ValueError("Don't mix *args and **kwargs in call to reverse()!")
text_args = [force_text(v) for v in args]
text_kwargs = {k: force_text(v) for (k, v) in kwargs.items()}
text_args = [str(v) for v in args]
text_kwargs = {k: str(v) for (k, v) in kwargs.items()}
if not self._populated:
self._populate()

View File

@ -18,7 +18,6 @@ import time
from django.utils.dates import (
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.translation import gettext as _
@ -29,14 +28,14 @@ re_escaped = re.compile(r'\\(.)')
class Formatter:
def format(self, formatstr):
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 type(self.data) is datetime.date and hasattr(TimeFormat, piece):
raise TypeError(
"The format for date objects may not contain "
"time-related format specifiers (found '%s')." % piece
)
pieces.append(force_text(getattr(self, piece)()))
pieces.append(str(getattr(self, piece)()))
elif piece:
pieces.append(re_escaped.sub(r'\1', piece))
return ''.join(pieces)

View File

@ -43,7 +43,7 @@ def escape(text):
conditional_escape() instead.
"""
return mark_safe(
force_text(text).replace('&', '&amp;').replace('<', '&lt;')
str(text).replace('&', '&amp;').replace('<', '&lt;')
.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)
def escapejs(value):
"""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):
@ -121,8 +121,8 @@ def format_html_join(sep, format_string, args_generator):
@keep_lazy_text
def linebreaks(value, autoescape=False):
"""Convert newlines into <p> and <br />s."""
value = normalize_newlines(force_text(value))
paras = re.split('\n{2,}', value)
value = normalize_newlines(value)
paras = re.split('\n{2,}', str(value))
if autoescape:
paras = ['<p>%s</p>' % escape(p).replace('\n', '<br />') for p in paras]
else:

View File

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

View File

@ -6,7 +6,6 @@ import warnings
from contextlib import ContextDecorator
from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.encoding import force_text
from django.utils.functional import lazy
__all__ = [
@ -226,7 +225,7 @@ def _string_concat(*strings):
'django.utils.translate.string_concat() is deprecated in '
'favor of django.utils.text.format_lazy().',
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)

View File

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

View File

@ -3,7 +3,6 @@ from django.http import (
HttpResponseServerError,
)
from django.template import Context, Engine, TemplateDoesNotExist, loader
from django.utils.encoding import force_text
from django.views.decorators.csrf import requires_csrf_token
ERROR_404_TEMPLATE_NAME = '404.html'
@ -117,5 +116,5 @@ def permission_denied(request, exception, template_name=ERROR_403_TEMPLATE_NAME)
raise
return HttpResponseForbidden('<h1>403 Forbidden</h1>', content_type='text/html')
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.forms import models as model_forms
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.detail import (
BaseDetailView, SingleObjectMixin, SingleObjectTemplateResponseMixin,
@ -49,13 +48,9 @@ class FormMixin(ContextMixin):
def get_success_url(self):
"""Return the URL to redirect to after processing a valid form."""
if self.success_url:
# Forcing possible reverse_lazy evaluation
url = force_text(self.success_url)
else:
raise ImproperlyConfigured(
"No URL to redirect to. Provide a success_url.")
return url
if not self.success_url:
raise ImproperlyConfigured("No URL to redirect to. Provide a success_url.")
return str(self.success_url) # success_url may be lazy
def form_valid(self, form):
"""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
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
examples in this document, ``value`` would be a ``Hand`` instance, not a
``HandField``). So if your ``__str__()`` method automatically converts to
the string form of your Python object, you can save yourself a lot of work.
``str()`` on the value. (In our examples in this document, ``value`` would
be a ``Hand`` instance, not a ``HandField``). So if your ``__str__()``
method automatically converts to the string form of your Python object, you
can save yourself a lot of work.
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
work::
from django.utils.encoding import force_text
from django.core.serializers.json import DjangoJSONEncoder
class LazyEncoder(DjangoJSONEncoder):
def default(self, obj):
if isinstance(obj, YourCustomType):
return force_text(obj)
return str(obj)
return super().default(obj)
You can then pass ``cls=LazyEncoder`` to the ``serializers.serialize()``