From dc8834cad41aa407f402dc54788df3cd37ab3e22 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Wed, 11 Jan 2017 23:17:25 +0100 Subject: [PATCH] Refs #23919 -- Removed unneeded force_str calls --- django/contrib/admin/utils.py | 7 ++--- django/contrib/auth/hashers.py | 6 ++-- .../management/commands/changepassword.py | 3 +- .../management/commands/createsuperuser.py | 11 ++++--- django/core/cache/backends/memcached.py | 5 ---- django/core/checks/messages.py | 4 +-- django/core/files/base.py | 4 +-- django/core/files/uploadedfile.py | 4 +-- django/core/handlers/wsgi.py | 9 ++---- django/core/mail/backends/smtp.py | 3 +- django/core/management/base.py | 10 +++---- .../core/management/commands/makemessages.py | 6 ++-- django/core/signing.py | 17 ++++------- django/db/backends/mysql/base.py | 3 +- django/db/backends/postgresql/base.py | 3 +- django/db/models/base.py | 4 +-- django/db/models/fields/files.py | 4 +-- django/forms/fields.py | 8 ++--- django/forms/widgets.py | 4 +-- django/http/request.py | 10 ++----- django/http/response.py | 5 +--- django/template/base.py | 5 ++-- django/test/client.py | 10 +++---- django/test/utils.py | 3 +- django/urls/resolvers.py | 4 +-- django/utils/formats.py | 8 ++--- django/utils/html.py | 6 ++-- django/utils/tree.py | 6 ++-- django/views/debug.py | 4 +-- django/views/generic/dates.py | 4 +-- tests/admin_scripts/tests.py | 2 +- tests/admin_utils/tests.py | 6 +--- tests/auth_tests/test_management.py | 3 +- tests/contenttypes_tests/tests.py | 4 +-- tests/dbshell/test_postgresql_psycopg2.py | 30 +++++++------------ tests/file_uploads/views.py | 6 ++-- tests/generic_views/test_list.py | 3 +- tests/handlers/tests.py | 6 +--- tests/httpwrappers/tests.py | 10 ++----- tests/middleware/tests.py | 3 +- tests/migrations/test_writer.py | 3 +- tests/or_lookups/tests.py | 5 ++-- tests/requests/tests.py | 3 +- tests/signing/tests.py | 3 +- 44 files changed, 100 insertions(+), 167 deletions(-) diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index 297796254df..c55173d6c9e 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -11,7 +11,7 @@ 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_str, force_text, smart_text +from django.utils.encoding import force_text, smart_text from django.utils.html import format_html from django.utils.text import capfirst from django.utils.translation import ( @@ -340,12 +340,9 @@ def label_for_field(name, model, model_admin=None, return_attr=False): # field is likely a ForeignObjectRel label = field.related_model._meta.verbose_name except FieldDoesNotExist: - if name == "__unicode__": + if name == "__str__": label = force_text(model._meta.verbose_name) attr = str - elif name == "__str__": - label = force_str(model._meta.verbose_name) - attr = bytes else: if callable(name): attr = name diff --git a/django/contrib/auth/hashers.py b/django/contrib/auth/hashers.py index 0446cf501f0..c52f31db59a 100644 --- a/django/contrib/auth/hashers.py +++ b/django/contrib/auth/hashers.py @@ -13,7 +13,7 @@ from django.dispatch import receiver from django.utils.crypto import ( constant_time_compare, get_random_string, pbkdf2, ) -from django.utils.encoding import force_bytes, force_str, force_text +from django.utils.encoding import force_bytes, force_text from django.utils.module_loading import import_string from django.utils.translation import ugettext_noop as _ @@ -627,7 +627,7 @@ class CryptPasswordHasher(BasePasswordHasher): def encode(self, password, salt): crypt = self._load_library() assert len(salt) == 2 - data = crypt.crypt(force_str(password), salt) + data = crypt.crypt(password, salt) assert data is not None # A platform like OpenBSD with a dummy crypt module. # we don't need to store the salt, but Django used to do this return "%s$%s$%s" % (self.algorithm, '', data) @@ -636,7 +636,7 @@ class CryptPasswordHasher(BasePasswordHasher): crypt = self._load_library() algorithm, salt, data = encoded.split('$', 2) assert algorithm == self.algorithm - return constant_time_compare(data, crypt.crypt(force_str(password), data)) + return constant_time_compare(data, crypt.crypt(password, data)) def safe_summary(self, encoded): algorithm, salt, data = encoded.split('$', 2) diff --git a/django/contrib/auth/management/commands/changepassword.py b/django/contrib/auth/management/commands/changepassword.py index c0c4ce3c611..f4ec15a4390 100644 --- a/django/contrib/auth/management/commands/changepassword.py +++ b/django/contrib/auth/management/commands/changepassword.py @@ -5,7 +5,6 @@ from django.contrib.auth.password_validation import validate_password from django.core.exceptions import ValidationError from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS -from django.utils.encoding import force_str UserModel = get_user_model() @@ -16,7 +15,7 @@ class Command(BaseCommand): requires_system_checks = False def _get_pass(self, prompt="Password: "): - p = getpass.getpass(prompt=force_str(prompt)) + p = getpass.getpass(prompt=prompt) if not p: raise CommandError("aborted") return p diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py index 7a6d0b02315..d9fd70b6f1e 100644 --- a/django/contrib/auth/management/commands/createsuperuser.py +++ b/django/contrib/auth/management/commands/createsuperuser.py @@ -10,7 +10,6 @@ from django.contrib.auth.password_validation import validate_password from django.core import exceptions from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS -from django.utils.encoding import force_str from django.utils.text import capfirst @@ -103,12 +102,12 @@ class Command(BaseCommand): if default_username: input_msg += " (leave blank to use '%s')" % default_username username_rel = self.username_field.remote_field - input_msg = force_str('%s%s: ' % ( + input_msg = '%s%s: ' % ( input_msg, ' (%s.%s)' % ( username_rel.model._meta.object_name, username_rel.field_name - ) if username_rel else '') + ) if username_rel else '' ) username = self.get_input_data(self.username_field, input_msg, default_username) if not username: @@ -126,13 +125,13 @@ class Command(BaseCommand): field = self.UserModel._meta.get_field(field_name) user_data[field_name] = options[field_name] while user_data[field_name] is None: - message = force_str('%s%s: ' % ( + message = '%s%s: ' % ( capfirst(field.verbose_name), ' (%s.%s)' % ( field.remote_field.model._meta.object_name, field.remote_field.field_name, ) if field.remote_field else '', - )) + ) input_value = self.get_input_data(field, message) user_data[field_name] = input_value fake_user_data[field_name] = input_value @@ -144,7 +143,7 @@ class Command(BaseCommand): # Get a password while password is None: password = getpass.getpass() - password2 = getpass.getpass(force_str('Password (again): ')) + password2 = getpass.getpass('Password (again): ') if password != password2: self.stderr.write("Error: Your passwords didn't match.") password = None diff --git a/django/core/cache/backends/memcached.py b/django/core/cache/backends/memcached.py index 82589a82b08..29bd2a95cdd 100644 --- a/django/core/cache/backends/memcached.py +++ b/django/core/cache/backends/memcached.py @@ -7,7 +7,6 @@ import warnings from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache from django.utils.deprecation import RemovedInDjango21Warning -from django.utils.encoding import force_str from django.utils.functional import cached_property @@ -65,10 +64,6 @@ class BaseMemcachedCache(BaseCache): timeout += int(time.time()) return int(timeout) - def make_key(self, key, version=None): - # Python 2 memcache requires the key to be a byte string. - return force_str(super(BaseMemcachedCache, self).make_key(key, version)) - def add(self, key, value, timeout=DEFAULT_TIMEOUT, version=None): key = self.make_key(key, version=version) return self._cache.add(key, value, self.get_backend_timeout(timeout)) diff --git a/django/core/checks/messages.py b/django/core/checks/messages.py index 0c44d350959..bb0e2b335c2 100644 --- a/django/core/checks/messages.py +++ b/django/core/checks/messages.py @@ -1,4 +1,4 @@ -from django.utils.encoding import force_str +from django.utils.encoding import force_text # Levels DEBUG = 10 @@ -35,7 +35,7 @@ class CheckMessage: # method doesn't return "applabel.modellabel" and cannot be changed. obj = self.obj._meta.label else: - obj = force_str(self.obj) + obj = force_text(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) diff --git a/django/core/files/base.py b/django/core/files/base.py index 0834c56b8d6..225c6dd3494 100644 --- a/django/core/files/base.py +++ b/django/core/files/base.py @@ -2,7 +2,7 @@ import os from io import BytesIO, StringIO, UnsupportedOperation from django.core.files.utils import FileProxyMixin -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text class File(FileProxyMixin): @@ -20,7 +20,7 @@ class File(FileProxyMixin): return force_text(self.name or '') def __repr__(self): - return force_str("<%s: %s>" % (self.__class__.__name__, self or "None")) + return "<%s: %s>" % (self.__class__.__name__, self or "None") def __bool__(self): return bool(self.name) diff --git a/django/core/files/uploadedfile.py b/django/core/files/uploadedfile.py index 6f71fc3b95f..aa1038ae783 100644 --- a/django/core/files/uploadedfile.py +++ b/django/core/files/uploadedfile.py @@ -9,7 +9,6 @@ from io import BytesIO from django.conf import settings from django.core.files import temp as tempfile from django.core.files.base import File -from django.utils.encoding import force_str __all__ = ('UploadedFile', 'TemporaryUploadedFile', 'InMemoryUploadedFile', 'SimpleUploadedFile') @@ -33,8 +32,7 @@ class UploadedFile(File): self.content_type_extra = content_type_extra def __repr__(self): - return force_str("<%s: %s (%s)>" % ( - self.__class__.__name__, self.name, self.content_type)) + return "<%s: %s (%s)>" % (self.__class__.__name__, self.name, self.content_type) def _get_name(self): return self._name diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 69b5f1c54d3..c61dae1dfa0 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -8,13 +8,10 @@ from django.conf import settings from django.core import signals from django.core.handlers import base from django.urls import set_script_prefix -from django.utils.encoding import ( - force_str, force_text, repercent_broken_unicode, -) +from django.utils.encoding import force_text, repercent_broken_unicode from django.utils.functional import cached_property -# encode() and decode() expect the charset to be a native string. -ISO_8859_1, UTF_8 = str('iso-8859-1'), str('utf-8') +ISO_8859_1, UTF_8 = 'iso-8859-1', 'utf-8' _slashes_re = re.compile(br'/+') @@ -159,7 +156,7 @@ class WSGIHandler(base.BaseHandler): response_headers = [(str(k), str(v)) for k, v in response.items()] for c in response.cookies.values(): response_headers.append((str('Set-Cookie'), str(c.output(header='')))) - start_response(force_str(status), response_headers) + start_response(status, response_headers) if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'): response = environ['wsgi.file_wrapper'](response.file_to_stream) return response diff --git a/django/core/mail/backends/smtp.py b/django/core/mail/backends/smtp.py index dbff399d8c2..b6d5c2fed38 100644 --- a/django/core/mail/backends/smtp.py +++ b/django/core/mail/backends/smtp.py @@ -8,7 +8,6 @@ from django.conf import settings from django.core.mail.backends.base import BaseEmailBackend from django.core.mail.message import sanitize_address from django.core.mail.utils import DNS_NAME -from django.utils.encoding import force_str class EmailBackend(BaseEmailBackend): @@ -68,7 +67,7 @@ class EmailBackend(BaseEmailBackend): if not self.use_ssl and self.use_tls: self.connection.starttls(keyfile=self.ssl_keyfile, certfile=self.ssl_certfile) if self.username and self.password: - self.connection.login(force_str(self.username), force_str(self.password)) + self.connection.login(self.username, self.password) return True except (smtplib.SMTPException, socket.error): if not self.fail_silently: diff --git a/django/core/management/base.py b/django/core/management/base.py index ae8c6731c96..80f7e0a5756 100644 --- a/django/core/management/base.py +++ b/django/core/management/base.py @@ -5,6 +5,7 @@ be executed through ``django-admin`` or ``manage.py``). import os import sys from argparse import ArgumentParser +from io import TextIOBase import django from django.core import checks @@ -12,7 +13,6 @@ from django.core.exceptions import ImproperlyConfigured from django.core.management.color import color_style, no_style from django.db import DEFAULT_DB_ALIAS, connections from django.db.migrations.exceptions import MigrationSchemaMissing -from django.utils.encoding import force_str class CommandError(Exception): @@ -73,7 +73,7 @@ def handle_default_options(options): sys.path.insert(0, options.pythonpath) -class OutputWrapper: +class OutputWrapper(TextIOBase): """ Wrapper around stdout/stderr """ @@ -104,7 +104,7 @@ class OutputWrapper: if ending and not msg.endswith(ending): msg += ending style_func = style_func or self.style_func - self._out.write(force_str(style_func(msg))) + self._out.write(style_func(msg)) class BaseCommand: @@ -377,9 +377,9 @@ class BaseCommand: if issues: visible_issue_count += len(issues) formatted = ( - self.style.ERROR(force_str(e)) + self.style.ERROR(str(e)) if e.is_serious() - else self.style.WARNING(force_str(e)) + else self.style.WARNING(str(e)) for e in issues) formatted = "\n".join(sorted(formatted)) body += '\n%s:\n%s\n' % (group_name, formatted) diff --git a/django/core/management/commands/makemessages.py b/django/core/management/commands/makemessages.py index 830b6efe05e..48ed70845ab 100644 --- a/django/core/management/commands/makemessages.py +++ b/django/core/management/commands/makemessages.py @@ -15,7 +15,7 @@ from django.core.management.utils import ( find_command, handle_extensions, popen_wrapper, ) from django.utils._os import upath -from django.utils.encoding import DEFAULT_LOCALE_ENCODING, force_str +from django.utils.encoding import DEFAULT_LOCALE_ENCODING from django.utils.functional import cached_property from django.utils.jslex import prepare_js_for_gettext from django.utils.text import get_text_list @@ -557,7 +557,7 @@ class Command(BaseCommand): input_files = [bf.work_path for bf in build_files] with NamedTemporaryFile(mode='w+') as input_files_list: - input_files_list.write(force_str('\n'.join(input_files), encoding=DEFAULT_LOCALE_ENCODING)) + input_files_list.write(('\n'.join(input_files))) input_files_list.flush() args.extend(['--files-from', input_files_list.name]) args.extend(self.xgettext_options) @@ -649,7 +649,7 @@ class Command(BaseCommand): with open(django_po, 'r', encoding='utf-8') as fp: m = plural_forms_re.search(fp.read()) if m: - plural_form_line = force_str(m.group('value')) + plural_form_line = m.group('value') if self.verbosity > 1: self.stdout.write("copying plural forms: %s\n" % plural_form_line) lines = [] diff --git a/django/core/signing.py b/django/core/signing.py index 811d23396fc..b6bb7492471 100644 --- a/django/core/signing.py +++ b/django/core/signing.py @@ -43,7 +43,7 @@ import zlib from django.conf import settings from django.utils import baseconv from django.utils.crypto import constant_time_compare, salted_hmac -from django.utils.encoding import force_bytes, force_str, force_text +from django.utils.encoding import force_bytes, force_text from django.utils.module_loading import import_string _SEP_UNSAFE = re.compile(r'^[A-z0-9-_=]*$') @@ -152,25 +152,21 @@ class Signer: def __init__(self, key=None, sep=':', salt=None): # Use of native strings in all versions of Python self.key = key or settings.SECRET_KEY - self.sep = force_str(sep) + self.sep = sep if _SEP_UNSAFE.match(self.sep): raise ValueError( 'Unsafe Signer separator: %r (cannot be empty or consist of ' 'only A-z0-9-_=)' % sep, ) - self.salt = force_str(salt or '%s.%s' % (self.__class__.__module__, self.__class__.__name__)) + self.salt = salt or '%s.%s' % (self.__class__.__module__, self.__class__.__name__) def signature(self, value): - signature = base64_hmac(self.salt + 'signer', value, self.key) - # Convert the signature from bytes to str only on Python 3 - return force_str(signature) + return force_text(base64_hmac(self.salt + 'signer', value, self.key)) def sign(self, value): - value = force_str(value) - return str('%s%s%s') % (value, self.sep, self.signature(value)) + return '%s%s%s' % (value, self.sep, self.signature(value)) def unsign(self, signed_value): - signed_value = force_str(signed_value) if self.sep not in signed_value: raise BadSignature('No "%s" found in value' % self.sep) value, sig = signed_value.rsplit(self.sep, 1) @@ -185,8 +181,7 @@ class TimestampSigner(Signer): return baseconv.base62.encode(int(time.time())) def sign(self, value): - value = force_str(value) - value = str('%s%s%s') % (value, self.sep, self.timestamp()) + value = '%s%s%s' % (force_text(value), self.sep, self.timestamp()) return super(TimestampSigner, self).sign(value) def unsign(self, value, max_age=None): diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 9f911343258..d056392753a 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -12,7 +12,6 @@ from django.db import utils from django.db.backends import utils as backend_utils from django.db.backends.base.base import BaseDatabaseWrapper from django.utils import six -from django.utils.encoding import force_str from django.utils.functional import cached_property from django.utils.safestring import SafeBytes, SafeText @@ -225,7 +224,7 @@ class DatabaseWrapper(BaseDatabaseWrapper): if settings_dict['NAME']: kwargs['db'] = settings_dict['NAME'] if settings_dict['PASSWORD']: - kwargs['passwd'] = force_str(settings_dict['PASSWORD']) + kwargs['passwd'] = settings_dict['PASSWORD'] if settings_dict['HOST'].startswith('/'): kwargs['unix_socket'] = settings_dict['HOST'] elif settings_dict['HOST']: diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py index 10b54faa209..a3b293ee366 100644 --- a/django/db/backends/postgresql/base.py +++ b/django/db/backends/postgresql/base.py @@ -12,7 +12,6 @@ from django.core.exceptions import ImproperlyConfigured from django.db import DEFAULT_DB_ALIAS from django.db.backends.base.base import BaseDatabaseWrapper from django.db.utils import DatabaseError as WrappedDatabaseError -from django.utils.encoding import force_str from django.utils.functional import cached_property from django.utils.safestring import SafeBytes, SafeText @@ -160,7 +159,7 @@ class DatabaseWrapper(BaseDatabaseWrapper): if settings_dict['USER']: conn_params['user'] = settings_dict['USER'] if settings_dict['PASSWORD']: - conn_params['password'] = force_str(settings_dict['PASSWORD']) + conn_params['password'] = settings_dict['PASSWORD'] if settings_dict['HOST']: conn_params['host'] = settings_dict['HOST'] if settings_dict['PORT']: diff --git a/django/db/models/base.py b/django/db/models/base.py index 8cba12bb6e3..047f90ec733 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -26,7 +26,7 @@ from django.db.models.signals import ( class_prepared, post_init, post_save, pre_init, pre_save, ) from django.db.models.utils import make_model_tuple -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.functional import curry from django.utils.text import capfirst, get_text_list from django.utils.translation import ugettext_lazy as _ @@ -505,7 +505,7 @@ class Model(metaclass=ModelBase): u = str(self) except (UnicodeEncodeError, UnicodeDecodeError): u = '[Bad Unicode data]' - return force_str('<%s: %s>' % (self.__class__.__name__, u)) + return '<%s: %s>' % (self.__class__.__name__, u) def __str__(self): return '%s object' % self.__class__.__name__ diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index 1235f657303..d1937bd5dbe 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -9,7 +9,7 @@ from django.core.files.storage import default_storage from django.core.validators import validate_image_file_extension from django.db.models import signals from django.db.models.fields import Field -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.translation import ugettext_lazy as _ @@ -304,7 +304,7 @@ class FileField(Field): if callable(self.upload_to): filename = self.upload_to(instance, filename) else: - dirname = force_text(datetime.datetime.now().strftime(force_str(self.upload_to))) + dirname = force_text(datetime.datetime.now().strftime(self.upload_to)) filename = posixpath.join(dirname, filename) return self.storage.generate_filename(filename) diff --git a/django/forms/fields.py b/django/forms/fields.py index 20521b26eaa..b7846d43a68 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -29,7 +29,7 @@ from django.forms.widgets import ( from django.utils import formats, six from django.utils.dateparse import parse_duration from django.utils.duration import duration_string -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.ipv6 import clean_ipv6_address from django.utils.translation import ugettext_lazy as _, ungettext_lazy @@ -429,7 +429,7 @@ class DateField(BaseTemporalField): return super(DateField, self).to_python(value) def strptime(self, value, format): - return datetime.datetime.strptime(force_str(value), format).date() + return datetime.datetime.strptime(value, format).date() class TimeField(BaseTemporalField): @@ -451,7 +451,7 @@ class TimeField(BaseTemporalField): return super(TimeField, self).to_python(value) def strptime(self, value, format): - return datetime.datetime.strptime(force_str(value), format).time() + return datetime.datetime.strptime(value, format).time() class DateTimeField(BaseTemporalField): @@ -482,7 +482,7 @@ class DateTimeField(BaseTemporalField): return from_current_timezone(result) def strptime(self, value, format): - return datetime.datetime.strptime(force_str(value), format) + return datetime.datetime.strptime(value, format) class DurationField(Field): diff --git a/django/forms/widgets.py b/django/forms/widgets.py index d8b4d6a4dc4..a8760623d20 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -13,7 +13,7 @@ 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_str, force_text +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 @@ -986,7 +986,7 @@ class SelectDateWidget(Widget): if settings.USE_L10N: try: input_format = get_format('DATE_INPUT_FORMATS')[0] - d = datetime.datetime.strptime(force_str(value), input_format) + d = datetime.datetime.strptime(value, input_format) year, month, day = d.year, d.month, d.day except ValueError: pass diff --git a/django/http/request.py b/django/http/request.py index 4ca2ed25fad..6f3b0c9951e 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -14,9 +14,7 @@ from django.core.files import uploadhandler from django.http.multipartparser import MultiPartParser, MultiPartParserError from django.utils import six from django.utils.datastructures import ImmutableList, MultiValueDict -from django.utils.encoding import ( - escape_uri_path, force_bytes, force_str, iri_to_uri, -) +from django.utils.encoding import escape_uri_path, force_bytes, iri_to_uri from django.utils.http import is_same_domain, limited_parse_qsl RAISE_ERROR = object() @@ -64,10 +62,8 @@ class HttpRequest: def __repr__(self): if self.method is None or not self.get_full_path(): - return force_str('<%s>' % self.__class__.__name__) - return force_str( - '<%s: %s %r>' % (self.__class__.__name__, self.method, force_str(self.get_full_path())) - ) + return '<%s>' % self.__class__.__name__ + return '<%s: %s %r>' % (self.__class__.__name__, self.method, self.get_full_path()) def _get_raw_host(self): """ diff --git a/django/http/response.py b/django/http/response.py index c5294acbbdc..e992adaed54 100644 --- a/django/http/response.py +++ b/django/http/response.py @@ -13,9 +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_str, force_text, iri_to_uri, -) +from django.utils.encoding import force_bytes, force_text, iri_to_uri from django.utils.http import cookie_date _charset_from_content_type_re = re.compile(r';\s*charset=(?P[^\s;]+)', re.I) @@ -170,7 +168,6 @@ class HttpResponseBase: - an aware ``datetime.datetime`` object in any time zone. If it is a ``datetime.datetime`` object then ``max_age`` will be calculated. """ - value = force_str(value) self.cookies[key] = value if expires is not None: if isinstance(expires, datetime.datetime): diff --git a/django/template/base.py b/django/template/base.py index ce3cc2c7c09..f6259ec7cfc 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -56,7 +56,7 @@ import re from django.template.context import ( # NOQA: imported for backwards compatibility BaseContext, Context, ContextPopException, RequestContext, ) -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.formats import localize from django.utils.html import conditional_escape, escape from django.utils.inspect import getargspec @@ -971,8 +971,7 @@ class TextNode(Node): self.s = s def __repr__(self): - rep = "<%s: %r>" % (self.__class__.__name__, self.s[:25]) - return force_str(rep, 'ascii', errors='replace') + return "<%s: %r>" % (self.__class__.__name__, self.s[:25]) def render(self, context): return self.s diff --git a/django/test/client.py b/django/test/client.py index c8c6e96a7ff..20c968bb3f1 100644 --- a/django/test/client.py +++ b/django/test/client.py @@ -21,7 +21,7 @@ from django.test import signals from django.test.utils import ContextList from django.urls import resolve from django.utils import six -from django.utils.encoding import force_bytes, force_str, uri_to_iri +from django.utils.encoding import force_bytes, uri_to_iri from django.utils.functional import SimpleLazyObject, curry from django.utils.http import urlencode from django.utils.itercompat import is_iterable @@ -317,10 +317,10 @@ class RequestFactory: return force_bytes(data, encoding=charset) def _get_path(self, parsed): - path = force_str(parsed[2]) + path = parsed.path # If there are parameters, add them - if parsed[3]: - path += str(";") + force_str(parsed[3]) + if parsed.params: + path += ";" + parsed.params path = uri_to_iri(path).encode(UTF_8) # Replace the behavior where non-ASCII values in the WSGI environ are # arbitrarily decoded with ISO-8859-1. @@ -389,7 +389,7 @@ class RequestFactory: content_type='application/octet-stream', secure=False, **extra): """Constructs an arbitrary HTTP request.""" - parsed = urlparse(force_str(path)) + parsed = urlparse(str(path)) # path can be lazy data = force_bytes(data, settings.DEFAULT_CHARSET) r = { 'PATH_INFO': self._get_path(parsed), diff --git a/django/test/utils.py b/django/test/utils.py index 4fa379b4a7c..a587e1fa965 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -23,7 +23,6 @@ from django.template import Template from django.test.signals import setting_changed, template_rendered from django.urls import get_script_prefix, set_script_prefix from django.utils.decorators import available_attrs -from django.utils.encoding import force_str from django.utils.translation import deactivate try: @@ -317,7 +316,7 @@ def get_runner(settings, test_runner_class=None): test_module_name = '.'.join(test_path[:-1]) else: test_module_name = '.' - test_module = __import__(test_module_name, {}, {}, force_str(test_path[-1])) + test_module = __import__(test_module_name, {}, {}, test_path[-1]) test_runner = getattr(test_module, test_path[-1]) return test_runner diff --git a/django/urls/resolvers.py b/django/urls/resolvers.py index 36586feab03..6084684d737 100644 --- a/django/urls/resolvers.py +++ b/django/urls/resolvers.py @@ -15,7 +15,7 @@ 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_str, force_text +from django.utils.encoding import force_text from django.utils.functional import cached_property from django.utils.http import RFC3986_SUBDELIMS, urlquote from django.utils.regex_helper import normalize @@ -160,7 +160,7 @@ class RegexURLPattern(LocaleRegexProvider): self.name = name def __repr__(self): - return force_str('<%s %s %s>' % (self.__class__.__name__, self.name, self.regex.pattern)) + return '<%s %s %s>' % (self.__class__.__name__, self.name, self.regex.pattern) def check(self): warnings = self._check_pattern_name() diff --git a/django/utils/formats.py b/django/utils/formats.py index 894003b4fab..74af39eade3 100644 --- a/django/utils/formats.py +++ b/django/utils/formats.py @@ -5,7 +5,6 @@ from importlib import import_module from django.conf import settings from django.utils import dateformat, datetime_safe, numberformat -from django.utils.encoding import force_str from django.utils.functional import lazy from django.utils.safestring import mark_safe from django.utils.translation import ( @@ -111,7 +110,6 @@ def get_format(format_type, lang=None, use_l10n=None): If use_l10n is provided and is not None, that will force the value to be localized (or not), overriding the value of settings.USE_L10N. """ - format_type = force_str(format_type) use_l10n = use_l10n or (use_l10n is None and settings.USE_L10N) if use_l10n and lang is None: lang = get_language() @@ -229,14 +227,14 @@ def localize_input(value, default=None): return number_format(value) elif isinstance(value, datetime.datetime): value = datetime_safe.new_datetime(value) - format = force_str(default or get_format('DATETIME_INPUT_FORMATS')[0]) + format = default or get_format('DATETIME_INPUT_FORMATS')[0] return value.strftime(format) elif isinstance(value, datetime.date): value = datetime_safe.new_date(value) - format = force_str(default or get_format('DATE_INPUT_FORMATS')[0]) + format = default or get_format('DATE_INPUT_FORMATS')[0] return value.strftime(format) elif isinstance(value, datetime.time): - format = force_str(default or get_format('TIME_INPUT_FORMATS')[0]) + format = default or get_format('TIME_INPUT_FORMATS')[0] return value.strftime(format) return value diff --git a/django/utils/html.py b/django/utils/html.py index 1fb39bb9b66..63335d74b41 100644 --- a/django/utils/html.py +++ b/django/utils/html.py @@ -5,7 +5,7 @@ from urllib.parse import ( parse_qsl, quote, unquote, urlencode, urlsplit, urlunsplit, ) -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.functional import keep_lazy, keep_lazy_text from django.utils.http import RFC3986_GENDELIMS, RFC3986_SUBDELIMS from django.utils.safestring import SafeData, SafeText, mark_safe @@ -189,7 +189,7 @@ def strip_spaces_between_tags(value): def smart_urlquote(url): "Quotes a URL if it isn't already quoted." def unquote_quote(segment): - segment = unquote(force_str(segment)) + segment = unquote(segment) # Tilde is part of RFC3986 Unreserved Characters # http://tools.ietf.org/html/rfc3986#section-2.3 # See also http://bugs.python.org/issue16285 @@ -211,7 +211,7 @@ def smart_urlquote(url): if query: # Separately unquoting key/value, so as to not mix querystring separators # included in query values. See #22267. - query_parts = [(unquote(force_str(q[0])), unquote(force_str(q[1]))) + query_parts = [(unquote(q[0]), unquote(q[1])) for q in parse_qsl(query, keep_blank_values=True)] # urlencode will take care of quoting query = urlencode(query_parts) diff --git a/django/utils/tree.py b/django/utils/tree.py index 5c86e73da8c..7f27fc7aac1 100644 --- a/django/utils/tree.py +++ b/django/utils/tree.py @@ -5,7 +5,7 @@ ORM. import copy -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text class Node: @@ -45,10 +45,10 @@ class Node: def __str__(self): template = '(NOT (%s: %s))' if self.negated else '(%s: %s)' - return force_str(template % (self.connector, ', '.join(force_text(c) for c in self.children))) + return template % (self.connector, ', '.join(force_text(c) for c in self.children)) def __repr__(self): - return str("<%s: %s>") % (self.__class__.__name__, self) + return "<%s: %s>" % (self.__class__.__name__, self) def __deepcopy__(self, memodict): """ diff --git a/django/views/debug.py b/django/views/debug.py index 28e0fe6eb27..7094299e60c 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -10,7 +10,7 @@ from django.template.defaultfilters import force_escape, pprint from django.urls import Resolver404, resolve from django.utils import timezone from django.utils.datastructures import MultiValueDict -from django.utils.encoding import force_bytes, force_text +from django.utils.encoding import force_text from django.utils.module_loading import import_string from django.utils.translation import ugettext as _ @@ -505,7 +505,7 @@ def technical_404_response(request, exception): 'root_urlconf': settings.ROOT_URLCONF, 'request_path': error_url, 'urlpatterns': tried, - 'reason': force_bytes(exception, errors='replace'), + 'reason': str(exception), 'request': request, 'settings': get_safe_settings(), 'raising_view_name': caller, diff --git a/django/views/generic/dates.py b/django/views/generic/dates.py index 86a49f8bd37..c738be8986c 100644 --- a/django/views/generic/dates.py +++ b/django/views/generic/dates.py @@ -5,7 +5,7 @@ from django.core.exceptions import ImproperlyConfigured from django.db import models from django.http import Http404 from django.utils import timezone -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from django.utils.functional import cached_property from django.utils.translation import ugettext as _ from django.views.generic.base import View @@ -687,7 +687,7 @@ def _date_from_string(year, year_format, month='', month_format='', day='', day_ format = delim.join((year_format, month_format, day_format)) datestr = delim.join((year, month, day)) try: - return datetime.datetime.strptime(force_str(datestr), format).date() + return datetime.datetime.strptime(datestr, format).date() except ValueError: raise Http404(_("Invalid date string '%(datestr)s' given format '%(format)s'") % { 'datestr': datestr, diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index 868d04196f9..50e034e03e5 100644 --- a/tests/admin_scripts/tests.py +++ b/tests/admin_scripts/tests.py @@ -1397,7 +1397,7 @@ class ManageRunserverEmptyAllowedHosts(AdminScriptTestCase): class ManageTestserver(AdminScriptTestCase): from django.core.management.commands.testserver import Command as TestserverCommand - @mock.patch.object(TestserverCommand, 'handle') + @mock.patch.object(TestserverCommand, 'handle', return_value='') def test_testserver_handle_params(self, mock_handle): out = StringIO() call_command('testserver', 'blah.json', stdout=out) diff --git a/tests/admin_utils/tests.py b/tests/admin_utils/tests.py index 1c14615e714..09136ea72ad 100644 --- a/tests/admin_utils/tests.py +++ b/tests/admin_utils/tests.py @@ -217,13 +217,9 @@ class UtilsTests(SimpleTestCase): ("History", None) ) - self.assertEqual( - label_for_field("__unicode__", Article), - "article" - ) self.assertEqual( label_for_field("__str__", Article), - str("article") + "article" ) with self.assertRaises(AttributeError): diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 12d029ffcdb..00864be47a0 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -15,7 +15,6 @@ from django.core.management import call_command from django.core.management.base import CommandError from django.db import migrations from django.test import TestCase, mock, override_settings -from django.utils.encoding import force_str from django.utils.translation import ugettext_lazy as _ from .models import ( @@ -44,7 +43,7 @@ def mock_inputs(inputs): assert str('__proxy__') not in prompt response = '' for key, val in inputs.items(): - if force_str(key) in prompt.lower(): + if key in prompt.lower(): response = val break return response diff --git a/tests/contenttypes_tests/tests.py b/tests/contenttypes_tests/tests.py index 0ae2ddbb640..7fedcb7abde 100644 --- a/tests/contenttypes_tests/tests.py +++ b/tests/contenttypes_tests/tests.py @@ -15,7 +15,7 @@ from django.test import ( SimpleTestCase, TestCase, TransactionTestCase, mock, override_settings, ) from django.test.utils import captured_stdout, isolate_apps -from django.utils.encoding import force_str, force_text +from django.utils.encoding import force_text from .models import ( Article, Author, ModelWithNullFKToSite, Post, SchemeIncludedURL, @@ -144,7 +144,7 @@ class GenericForeignKeyTests(SimpleTestCase): class Model(models.Model): field = GenericForeignKey() expected = "contenttypes_tests.Model.field" - actual = force_str(Model.field) + actual = force_text(Model.field) self.assertEqual(expected, actual) def test_missing_content_type_field(self): diff --git a/tests/dbshell/test_postgresql_psycopg2.py b/tests/dbshell/test_postgresql_psycopg2.py index 755464b3bbe..f0848ac7b89 100644 --- a/tests/dbshell/test_postgresql_psycopg2.py +++ b/tests/dbshell/test_postgresql_psycopg2.py @@ -1,9 +1,7 @@ -import locale import os from django.db.backends.postgresql.client import DatabaseClient from django.test import SimpleTestCase, mock -from django.utils.encoding import force_bytes, force_str class PostgreSqlDbshellCommandTestCase(SimpleTestCase): @@ -13,13 +11,12 @@ class PostgreSqlDbshellCommandTestCase(SimpleTestCase): That function invokes the runshell command, while mocking subprocess.call. It returns a 2-tuple with: - The command line list - - The binary content of file pointed by environment PGPASSFILE, or - None. + - The content of the file pointed by environment PGPASSFILE, or None. """ def _mock_subprocess_call(*args): self.subprocess_args = list(*args) if 'PGPASSFILE' in os.environ: - with open(os.environ['PGPASSFILE'], 'rb') as f: + with open(os.environ['PGPASSFILE'], 'r') as f: self.pgpass = f.read().strip() # ignore line endings else: self.pgpass = None @@ -40,7 +37,7 @@ class PostgreSqlDbshellCommandTestCase(SimpleTestCase): 'port': '444', }), ( ['psql', '-U', 'someuser', '-h', 'somehost', '-p', '444', 'dbname'], - b'somehost:444:dbname:someuser:somepassword', + 'somehost:444:dbname:someuser:somepassword', ) ) @@ -67,7 +64,7 @@ class PostgreSqlDbshellCommandTestCase(SimpleTestCase): 'port': '444', }), ( ['psql', '-U', 'some:user', '-h', '::1', '-p', '444', 'dbname'], - b'\\:\\:1:444:dbname:some\\:user:some\\:password', + '\\:\\:1:444:dbname:some\\:user:some\\:password', ) ) @@ -81,30 +78,23 @@ class PostgreSqlDbshellCommandTestCase(SimpleTestCase): 'port': '444', }), ( ['psql', '-U', 'some\\user', '-h', 'somehost', '-p', '444', 'dbname'], - b'somehost:444:dbname:some\\\\user:some\\\\password', + 'somehost:444:dbname:some\\\\user:some\\\\password', ) ) def test_accent(self): - # The pgpass temporary file needs to be encoded using the system locale. - encoding = locale.getpreferredencoding() username = 'rôle' password = 'sésame' - username_str = force_str(username, encoding) - password_str = force_str(password, encoding) - pgpass_bytes = force_bytes( - 'somehost:444:dbname:%s:%s' % (username, password), - encoding=encoding, - ) + pgpass_string = 'somehost:444:dbname:%s:%s' % (username, password) self.assertEqual( self._run_it({ 'database': 'dbname', - 'user': username_str, - 'password': password_str, + 'user': username, + 'password': password, 'host': 'somehost', 'port': '444', }), ( - ['psql', '-U', username_str, '-h', 'somehost', '-p', '444', 'dbname'], - pgpass_bytes, + ['psql', '-U', username, '-h', 'somehost', '-p', '444', 'dbname'], + pgpass_string, ) ) diff --git a/tests/file_uploads/views.py b/tests/file_uploads/views.py index 789cc2a3652..3eca47fe358 100644 --- a/tests/file_uploads/views.py +++ b/tests/file_uploads/views.py @@ -4,7 +4,7 @@ import os from django.core.files.uploadedfile import UploadedFile from django.http import HttpResponse, HttpResponseServerError -from django.utils.encoding import force_bytes, force_str +from django.utils.encoding import force_bytes, force_text from .models import FileModel from .tests import UNICODE_FILENAME, UPLOAD_TO @@ -152,9 +152,7 @@ def file_upload_content_type_extra(request): """ params = {} for file_name, uploadedfile in request.FILES.items(): - params[file_name] = { - k: force_str(v) for k, v in uploadedfile.content_type_extra.items() - } + params[file_name] = {k: force_text(v) for k, v in uploadedfile.content_type_extra.items()} return HttpResponse(json.dumps(params)) diff --git a/tests/generic_views/test_list.py b/tests/generic_views/test_list.py index d5851d4ff80..429d46f50c9 100644 --- a/tests/generic_views/test_list.py +++ b/tests/generic_views/test_list.py @@ -2,7 +2,6 @@ import datetime from django.core.exceptions import ImproperlyConfigured from django.test import TestCase, override_settings -from django.utils.encoding import force_str from django.views.generic.base import View from .models import Artist, Author, Book, Page @@ -235,7 +234,7 @@ class ListViewTests(TestCase): self._make_authors(1) res = self.client.get('/list/authors/paginated/2/') self.assertEqual(res.status_code, 404) - self.assertEqual(force_str(res.context.get('reason')), "Invalid page (2): That page contains no results") + self.assertEqual(res.context.get('reason'), "Invalid page (2): That page contains no results") def _make_authors(self, n): Author.objects.all().delete() diff --git a/tests/handlers/tests.py b/tests/handlers/tests.py index d7cfaadf629..ffb8a1f1455 100644 --- a/tests/handlers/tests.py +++ b/tests/handlers/tests.py @@ -7,7 +7,6 @@ from django.db import close_old_connections, connection from django.test import ( RequestFactory, SimpleTestCase, TransactionTestCase, override_settings, ) -from django.utils.encoding import force_str try: from http import HTTPStatus @@ -65,10 +64,7 @@ class HandlerTests(SimpleTestCase): raw_cookie = 'want="café"'.encode('utf-8').decode('iso-8859-1') environ['HTTP_COOKIE'] = raw_cookie request = WSGIRequest(environ) - # If would be nicer if request.COOKIES returned unicode values. - # However the current cookie parser doesn't do this and fixing it is - # much more work than fixing #20557. Feel free to remove force_str()! - self.assertEqual(request.COOKIES['want'], force_str("café")) + self.assertEqual(request.COOKIES['want'], "café") def test_invalid_unicode_cookie(self): """ diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py index a4ea614175d..fe2ad1a216a 100644 --- a/tests/httpwrappers/tests.py +++ b/tests/httpwrappers/tests.py @@ -17,7 +17,6 @@ from django.http import ( ) from django.test import SimpleTestCase from django.utils._os import upath -from django.utils.encoding import force_str from django.utils.functional import lazystr @@ -294,13 +293,8 @@ class HttpResponseTests(unittest.TestCase): self.assertIsInstance(r['key'], str) self.assertIn(b'test', r.serialize_headers()) - # Latin-1 unicode or bytes values are also converted to native strings. + # Non-ASCII values are serialized to Latin-1. r['key'] = 'café' - self.assertEqual(r['key'], force_str('café', 'latin-1')) - self.assertIsInstance(r['key'], str) - r['key'] = 'café'.encode('latin-1') - self.assertEqual(r['key'], force_str('café', 'latin-1')) - self.assertIsInstance(r['key'], str) self.assertIn('café'.encode('latin-1'), r.serialize_headers()) # Other unicode values are MIME-encoded (there's no way to pass them as bytes). @@ -759,7 +753,7 @@ class CookieTests(unittest.TestCase): # More characters the spec forbids. self.assertEqual(parse_cookie('a b,c<>@:/[]?{}=d " =e,f g'), {'a b,c<>@:/[]?{}': 'd " =e,f g'}) # Unicode characters. The spec only allows ASCII. - self.assertEqual(parse_cookie('saint=André Bessette'), {'saint': force_str('André Bessette')}) + self.assertEqual(parse_cookie('saint=André Bessette'), {'saint': 'André Bessette'}) # Browsers don't send extra whitespace or semicolons in Cookie headers, # but parse_cookie() should parse whitespace the same way # document.cookie parses whitespace. diff --git a/tests/middleware/tests.py b/tests/middleware/tests.py index 8749a9ee501..bd2ba898483 100644 --- a/tests/middleware/tests.py +++ b/tests/middleware/tests.py @@ -22,7 +22,6 @@ from django.test import ( RequestFactory, SimpleTestCase, ignore_warnings, override_settings, ) from django.utils.deprecation import RemovedInDjango21Warning -from django.utils.encoding import force_str int2byte = struct.Struct(">B").pack @@ -350,7 +349,7 @@ class CommonMiddlewareTest(SimpleTestCase): def test_non_ascii_query_string_does_not_crash(self): """Regression test for #15152""" request = self.rf.get('/slash') - request.META['QUERY_STRING'] = force_str('drink=café') + request.META['QUERY_STRING'] = 'drink=café' r = CommonMiddleware().process_request(request) self.assertEqual(r.status_code, 301) diff --git a/tests/migrations/test_writer.py b/tests/migrations/test_writer.py index a51842e02d3..46126bb760d 100644 --- a/tests/migrations/test_writer.py +++ b/tests/migrations/test_writer.py @@ -24,7 +24,6 @@ from django.test import SimpleTestCase, ignore_warnings, mock from django.utils import datetime_safe from django.utils._os import upath from django.utils.deconstruct import deconstructible -from django.utils.encoding import force_str from django.utils.functional import SimpleLazyObject from django.utils.timezone import FixedOffset, get_default_timezone, utc from django.utils.translation import ugettext_lazy as _ @@ -170,7 +169,7 @@ class WriterTests(SimpleTestCase): def safe_exec(self, string, value=None): d = {} try: - exec(force_str(string), globals(), d) + exec(string, globals(), d) except Exception as e: if value: self.fail("Could not exec %r (from value %r): %s" % (string.strip(), value, e)) diff --git a/tests/or_lookups/tests.py b/tests/or_lookups/tests.py index dd93ed7efc7..fd4cc3369b9 100644 --- a/tests/or_lookups/tests.py +++ b/tests/or_lookups/tests.py @@ -3,7 +3,6 @@ from operator import attrgetter from django.db.models import Q from django.test import TestCase -from django.utils.encoding import force_str from .models import Article @@ -124,9 +123,9 @@ class OrLookupsTests(TestCase): def test_q_repr(self): or_expr = Q(baz=Article(headline="Foö")) - self.assertEqual(repr(or_expr), force_str("))>")) + self.assertEqual(repr(or_expr), "))>") negated_or = ~Q(baz=Article(headline="Foö")) - self.assertEqual(repr(negated_or), force_str(")))>")) + self.assertEqual(repr(negated_or), ")))>") def test_q_negated(self): # Q objects can be negated diff --git a/tests/requests/tests.py b/tests/requests/tests.py index 54fe797728b..0dcaebbca52 100644 --- a/tests/requests/tests.py +++ b/tests/requests/tests.py @@ -14,7 +14,6 @@ from django.http.request import split_domain_port from django.test import RequestFactory, SimpleTestCase, override_settings from django.test.client import FakePayload from django.test.utils import freeze_time, str_prefix -from django.utils.encoding import force_str from django.utils.http import cookie_date, urlencode from django.utils.timezone import utc @@ -270,7 +269,7 @@ class RequestsTests(SimpleTestCase): response = HttpResponse() cookie_value = '清風' response.set_cookie('test', cookie_value) - self.assertEqual(force_str(cookie_value), response.cookies['test'].value) + self.assertEqual(cookie_value, response.cookies['test'].value) def test_limited_stream(self): # Read all of a limited stream diff --git a/tests/signing/tests.py b/tests/signing/tests.py index bc838d015f1..a55457efdd5 100644 --- a/tests/signing/tests.py +++ b/tests/signing/tests.py @@ -3,7 +3,6 @@ import datetime from django.core import signing from django.test import SimpleTestCase from django.test.utils import freeze_time -from django.utils.encoding import force_str class TestSigner(SimpleTestCase): @@ -47,7 +46,7 @@ class TestSigner(SimpleTestCase): for example in examples: signed = signer.sign(example) self.assertIsInstance(signed, str) - self.assertNotEqual(force_str(example), signed) + self.assertNotEqual(example, signed) self.assertEqual(example, signer.unsign(signed)) def test_unsign_detects_tampering(self):