From d1bab24e0144d14513a1411503c95ececb425188 Mon Sep 17 00:00:00 2001 From: Vytis Banaitis Date: Fri, 20 Jan 2017 23:04:05 +0200 Subject: [PATCH] Refs #23919, #27778 -- Removed obsolete mentions of unicode. --- django/contrib/admin/utils.py | 5 +- django/contrib/auth/management/__init__.py | 6 +-- django/contrib/gis/feeds.py | 4 +- .../gis/management/commands/ogrinspect.py | 2 +- django/contrib/gis/utils/ogrinspect.py | 2 +- django/contrib/messages/storage/base.py | 2 +- django/core/handlers/wsgi.py | 2 +- django/core/mail/message.py | 8 ++-- django/core/signing.py | 4 +- django/core/validators.py | 2 +- django/db/backends/oracle/base.py | 2 +- django/db/models/fields/__init__.py | 2 +- django/db/models/fields/files.py | 2 +- django/forms/fields.py | 4 +- django/forms/widgets.py | 4 +- django/http/multipartparser.py | 2 +- django/http/request.py | 2 +- django/template/base.py | 12 +++-- django/template/defaultfilters.py | 7 ++- django/test/utils.py | 7 --- django/utils/dateformat.py | 4 +- django/utils/encoding.py | 12 ++--- django/utils/feedgenerator.py | 47 +++++++++--------- django/utils/safestring.py | 16 +++---- django/utils/text.py | 2 +- django/utils/translation/template.py | 3 +- django/utils/translation/trans_real.py | 2 +- django/views/debug.py | 4 +- docs/howto/custom-management-commands.txt | 2 +- docs/howto/custom-template-tags.txt | 12 ++--- docs/ref/contrib/gis/geos.txt | 12 ++--- docs/ref/contrib/syndication.txt | 12 ++--- docs/ref/files/uploads.txt | 2 +- docs/ref/forms/api.txt | 8 ++-- docs/ref/forms/fields.txt | 26 +++++----- docs/ref/models/querysets.txt | 22 ++++----- docs/ref/request-response.txt | 5 +- docs/ref/templates/builtins.txt | 3 +- docs/ref/unicode.txt | 48 +++++++++---------- docs/ref/utils.txt | 27 +++++------ docs/ref/views.txt | 2 +- docs/topics/db/models.txt | 2 +- docs/topics/i18n/timezones.txt | 5 -- docs/topics/i18n/translation.txt | 21 ++++---- docs/topics/migrations.txt | 2 +- tests/backends/tests.py | 4 +- tests/datatypes/tests.py | 5 +- .../widget_tests/test_clearablefileinput.py | 2 +- .../widget_tests/test_timeinput.py | 4 +- tests/httpwrappers/tests.py | 6 +-- tests/m2m_and_m2o/models.py | 4 +- tests/m2m_and_m2o/tests.py | 8 ++-- tests/many_to_many/models.py | 2 +- tests/many_to_one/tests.py | 5 +- tests/model_regress/models.py | 2 +- tests/model_regress/tests.py | 8 ++-- tests/queries/tests.py | 3 -- tests/signing/tests.py | 2 +- .../syntax_tests/test_filter_syntax.py | 3 +- tests/template_tests/test_loaders.py | 2 +- tests/template_tests/test_unicode.py | 6 +-- tests/template_tests/utils.py | 2 +- tests/test_client_regress/tests.py | 2 +- 63 files changed, 201 insertions(+), 251 deletions(-) diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py index b890d9e3af..3e506a4b0e 100644 --- a/django/contrib/admin/utils.py +++ b/django/contrib/admin/utils.py @@ -283,10 +283,7 @@ def lookup_field(name, obj, model_admin=None): if callable(name): attr = name value = attr(obj) - elif (model_admin is not None and - hasattr(model_admin, name) and - not name == '__str__' and - not name == '__unicode__'): + elif model_admin is not None and hasattr(model_admin, name) and name != '__str__': attr = getattr(model_admin, name) value = attr(obj) else: diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py index 0d3fca03eb..1c2ed220c9 100644 --- a/django/contrib/auth/management/__init__.py +++ b/django/contrib/auth/management/__init__.py @@ -84,10 +84,8 @@ def create_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_ def get_system_username(): """ - Try to determine the current system user's username. - - :returns: The username as a unicode string, or an empty string if the - username could not be determined. + Return the current system user's username, or an empty string if the + username could not be determined. """ try: result = getpass.getuser() diff --git a/django/contrib/gis/feeds.py b/django/contrib/gis/feeds.py index b98e59653a..0355171aa8 100644 --- a/django/contrib/gis/feeds.py +++ b/django/contrib/gis/feeds.py @@ -11,8 +11,8 @@ class GeoFeedMixin: def georss_coords(self, coords): """ In GeoRSS coordinate pairs are ordered by lat/lon and separated by - a single white space. Given a tuple of coordinates, this will return - a unicode GeoRSS representation. + a single white space. Given a tuple of coordinates, return a string + GeoRSS representation. """ return ' '.join('%f %f' % (coord[1], coord[0]) for coord in coords) diff --git a/django/contrib/gis/management/commands/ogrinspect.py b/django/contrib/gis/management/commands/ogrinspect.py index aa5e22ec7c..3763749cef 100644 --- a/django/contrib/gis/management/commands/ogrinspect.py +++ b/django/contrib/gis/management/commands/ogrinspect.py @@ -74,7 +74,7 @@ class Command(BaseCommand): ) parser.add_argument( '--name-field', dest='name_field', - help='Specifies a field name to return for the `__unicode__`/`__str__` function.', + help='Specifies a field name to return for the __str__() method.', ) parser.add_argument( '--no-imports', action='store_false', dest='imports', default=True, diff --git a/django/contrib/gis/utils/ogrinspect.py b/django/contrib/gis/utils/ogrinspect.py index 52e0e655e4..5ffd46871b 100644 --- a/django/contrib/gis/utils/ogrinspect.py +++ b/django/contrib/gis/utils/ogrinspect.py @@ -92,7 +92,7 @@ def ogrinspect(*args, **kwargs): `multi_geom` => Boolean (default: False) - specify as multigeometry. `name_field` => String - specifies a field name to return for the - `__unicode__`/`__str__` function (which will be generated if specified). + __str__() method (which will be generated if specified). `imports` => Boolean (default: True) - set to False to omit the `from django.contrib.gis.db import models` code from the diff --git a/django/contrib/messages/storage/base.py b/django/contrib/messages/storage/base.py index 2e67c84f4a..3dea49df19 100644 --- a/django/contrib/messages/storage/base.py +++ b/django/contrib/messages/storage/base.py @@ -20,7 +20,7 @@ class Message: def _prepare(self): """ Prepares the message for serialization by forcing the ``message`` - and ``extra_tags`` to unicode in case they are lazy translations. + and ``extra_tags`` to str in case they are lazy translations. Known "safe" types (None, int, etc.) are not converted (see Django's ``force_text`` implementation for details). diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py index 2b3c355b9d..3c4a03774e 100644 --- a/django/core/handlers/wsgi.py +++ b/django/core/handlers/wsgi.py @@ -164,7 +164,7 @@ class WSGIHandler(base.BaseHandler): def get_path_info(environ): """ - Returns the HTTP request's PATH_INFO as a unicode string. + Return the HTTP request's PATH_INFO as a string. """ path_info = get_bytes_from_wsgi(environ, 'PATH_INFO', '/') diff --git a/django/core/mail/message.py b/django/core/mail/message.py index ae2e017b6e..7fab676474 100644 --- a/django/core/mail/message.py +++ b/django/core/mail/message.py @@ -207,8 +207,8 @@ class EmailMessage: Initialize a single email message (which can be sent to multiple recipients). - All strings used to create the message can be unicode strings - (or UTF-8 bytestrings). The SafeMIMEText class will handle any + All string arguments used to create the message can be strings + or UTF-8 bytestrings. The SafeMIMEText class will handle any necessary encoding conversions. """ if to: @@ -425,8 +425,8 @@ class EmailMultiAlternatives(EmailMessage): Initialize a single email message (which can be sent to multiple recipients). - All strings used to create the message can be unicode strings (or UTF-8 - bytestrings). The SafeMIMEText class will handle any necessary encoding + All string arguments used to create the message can be strings or UTF-8 + bytestrings. The SafeMIMEText class will handle any necessary encoding conversions. """ super().__init__( diff --git a/django/core/signing.py b/django/core/signing.py index b6a9a974c4..acf4959fc0 100644 --- a/django/core/signing.py +++ b/django/core/signing.py @@ -133,8 +133,8 @@ def loads(s, key=None, salt='django.core.signing', serializer=JSONSerializer, ma The serializer is expected to accept a bytestring. """ - # TimestampSigner.unsign always returns unicode but base64 and zlib - # compression operate on bytes. + # TimestampSigner.unsign() returns str but base64 and zlib compression + # operate on bytes. base64d = force_bytes(TimestampSigner(key, salt=salt).unsign(s, max_age=max_age)) decompress = False if base64d[:1] == b'.': diff --git a/django/core/validators.py b/django/core/validators.py index 0b90b4345c..732bcae486 100644 --- a/django/core/validators.py +++ b/django/core/validators.py @@ -71,7 +71,7 @@ class RegexValidator: @deconstructible class URLValidator(RegexValidator): - ul = '\u00a1-\uffff' # unicode letters range (must be a unicode string, not a raw string) + ul = '\u00a1-\uffff' # unicode letters range (must not be a raw string) # IP patterns ipv4_re = r'(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}' diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py index d19f189358..696c61d542 100644 --- a/django/db/backends/oracle/base.py +++ b/django/db/backends/oracle/base.py @@ -526,7 +526,7 @@ class CursorIterator: def _rowfactory(row, cursor): # Cast numeric values as the appropriate Python type based upon the - # cursor description, and convert strings to unicode. + # cursor description. casted = [] for value, desc in zip(row, cursor.description): if value is not None and desc[1] is Database.NUMBER: diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index bcaf0597a7..809a14277e 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -366,7 +366,7 @@ class Field(RegisterLookupMixin): Note that the positional or keyword arguments must contain values of the following types (including inner values of collection types): - * None, bool, str, unicode, int, long, float, complex, set, frozenset, list, tuple, dict + * None, bool, str, int, float, complex, set, frozenset, list, tuple, dict * UUID * datetime.datetime (naive), datetime.date * top-level classes, top-level functions - will be referenced by their full import path diff --git a/django/db/models/fields/files.py b/django/db/models/fields/files.py index 60ac33ff63..0e9ec19e70 100644 --- a/django/db/models/fields/files.py +++ b/django/db/models/fields/files.py @@ -314,7 +314,7 @@ class FileField(Field): # needed because we need to consume values that are also sane for a # regular (non Model-) Form to find in its cleaned_data dictionary. if data is not None: - # This value will be converted to unicode and stored in the + # This value will be converted to str and stored in the # database, so leaving False as-is is not acceptable. if not data: data = '' diff --git a/django/forms/fields.py b/django/forms/fields.py index e0c4edad52..2994ece1ce 100644 --- a/django/forms/fields.py +++ b/django/forms/fields.py @@ -229,7 +229,7 @@ class CharField(Field): self.validators.append(validators.MaxLengthValidator(int(max_length))) def to_python(self, value): - "Returns a Unicode object." + "Returns a string." if value in self.empty_values: return self.empty_value value = force_text(value) @@ -799,7 +799,7 @@ class ChoiceField(Field): choices = property(_get_choices, _set_choices) def to_python(self, value): - "Returns a Unicode object." + "Return a string." if value in self.empty_values: return '' return force_text(value) diff --git a/django/forms/widgets.py b/django/forms/widgets.py index 4317a0fc39..eef90a3bd4 100644 --- a/django/forms/widgets.py +++ b/django/forms/widgets.py @@ -200,9 +200,7 @@ class Widget(metaclass=MediaDefiningClass): return context def render(self, name, value, attrs=None, renderer=None): - """ - Returns this Widget rendered as HTML, as a Unicode string. - """ + """Render the widget as an HTML string.""" context = self.get_context(name, value, attrs) return self._render(self.template_name, context, renderer) diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py index 5f08924df2..543fc4a552 100644 --- a/django/http/multipartparser.py +++ b/django/http/multipartparser.py @@ -651,7 +651,7 @@ def parse_header(line): """ Parse the header into a key-value. - Input (line): bytes, output: unicode for key/name, bytes for value which + Input (line): bytes, output: str for key/name, bytes for values which will be decoded later. """ plist = _parse_header_params(b';' + line) diff --git a/django/http/request.py b/django/http/request.py index c91a51b48d..797b0414b6 100644 --- a/django/http/request.py +++ b/django/http/request.py @@ -354,7 +354,7 @@ class QueryDict(MultiValueDict): will always return a mutable copy. Both keys and values set on this class are converted from the given encoding - (DEFAULT_CHARSET by default) to unicode. + (DEFAULT_CHARSET by default) to str. """ # These are both reset in __init__, but is specified here at the class diff --git a/django/template/base.py b/django/template/base.py index 0c796ceaf2..de1a21a2ac 100644 --- a/django/template/base.py +++ b/django/template/base.py @@ -153,8 +153,10 @@ class Template: try: template_string = force_text(template_string) except UnicodeDecodeError: - raise TemplateEncodingError("Templates can only be constructed " - "from unicode or UTF-8 strings.") + raise TemplateEncodingError( + "Templates can only be constructed from strings or UTF-8 " + "bytestrings." + ) # If Template is instantiated directly rather than from an Engine and # exactly one Django template engine is configured, use that engine. # This is required to preserve backwards-compatibility for direct use @@ -270,7 +272,7 @@ class Template: bottom = min(total, line + 1 + context_lines) # In some rare cases exc_value.args can be empty or an invalid - # unicode string. + # string. try: message = force_text(exception.args[0]) except (IndexError, UnicodeDecodeError): @@ -980,8 +982,8 @@ class TextNode(Node): def render_value_in_context(value, context): """ Converts any value to a string to become part of a rendered template. This - means escaping, if required, and conversion to a unicode object. If value - is a string, it is expected to have already been translated. + means escaping, if required, and conversion to a string. If value is a + string, it's expected to already be translated. """ value = template_localtime(value, use_tz=context.use_tz) value = localize(value, use_l10n=context.use_l10n) diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py index c6472bce16..c5080e6024 100644 --- a/django/template/defaultfilters.py +++ b/django/template/defaultfilters.py @@ -33,9 +33,8 @@ register = Library() def stringfilter(func): """ - Decorator for filters which should only receive unicode objects. The object - passed as the first positional argument will be converted to a unicode - object. + Decorator for filters which should only receive strings. The object + passed as the first positional argument will be converted to a string. """ def _dec(*args, **kwargs): if args: @@ -471,7 +470,7 @@ def safe(value): def safeseq(value): """ A "safe" filter for sequences. Marks each element in the sequence, - individually, as safe, after converting them to unicode. Returns a list + individually, as safe, after converting them to strings. Returns a list with the results. """ return [mark_safe(force_text(obj)) for obj in value] diff --git a/django/test/utils.py b/django/test/utils.py index 43ce455762..5c374c2292 100644 --- a/django/test/utils.py +++ b/django/test/utils.py @@ -594,16 +594,9 @@ def strip_quotes(want, got): s = s.strip() return len(s) >= 2 and s[0] == s[-1] and s[0] in ('"', "'") - def is_quoted_unicode(s): - s = s.strip() - return len(s) >= 3 and s[0] == 'u' and s[1] == s[-1] and s[1] in ('"', "'") - if is_quoted_string(want) and is_quoted_string(got): want = want.strip()[1:-1] got = got.strip()[1:-1] - elif is_quoted_unicode(want) and is_quoted_unicode(got): - want = want.strip()[2:-1] - got = got.strip()[2:-1] return want, got diff --git a/django/utils/dateformat.py b/django/utils/dateformat.py index 67968e5d73..74c4b894d3 100644 --- a/django/utils/dateformat.py +++ b/django/utils/dateformat.py @@ -85,9 +85,7 @@ class TimeFormat(Formatter): try: if hasattr(self.data, 'tzinfo') and self.data.tzinfo: - # Have to use tzinfo.tzname and not datetime.tzname - # because datatime.tzname does not expect Unicode - return self.data.tzinfo.tzname(self.data) or "" + return self.data.tzname() or '' except NotImplementedError: pass return "" diff --git a/django/utils/encoding.py b/django/utils/encoding.py index d0fd2f19e7..e889d5f3a9 100644 --- a/django/utils/encoding.py +++ b/django/utils/encoding.py @@ -24,8 +24,8 @@ python_2_unicode_compatible = six.python_2_unicode_compatible def smart_text(s, encoding='utf-8', strings_only=False, errors='strict'): """ - Returns a text object representing 's' -- unicode on Python 2 and str on - Python 3. Treats bytestrings using the 'encoding' codec. + Return a string representing 's'. Treat bytestrings using the 'encoding' + codec. If strings_only is True, don't convert (some) non-string-like objects. """ @@ -78,9 +78,9 @@ def force_text(s, encoding='utf-8', strings_only=False, errors='strict'): else: # If we get to here, the caller has passed in an Exception # subclass populated with non-ASCII bytestring data without a - # working unicode method. Try to handle this without raising a + # working __str__() method. Try to handle this without raising a # further exception by individually forcing the exception args - # to unicode. + # to strings. s = ' '.join(force_text(arg, encoding, strings_only, errors) for arg in s) return s @@ -186,7 +186,7 @@ def uri_to_iri(uri): This is the algorithm from section 3.2 of RFC 3987. Takes an URI in ASCII bytes (e.g. '/I%20%E2%99%A5%20Django/') and returns - unicode containing the encoded result (e.g. '/I \xe2\x99\xa5 Django/'). + a string containing the encoded result (e.g. '/I \xe2\x99\xa5 Django/'). """ if uri is None: return uri @@ -231,7 +231,7 @@ def filepath_to_uri(path): """Convert a file system path to a URI portion that is suitable for inclusion in a URL. - We are assuming input is either UTF-8 or unicode already. + Assume the input is either UTF-8 bytes or a string. This method will encode certain chars that would normally be recognized as special chars for URIs. Note that this method does not encode the ' diff --git a/django/utils/feedgenerator.py b/django/utils/feedgenerator.py index 4772acb1c9..814d767671 100644 --- a/django/utils/feedgenerator.py +++ b/django/utils/feedgenerator.py @@ -84,25 +84,25 @@ class SyndicationFeed: def __init__(self, title, link, description, language=None, author_email=None, author_name=None, author_link=None, subtitle=None, categories=None, feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs): - def to_unicode(s): + def to_str(s): return force_text(s, strings_only=True) if categories: categories = [force_text(c) for c in categories] if ttl is not None: - # Force ints to unicode + # Force ints to str ttl = force_text(ttl) self.feed = { - 'title': to_unicode(title), + 'title': to_str(title), 'link': iri_to_uri(link), - 'description': to_unicode(description), - 'language': to_unicode(language), - 'author_email': to_unicode(author_email), - 'author_name': to_unicode(author_name), + 'description': to_str(description), + 'language': to_str(language), + 'author_email': to_str(author_email), + 'author_name': to_str(author_name), 'author_link': iri_to_uri(author_link), - 'subtitle': to_unicode(subtitle), + 'subtitle': to_str(subtitle), 'categories': categories or (), 'feed_url': iri_to_uri(feed_url), - 'feed_copyright': to_unicode(feed_copyright), + 'feed_copyright': to_str(feed_copyright), 'id': feed_guid or link, 'ttl': ttl, } @@ -114,33 +114,32 @@ class SyndicationFeed: unique_id=None, unique_id_is_permalink=None, categories=(), item_copyright=None, ttl=None, updateddate=None, enclosures=None, **kwargs): """ - Adds an item to the feed. All args are expected to be Python Unicode - objects except pubdate and updateddate, which are datetime.datetime - objects, and enclosures, which is an iterable of instances of the - Enclosure class. + Add an item to the feed. All args are expected to be strings except + pubdate and updateddate, which are datetime.datetime objects, and + enclosures, which is an iterable of instances of the Enclosure class. """ - def to_unicode(s): + def to_str(s): return force_text(s, strings_only=True) if categories: - categories = [to_unicode(c) for c in categories] + categories = [to_str(c) for c in categories] if ttl is not None: - # Force ints to unicode + # Force ints to str ttl = force_text(ttl) item = { - 'title': to_unicode(title), + 'title': to_str(title), 'link': iri_to_uri(link), - 'description': to_unicode(description), - 'author_email': to_unicode(author_email), - 'author_name': to_unicode(author_name), + 'description': to_str(description), + 'author_email': to_str(author_email), + 'author_name': to_str(author_name), 'author_link': iri_to_uri(author_link), 'pubdate': pubdate, 'updateddate': updateddate, - 'comments': to_unicode(comments), - 'unique_id': to_unicode(unique_id), + 'comments': to_str(comments), + 'unique_id': to_str(unique_id), 'unique_id_is_permalink': unique_id_is_permalink, 'enclosures': enclosures, 'categories': categories or (), - 'item_copyright': to_unicode(item_copyright), + 'item_copyright': to_str(item_copyright), 'ttl': ttl, } item.update(kwargs) @@ -212,7 +211,7 @@ class SyndicationFeed: class Enclosure: "Represents an RSS enclosure" def __init__(self, url, length, mime_type): - "All args are expected to be Python Unicode objects" + "All args are expected to be strings" self.length, self.mime_type = length, mime_type self.url = iri_to_uri(url) diff --git a/django/utils/safestring.py b/django/utils/safestring.py index 9b83a947d5..2aed4a3cb9 100644 --- a/django/utils/safestring.py +++ b/django/utils/safestring.py @@ -26,7 +26,7 @@ class SafeBytes(bytes, SafeData): def __add__(self, rhs): """ Concatenating a safe byte string with another safe byte string or safe - unicode string is safe. Otherwise, the result is no longer safe. + string is safe. Otherwise, the result is no longer safe. """ t = super().__add__(rhs) if isinstance(rhs, SafeText): @@ -37,9 +37,8 @@ class SafeBytes(bytes, SafeData): def _proxy_method(self, *args, **kwargs): """ - Wrap a call to a normal unicode method up so that we return safe - results. The method that is being wrapped is passed in the 'method' - argument. + Wrap a call to a normal bytes method up so that the result is safe. + The method that is being wrapped is passed in the 'method' argument. """ method = kwargs.pop('method') data = method(self, *args, **kwargs) @@ -58,8 +57,8 @@ class SafeText(str, SafeData): """ def __add__(self, rhs): """ - Concatenating a safe unicode string with another safe byte string or - safe unicode string is safe. Otherwise, the result is no longer safe. + Concatenating a safe string with another safe byte string or + safe string is safe. Otherwise, the result is no longer safe. """ t = super().__add__(rhs) if isinstance(rhs, SafeData): @@ -68,9 +67,8 @@ class SafeText(str, SafeData): def _proxy_method(self, *args, **kwargs): """ - Wrap a call to a normal unicode method up so that we return safe - results. The method that is being wrapped is passed in the 'method' - argument. + Wrap a call to a normal str method up so that the result is safe. + The method that is being wrapped is passed in the 'method' argument. """ method = kwargs.pop('method') data = method(self, *args, **kwargs) diff --git a/django/utils/text.py b/django/utils/text.py index 70f6b60777..0feeda7416 100644 --- a/django/utils/text.py +++ b/django/utils/text.py @@ -230,7 +230,7 @@ def get_valid_filename(s): """ Returns the given string converted to a string that can be used for a clean filename. Specifically, leading and trailing spaces are removed; other - spaces are converted to underscores; and anything that is not a unicode + spaces are converted to underscores; and anything that is not an alphanumeric, dash, underscore, or dot, is removed. >>> get_valid_filename("john's portrait in 2004.jpg") 'johns_portrait_in_2004.jpg' diff --git a/django/utils/translation/template.py b/django/utils/translation/template.py index 42ff84dc27..c471dd489f 100644 --- a/django/utils/translation/template.py +++ b/django/utils/translation/template.py @@ -54,8 +54,7 @@ def templatize(src, origin=None, charset='utf-8'): comment = [] lineno_comment_map = {} comment_lineno_cache = None - # Adding the u prefix allows gettext to recognize the Unicode string - # (#26093). + # Adding the u prefix allows gettext to recognize the string (#26093). raw_prefix = 'u' def join_tokens(tokens, trim=False): diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py index c8913feb71..efa4a916df 100644 --- a/django/utils/translation/trans_real.py +++ b/django/utils/translation/trans_real.py @@ -337,7 +337,7 @@ def pgettext(context, message): result = ugettext(msg_with_ctxt) if CONTEXT_SEPARATOR in result: # Translation not found - # force unicode, because lazy version expects unicode + # force str, because the lazy version expects str. result = force_text(message) return result diff --git a/django/views/debug.py b/django/views/debug.py index 7094299e60..4fe3f35a2e 100644 --- a/django/views/debug.py +++ b/django/views/debug.py @@ -263,7 +263,7 @@ class ExceptionReporter: frame_vars = [] for k, v in frame['vars']: v = pprint(v) - # The force_escape filter assume unicode, make sure that works + # The force_escape filter assumes str, make sure that works if isinstance(v, bytes): v = v.decode('utf-8', 'replace') # don't choke on non-utf-8 input # Trim large blobs of data @@ -360,7 +360,7 @@ class ExceptionReporter: return None, [], None, [] # If we just read the source from a file, or if the loader did not - # apply tokenize.detect_encoding to decode the source into a Unicode + # apply tokenize.detect_encoding to decode the source into a # string, then we should do that ourselves. if isinstance(source[0], bytes): encoding = 'ascii' diff --git a/docs/howto/custom-management-commands.txt b/docs/howto/custom-management-commands.txt index b5212e305c..d7cd14663e 100644 --- a/docs/howto/custom-management-commands.txt +++ b/docs/howto/custom-management-commands.txt @@ -305,7 +305,7 @@ the :meth:`~BaseCommand.handle` method must be implemented. The actual logic of the command. Subclasses must implement this method. - It may return a Unicode string which will be printed to ``stdout`` (wrapped + It may return a string which will be printed to ``stdout`` (wrapped by ``BEGIN;`` and ``COMMIT;`` if :attr:`output_transaction` is ``True``). .. method:: BaseCommand.check(app_configs=None, tags=None, display_num_errors=False) diff --git a/docs/howto/custom-template-tags.txt b/docs/howto/custom-template-tags.txt index 448576784f..9ce743549d 100644 --- a/docs/howto/custom-template-tags.txt +++ b/docs/howto/custom-template-tags.txt @@ -188,12 +188,11 @@ Filters and auto-escaping ------------------------- When writing a custom filter, give some thought to how the filter will interact -with Django's auto-escaping behavior. Note that three types of strings can be +with Django's auto-escaping behavior. Note that two types of strings can be passed around inside the template code: -* **Raw strings** are the native Python ``str`` or ``unicode`` types. On - output, they're escaped if auto-escaping is in effect and presented - unchanged, otherwise. +* **Raw strings** are the native Python strings. On output, they're escaped if + auto-escaping is in effect and presented unchanged, otherwise. * **Safe strings** are strings that have been marked safe from further escaping at output time. Any necessary escaping has already been done. @@ -229,9 +228,8 @@ Template filter code falls into one of two situations: The reason ``is_safe`` is necessary is because there are plenty of normal string operations that will turn a ``SafeData`` object back into - a normal ``str`` or ``unicode`` object and, rather than try to catch - them all, which would be very difficult, Django repairs the damage after - the filter has completed. + a normal ``str`` object and, rather than try to catch them all, which would + be very difficult, Django repairs the damage after the filter has completed. For example, suppose you have a filter that adds the string ``xx`` to the end of any input. Since this introduces no dangerous HTML characters diff --git a/docs/ref/contrib/gis/geos.txt b/docs/ref/contrib/gis/geos.txt index 6df0daf514..815d4268cb 100644 --- a/docs/ref/contrib/gis/geos.txt +++ b/docs/ref/contrib/gis/geos.txt @@ -197,14 +197,14 @@ given ``geo_input`` argument, and then assumes the proper geometry subclass The following input formats, along with their corresponding Python types, are accepted: -======================= ====================== +======================= ========== Format Input Type -======================= ====================== -WKT / EWKT ``str`` or ``unicode`` -HEX / HEXEWKB ``str`` or ``unicode`` +======================= ========== +WKT / EWKT ``str`` +HEX / HEXEWKB ``str`` WKB / EWKB ``buffer`` -GeoJSON ``str`` or ``unicode`` -======================= ====================== +GeoJSON ``str`` +======================= ========== .. classmethod:: GEOSGeometry.from_gml(gml_string) diff --git a/docs/ref/contrib/syndication.txt b/docs/ref/contrib/syndication.txt index 8c32cef191..d8e59edc85 100644 --- a/docs/ref/contrib/syndication.txt +++ b/docs/ref/contrib/syndication.txt @@ -114,7 +114,7 @@ into those elements. calling the methods ``item_title()`` and ``item_description()`` on the :class:`~django.contrib.syndication.views.Feed` class. They are passed a single parameter, ``item``, which is the object itself. These are - optional; by default, the unicode representation of the object is used for + optional; by default, the string representation of the object is used for both. If you want to do any special formatting for either the title or @@ -615,7 +615,7 @@ This example illustrates all possible attributes and methods for a # ITEM TITLE AND DESCRIPTION -- If title_template or # description_template are not defined, these are used instead. Both are - # optional, by default they will use the unicode representation of the + # optional, by default they will use the string representation of the # item. def item_title(self, item): @@ -940,8 +940,8 @@ They share this interface: Any extra keyword arguments you pass to ``__init__`` will be stored in ``self.feed`` for use with `custom feed generators`_. - All parameters should be Unicode objects, except ``categories``, which - should be a sequence of Unicode objects. Beware that some control characters + All parameters should be strings, except ``categories``, which should be a + sequence of strings. Beware that some control characters are `not allowed `_ in XML documents. If your content has some of them, you might encounter a :exc:`ValueError` when producing the feed. @@ -971,13 +971,13 @@ They share this interface: Extra keyword arguments will be stored for `custom feed generators`_. - All parameters, if given, should be Unicode objects, except: + All parameters, if given, should be strings, except: * ``pubdate`` should be a Python :class:`~datetime.datetime` object. * ``updateddate`` should be a Python :class:`~datetime.datetime` object. * ``enclosures`` should be a list of :class:`django.utils.feedgenerator.Enclosure` instances. - * ``categories`` should be a sequence of Unicode objects. + * ``categories`` should be a sequence of strings. :meth:`.SyndicationFeed.write` Outputs the feed in the given encoding to outfile, which is a file-like object. diff --git a/docs/ref/files/uploads.txt b/docs/ref/files/uploads.txt index 9bc508781f..4e843732a1 100644 --- a/docs/ref/files/uploads.txt +++ b/docs/ref/files/uploads.txt @@ -196,7 +196,7 @@ attributes: ``field_name`` is a string name of the file ```` field. - ``file_name`` is the unicode filename that was provided by the browser. + ``file_name`` is the filename provided by the browser. ``content_type`` is the MIME type provided by the browser -- E.g. ``'image/jpeg'``. diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt index e64e25d241..fda7472105 100644 --- a/docs/ref/forms/api.txt +++ b/docs/ref/forms/api.txt @@ -112,7 +112,7 @@ messages:: {'sender': ['Enter a valid email address.'], 'subject': ['This field is required.']} In this dictionary, the keys are the field names, and the values are lists of -Unicode strings representing the error messages. The error messages are stored +strings representing the error messages. The error messages are stored in lists because a field can have multiple error messages. You can access :attr:`~Form.errors` without having to call @@ -357,8 +357,8 @@ it, you can access the clean data via its ``cleaned_data`` attribute:: {'cc_myself': True, 'message': 'Hi there', 'sender': 'foo@example.com', 'subject': 'hello'} Note that any text-based field -- such as ``CharField`` or ``EmailField`` -- -always cleans the input into a Unicode string. We'll cover the encoding -implications later in this document. +always cleans the input into a string. We'll cover the encoding implications +later in this document. If your data does *not* validate, the ``cleaned_data`` dictionary contains only the valid fields:: @@ -490,7 +490,7 @@ Notice the following: Although ```` output is the default output style when you ``print`` a form, other output styles are available. Each style is available as a method on -a form object, and each rendering method returns a Unicode object. +a form object, and each rendering method returns a string. ``as_p()`` ---------- diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt index 2949ad0a9b..341d142c4b 100644 --- a/docs/ref/forms/fields.txt +++ b/docs/ref/forms/fields.txt @@ -88,9 +88,8 @@ To specify that a field is *not* required, pass ``required=False`` to the If a ``Field`` has ``required=False`` and you pass ``clean()`` an empty value, then ``clean()`` will return a *normalized* empty value rather than raising -``ValidationError``. For ``CharField``, this will be a Unicode empty string. -For other ``Field`` classes, it might be ``None``. (This varies from field to -field.) +``ValidationError``. For ``CharField``, this will be an empty string. For other +``Field`` classes, it might be ``None``. (This varies from field to field.) Widgets of required form fields have the ``required`` HTML attribute. Set the :attr:`Form.use_required_attribute` attribute to ``False`` to disable it. The @@ -371,7 +370,7 @@ For each field, we describe the default widget used if you don't specify * Default widget: :class:`TextInput` * Empty value: Whatever you've given as :attr:`empty_value`. - * Normalizes to: A Unicode object. + * Normalizes to: A string. * Validates ``max_length`` or ``min_length``, if they are provided. Otherwise, all inputs are valid. * Error message keys: ``required``, ``max_length``, ``min_length`` @@ -402,7 +401,7 @@ For each field, we describe the default widget used if you don't specify * Default widget: :class:`Select` * Empty value: ``''`` (an empty string) - * Normalizes to: A Unicode object. + * Normalizes to: A string. * Validates that the given value exists in the list of choices. * Error message keys: ``required``, ``invalid_choice`` @@ -585,7 +584,7 @@ For each field, we describe the default widget used if you don't specify * Default widget: :class:`EmailInput` * Empty value: ``''`` (an empty string) - * Normalizes to: A Unicode object. + * Normalizes to: A string. * Validates that the given value is a valid email address, using a moderately complex regular expression. * Error message keys: ``required``, ``invalid`` @@ -629,7 +628,7 @@ For each field, we describe the default widget used if you don't specify * Default widget: :class:`Select` * Empty value: ``None`` - * Normalizes to: A unicode object + * Normalizes to: A string. * Validates that the selected choice exists in the list of choices. * Error message keys: ``required``, ``invalid_choice`` @@ -747,8 +746,7 @@ For each field, we describe the default widget used if you don't specify * Default widget: :class:`TextInput` * Empty value: ``''`` (an empty string) - * Normalizes to: A Unicode object. IPv6 addresses are - normalized as described below. + * Normalizes to: A string. IPv6 addresses are normalized as described below. * Validates that the given value is a valid IP address. * Error message keys: ``required``, ``invalid`` @@ -780,7 +778,7 @@ For each field, we describe the default widget used if you don't specify * Default widget: :class:`SelectMultiple` * Empty value: ``[]`` (an empty list) - * Normalizes to: A list of Unicode objects. + * Normalizes to: A list of strings. * Validates that every value in the given list of values exists in the list of choices. * Error message keys: ``required``, ``invalid_choice``, ``invalid_list`` @@ -829,7 +827,7 @@ For each field, we describe the default widget used if you don't specify * Default widget: :class:`TextInput` * Empty value: ``''`` (an empty string) - * Normalizes to: A Unicode object. + * Normalizes to: A string. * Validates that the given value matches against a certain regular expression. * Error message keys: ``required``, ``invalid`` @@ -856,7 +854,7 @@ For each field, we describe the default widget used if you don't specify * Default widget: :class:`TextInput` * Empty value: ``''`` (an empty string) - * Normalizes to: A Unicode object. + * Normalizes to: A string. * Validates that the given value contains only letters, numbers, underscores, and hyphens. * Error messages: ``required``, ``invalid`` @@ -902,7 +900,7 @@ For each field, we describe the default widget used if you don't specify * Default widget: :class:`URLInput` * Empty value: ``''`` (an empty string) - * Normalizes to: A Unicode object. + * Normalizes to: A string. * Validates that the given value is a valid URL. * Error message keys: ``required``, ``invalid`` @@ -936,7 +934,7 @@ Slightly complex built-in ``Field`` classes * Default widget: :class:`TextInput` * Empty value: ``''`` (an empty string) - * Normalizes to: A Unicode object. + * Normalizes to: A string. * Validates the given value against each of the fields specified as an argument to the ``ComboField``. * Error message keys: ``required``, ``invalid`` diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 2893c91b8e..844c9e1d11 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -2391,10 +2391,9 @@ Note the first query will match ``'Beatles Blog'``, ``'beatles blog'``, .. admonition:: SQLite users - When using the SQLite backend and Unicode (non-ASCII) strings, bear in - mind the :ref:`database note ` about string - comparisons. SQLite does not do case-insensitive matching for Unicode - strings. + When using the SQLite backend and non-ASCII strings, bear in mind the + :ref:`database note ` about string comparisons. + SQLite does not do case-insensitive matching for non-ASCII strings. .. fieldlookup:: contains @@ -2438,9 +2437,8 @@ SQL equivalent:: .. admonition:: SQLite users - When using the SQLite backend and Unicode (non-ASCII) strings, bear in - mind the :ref:`database note ` about string - comparisons. + When using the SQLite backend and non-ASCII strings, bear in mind the + :ref:`database note ` about string comparisons. .. fieldlookup:: in @@ -2572,9 +2570,8 @@ SQL equivalent:: .. admonition:: SQLite users - When using the SQLite backend and Unicode (non-ASCII) strings, bear in - mind the :ref:`database note ` about string - comparisons. + When using the SQLite backend and non-ASCII strings, bear in mind the + :ref:`database note ` about string comparisons. .. fieldlookup:: endswith @@ -2614,9 +2611,8 @@ SQL equivalent:: .. admonition:: SQLite users - When using the SQLite backend and Unicode (non-ASCII) strings, bear in - mind the :ref:`database note ` about string - comparisons. + When using the SQLite backend and non-ASCII strings, bear in mind the + :ref:`database note ` about string comparisons. .. fieldlookup:: range diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt index a6f80feb2e..2d564d1954 100644 --- a/docs/ref/request-response.txt +++ b/docs/ref/request-response.txt @@ -416,7 +416,7 @@ a subclass of dictionary. Exceptions are outlined here: ``mutable=True`` to its ``__init__()``. Strings for setting both keys and values will be converted from ``encoding`` - to unicode. If encoding is not set, it defaults to :setting:`DEFAULT_CHARSET`. + to ``str``. If encoding is not set, it defaults to :setting:`DEFAULT_CHARSET`. .. classmethod:: QueryDict.fromkeys(iterable, value='', mutable=False, encoding=None) @@ -654,8 +654,7 @@ Attributes .. attribute:: HttpResponse.content - A bytestring representing the content, encoded from a Unicode - object if necessary. + A bytestring representing the content, encoded from a string if necessary. .. attribute:: HttpResponse.charset diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index b4fe7f9665..5b453a0cba 100644 --- a/docs/ref/templates/builtins.txt +++ b/docs/ref/templates/builtins.txt @@ -1934,8 +1934,7 @@ If ``value`` is ``Totally LOVING this Album!``, the output will be ------------- Returns the value turned into a list. For a string, it's a list of characters. -For an integer, the argument is cast into an unicode string before creating a -list. +For an integer, the argument is cast to a string before creating a list. For example:: diff --git a/docs/ref/unicode.txt b/docs/ref/unicode.txt index d493ce56ad..eb71b63682 100644 --- a/docs/ref/unicode.txt +++ b/docs/ref/unicode.txt @@ -3,8 +3,8 @@ Unicode data ============ Django natively supports Unicode data everywhere. Providing your database can -somehow store the data, you can safely pass around Unicode strings to -templates, models and the database. +somehow store the data, you can safely pass around strings to templates, +models, and the database. This document tells you what you need to know if you're writing applications that use data or templates that are encoded in something other than ASCII. @@ -35,11 +35,10 @@ able to store certain characters in the database, and information will be lost. .. _section 2: https://docs.oracle.com/database/121/NLSPG/ch2charset.htm#NLSPG002 .. _section 11: https://docs.oracle.com/database/121/NLSPG/ch11charsetmig.htm#NLSPG011 -All of Django's database backends automatically convert Unicode strings into +All of Django's database backends automatically convert strings into the appropriate encoding for talking to the database. They also automatically -convert strings retrieved from the database into Python Unicode strings. You -don't even need to tell Django what encoding your database uses: that is -handled transparently. +convert strings retrieved from the database into strings. You don't even need +to tell Django what encoding your database uses: that is handled transparently. For more, see the section "The database API" below. @@ -48,7 +47,7 @@ General string handling Whenever you use strings with Django -- e.g., in database lookups, template rendering or anywhere else -- you have two choices for encoding those strings. -You can use normal Unicode strings or bytestrings (starting with a 'b'). +You can use normal strings or bytestrings (starting with a 'b'). .. warning:: @@ -74,13 +73,13 @@ using your application -- and if that person chooses a different setting, your code must still continue to work. Ergo, it cannot rely on that setting. In most cases when Django is dealing with strings, it will convert them to -Unicode strings before doing anything else. So, as a general rule, if you pass -in a bytestring, be prepared to receive a Unicode string back in the result. +strings before doing anything else. So, as a general rule, if you pass +in a bytestring, be prepared to receive a string back in the result. Translated strings ------------------ -Aside from Unicode strings and bytestrings, there's a third type of string-like +Aside from strings and bytestrings, there's a third type of string-like object you may encounter when using Django. The framework's internationalization features introduce the concept of a "lazy translation" -- a string that has been marked as translated but whose actual translation result @@ -93,7 +92,7 @@ Normally, you won't have to worry about lazy translations. Just be aware that if you examine an object and it claims to be a ``django.utils.functional.__proxy__`` object, it is a lazy translation. Calling ``str()`` with the lazy translation as the argument will generate a -Unicode string in the current locale. +string in the current locale. For more details about lazy translation objects, refer to the :doc:`internationalization ` documentation. @@ -102,17 +101,17 @@ Useful utility functions ------------------------ Because some string operations come up again and again, Django ships with a few -useful functions that should make working with Unicode and bytestring objects +useful functions that should make working with string and bytestring objects a bit easier. Conversion functions ~~~~~~~~~~~~~~~~~~~~ The ``django.utils.encoding`` module contains a few functions that are handy -for converting back and forth between Unicode and bytestrings. +for converting back and forth between strings and bytestrings. * ``smart_text(s, encoding='utf-8', strings_only=False, errors='strict')`` - converts its input to a Unicode string. The ``encoding`` parameter + converts its input to a string. The ``encoding`` parameter specifies the input encoding. (For example, Django uses this internally when processing form input data, which might not be UTF-8 encoded.) The ``strings_only`` parameter, if set to True, will result in Python @@ -126,7 +125,7 @@ for converting back and forth between Unicode and bytestrings. cases. The difference is when the first argument is a :ref:`lazy translation ` instance. While ``smart_text()`` preserves lazy translations, ``force_text()`` forces those objects to a - Unicode string (causing the translation to occur). Normally, you'll want + string (causing the translation to occur). Normally, you'll want to use ``smart_text()``. However, ``force_text()`` is useful in template tags and filters that absolutely *must* have a string to work with, not just something that can be converted to a string. @@ -139,8 +138,8 @@ for converting back and forth between Unicode and bytestrings. but the difference is needed in a few places within Django's internals. Normally, you'll only need to use ``force_text()``. Call it as early as -possible on any input data that might be either Unicode or a bytestring, and -from then on, you can treat the result as always being Unicode. +possible on any input data that might be either a string or a bytestring, and +from then on, you can treat the result as always being a string. .. _uri-and-iri-handling: @@ -225,13 +224,13 @@ double-quoting problems. Models ====== -Because all strings are returned from the database as Unicode strings, model +Because all strings are returned from the database as ``str`` objects, model fields that are character based (CharField, TextField, URLField, etc.) will contain Unicode values when Django retrieves data from the database. This is *always* the case, even if the data could fit into an ASCII bytestring. You can pass in bytestrings when creating a model or populating a field, and -Django will convert it to Unicode when it needs to. +Django will convert it to strings when it needs to. Taking care in ``get_absolute_url()`` ------------------------------------- @@ -263,7 +262,7 @@ non-ASCII characters would have been removed in quoting in the first line.) The database API ================ -You can pass either Unicode strings or UTF-8 bytestrings as arguments to +You can pass either strings or UTF-8 bytestrings as arguments to ``filter()`` methods and the like in the database API. The following two querysets are identical:: @@ -273,11 +272,12 @@ querysets are identical:: Templates ========= -You can use either Unicode or bytestrings when creating templates manually:: +You can use either strings or UTF-8 bytestrings when creating templates +manually:: from django.template import Template t1 = Template(b'This is a bytestring template.') - t2 = Template('This is a Unicode template.') + t2 = Template('This is a string template.') But the common case is to read templates from the filesystem, and this creates a slight complication: not all filesystems store their data encoded as UTF-8. @@ -294,13 +294,13 @@ Template tags and filters A couple of tips to remember when writing your own template tags and filters: -* Always return Unicode strings from a template tag's ``render()`` method +* Always return strings from a template tag's ``render()`` method and from template filters. * Use ``force_text()`` in preference to ``smart_text()`` in these places. Tag rendering and filter calls occur as the template is being rendered, so there is no advantage to postponing the conversion of lazy - translation objects into strings. It's easier to work solely with Unicode + translation objects into strings. It's easier to work solely with strings at that point. .. _unicode-files: diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt index 056f228bdf..cc6cf74478 100644 --- a/docs/ref/utils.txt +++ b/docs/ref/utils.txt @@ -276,13 +276,13 @@ The functions defined in this module share the following properties: This is an algorithm from section 3.2 of :rfc:`3987#section-3.2`. - Takes a URI in ASCII bytes and returns a unicode string containing the - encoded result. + Takes a URI in ASCII bytes and returns a string containing the encoded + result. .. function:: filepath_to_uri(path) Convert a file system path to a URI portion that is suitable for inclusion - in a URL. The path is assumed to be either UTF-8 or unicode. + in a URL. The path is assumed to be either UTF-8 bytes or string. This method will encode certain characters that would normally be recognized as special characters for URIs. Note that this method does not @@ -346,13 +346,13 @@ https://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004 Any extra keyword arguments you pass to ``__init__`` will be stored in ``self.feed``. - All parameters should be Unicode objects, except ``categories``, which - should be a sequence of Unicode objects. + All parameters should be strings, except ``categories``, which should + be a sequence of strings. .. method:: add_item(title, link, description, author_email=None, author_name=None, author_link=None, pubdate=None, comments=None, unique_id=None, categories=(), item_copyright=None, ttl=None, updateddate=None, enclosures=None, **kwargs) - Adds an item to the feed. All args are expected to be Python ``unicode`` - objects except ``pubdate`` and ``updateddate``, which are ``datetime.datetime`` + Adds an item to the feed. All args are expected to be strings except + ``pubdate`` and ``updateddate``, which are ``datetime.datetime`` objects, and ``enclosures``, which is a list of ``Enclosure`` instances. .. method:: num_items() @@ -802,7 +802,7 @@ appropriate entities. .. function:: mark_safe(s) Explicitly mark a string as safe for (HTML) output purposes. The returned - object can be used everywhere a string or unicode object is appropriate. + object can be used everywhere a string is appropriate. Can be called multiple times on a single string. @@ -1030,16 +1030,15 @@ For a complete discussion on the usage of the following see the .. function:: gettext(message) - Translates ``message`` and returns it in a UTF-8 bytestring + Translates ``message`` and returns it in a UTF-8 bytestring. .. function:: ugettext(message) - Translates ``message`` and returns it in a unicode string + Translates ``message`` and returns it as a string. .. function:: pgettext(context, message) - Translates ``message`` given the ``context`` and returns - it in a unicode string. + Translates ``message`` given the ``context`` and returns it as a string. For more information, see :ref:`contextual-markers`. @@ -1067,12 +1066,12 @@ For a complete discussion on the usage of the following see the .. function:: ungettext(singular, plural, number) Translates ``singular`` and ``plural`` and returns the appropriate string - based on ``number`` in a unicode string. + based on ``number`` as a string. .. function:: npgettext(context, singular, plural, number) Translates ``singular`` and ``plural`` and returns the appropriate string - based on ``number`` and the ``context`` in a unicode string. + based on ``number`` and the ``context`` as a string. .. function:: ngettext_lazy(singular, plural, number) .. function:: ungettext_lazy(singular, plural, number) diff --git a/docs/ref/views.txt b/docs/ref/views.txt index 93303527bc..dd1897c915 100644 --- a/docs/ref/views.txt +++ b/docs/ref/views.txt @@ -121,7 +121,7 @@ default, call the view ``django.views.defaults.permission_denied``. This view loads and renders the template ``403.html`` in your root template directory, or if this file does not exist, instead serves the text "403 Forbidden", as per :rfc:`7231#section-6.5.3` (the HTTP 1.1 Specification). -The template context contains ``exception``, which is the unicode +The template context contains ``exception``, which is the string representation of the exception that triggered the view. ``django.views.defaults.permission_denied`` is triggered by a diff --git a/docs/topics/db/models.txt b/docs/topics/db/models.txt index 5f24a8e3f2..bd76103a4d 100644 --- a/docs/topics/db/models.txt +++ b/docs/topics/db/models.txt @@ -762,7 +762,7 @@ You can override most of these -- see `overriding predefined model methods`_, below -- but there are a couple that you'll almost always want to define: :meth:`~Model.__str__` - A Python "magic method" that returns a unicode "representation" of any + A Python "magic method" that returns a string representation of any object. This is what Python and Django will use whenever a model instance needs to be coerced and displayed as a plain string. Most notably, this happens when you display an object in an interactive diff --git a/docs/topics/i18n/timezones.txt b/docs/topics/i18n/timezones.txt index ecabefb421..e3fccf36cb 100644 --- a/docs/topics/i18n/timezones.txt +++ b/docs/topics/i18n/timezones.txt @@ -472,11 +472,6 @@ Setup of local time. This shields you from subtle and unreproducible bugs around Daylight Saving Time (DST) transitions. - In this regard, time zones are comparable to ``unicode`` in Python. At first - it's hard. You get encoding and decoding errors. Then you learn the rules. - And some problems disappear -- you never get mangled output again when your - application receives non-ASCII input. - When you enable time zone support, you'll encounter some errors because you're using naive datetimes where Django expects aware datetimes. Such errors show up when running tests and they're easy to fix. You'll quickly diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt index 46c77f1d0d..0aa16717d9 100644 --- a/docs/topics/i18n/translation.txt +++ b/docs/topics/i18n/translation.txt @@ -57,12 +57,9 @@ as a shorter alias, ``_``, to save typing. global namespace, as an alias for ``gettext()``. In Django, we have chosen not to follow this practice, for a couple of reasons: - 1. For international character set (Unicode) support, - :func:`~django.utils.translation.ugettext` is more useful than - ``gettext()``. Sometimes, you should be using - :func:`~django.utils.translation.ugettext_lazy` as the default - translation method for a particular file. Without ``_()`` in the - global namespace, the developer has to think about which is the + 1. Sometimes, you should use :func:`~django.utils.translation.ugettext_lazy` + as the default translation method for a particular file. Without ``_()`` + in the global namespace, the developer has to think about which is the most appropriate translation function. 2. The underscore character (``_``) is used to represent "the previous @@ -418,7 +415,7 @@ Working with lazy translation objects ------------------------------------- The result of a ``ugettext_lazy()`` call can be used wherever you would use a -unicode string (a :class:`str` object) in other Django code, but it may not +string (a :class:`str` object) in other Django code, but it may not work with arbitrary Python code. For example, the following won't work because the `requests `_ library doesn't handle ``ugettext_lazy`` objects:: @@ -434,14 +431,14 @@ strings before passing them to non-Django code:: If you try to use a ``ugettext_lazy()`` result where a bytestring (a :class:`bytes` object) is expected, things won't work as expected since a ``ugettext_lazy()`` object doesn't know how to convert itself to a bytestring. -You can't use a unicode string inside a bytestring, either, so this is -consistent with normal Python behavior. For example, putting a unicode proxy -into a unicode string is fine:: +You can't use a string inside a bytestring, either, so this is consistent with +normal Python behavior. For example, putting a string proxy into a string is +fine:: "Hello %s" % ugettext_lazy("people") -But you can't insert a unicode object into a bytestring and nor can you insert -a unicode proxy there:: +But you can't insert a string into a bytestring and nor can you insert +a string proxy there:: b"Hello %s" % ugettext_lazy("people") diff --git a/docs/topics/migrations.txt b/docs/topics/migrations.txt index 0acf1a2110..c767584589 100644 --- a/docs/topics/migrations.txt +++ b/docs/topics/migrations.txt @@ -653,7 +653,7 @@ for basic values, and doesn't specify import paths). Django can serialize the following: -- ``int``, ``float``, ``bool``, ``str``, ``unicode``, ``bytes``, ``None`` +- ``int``, ``float``, ``bool``, ``str``, ``bytes``, ``None`` - ``list``, ``set``, ``tuple``, ``dict`` - ``datetime.date``, ``datetime.time``, and ``datetime.datetime`` instances (include those that are timezone-aware) diff --git a/tests/backends/tests.py b/tests/backends/tests.py index 214852ea77..284a878172 100644 --- a/tests/backends/tests.py +++ b/tests/backends/tests.py @@ -411,9 +411,7 @@ class LastExecutedQueryTest(TestCase): self.assertIn(Reporter._meta.db_table, sql) def test_query_encoding(self): - """ - last_executed_query() returns an Unicode string - """ + """last_executed_query() returns a string.""" data = RawData.objects.filter(raw_data=b'\x00\x46 \xFE').extra(select={'föö': 1}) sql, params = data.query.sql_with_params() cursor = data.query.get_compiler('default').execute_sql(CURSOR) diff --git a/tests/datatypes/tests.py b/tests/datatypes/tests.py index 5c3dffa457..52f24fe051 100644 --- a/tests/datatypes/tests.py +++ b/tests/datatypes/tests.py @@ -69,9 +69,8 @@ class DataTypesTestCase(TestCase): self.assertEqual(0, Donut.objects.filter(consumed_at__year=2005).count()) self.assertEqual(0, Donut.objects.filter(consumed_at__year=2008).count()) - def test_textfields_unicode(self): - """Regression test for #10238: TextField values returned from the - database should be unicode.""" + def test_textfields_str(self): + """TextField values returned from the database should be str.""" d = Donut.objects.create(name='Jelly Donut', review='Outstanding') newd = Donut.objects.get(id=d.id) self.assertIsInstance(newd.review, str) diff --git a/tests/forms_tests/widget_tests/test_clearablefileinput.py b/tests/forms_tests/widget_tests/test_clearablefileinput.py index eea7054541..3250f6e98e 100644 --- a/tests/forms_tests/widget_tests/test_clearablefileinput.py +++ b/tests/forms_tests/widget_tests/test_clearablefileinput.py @@ -6,7 +6,7 @@ from .base import WidgetTest class FakeFieldFile: """ - Quacks like a FieldFile (has a .url and unicode representation), but + Quacks like a FieldFile (has a .url and string representation), but doesn't require us to care about storages etc. """ url = 'something' diff --git a/tests/forms_tests/widget_tests/test_timeinput.py b/tests/forms_tests/widget_tests/test_timeinput.py index 96fb04e24c..ab355e2ec9 100644 --- a/tests/forms_tests/widget_tests/test_timeinput.py +++ b/tests/forms_tests/widget_tests/test_timeinput.py @@ -28,9 +28,7 @@ class TimeInputTest(WidgetTest): )) def test_string(self): - """ - We should be able to initialize from a unicode value. - """ + """Initializing from a string value.""" self.check_html(self.widget, 'time', '13:12:11', html=( '' )) diff --git a/tests/httpwrappers/tests.py b/tests/httpwrappers/tests.py index c58163b014..800b584fe5 100644 --- a/tests/httpwrappers/tests.py +++ b/tests/httpwrappers/tests.py @@ -280,7 +280,7 @@ class HttpResponseTests(unittest.TestCase): def test_headers_type(self): r = HttpResponse() - # ASCII unicode or bytes values are converted to strings. + # ASCII strings or bytes values are converted to strings. r['key'] = 'test' self.assertEqual(r['key'], 'test') r['key'] = 'test'.encode('ascii') @@ -296,7 +296,7 @@ class HttpResponseTests(unittest.TestCase): self.assertEqual(r['key'], '=?utf-8?b?4oCg?=') self.assertIn(b'=?utf-8?b?4oCg?=', r.serialize_headers()) - # The response also converts unicode or bytes keys to strings, but requires + # The response also converts string or bytes keys to strings, but requires # them to contain ASCII r = HttpResponse() del r['Content-Type'] @@ -570,7 +570,7 @@ class StreamingHttpResponseTests(SimpleTestCase): self.assertEqual(list(r), [b'abc', b'def']) self.assertEqual(list(r), []) - # iterating over Unicode strings still yields bytestring chunks. + # iterating over strings still yields bytestring chunks. r.streaming_content = iter(['hello', 'café']) chunks = list(r) # '\xc3\xa9' == unichr(233).encode('utf-8') diff --git a/tests/m2m_and_m2o/models.py b/tests/m2m_and_m2o/models.py index d9da2bf534..9e3cf7c1da 100644 --- a/tests/m2m_and_m2o/models.py +++ b/tests/m2m_and_m2o/models.py @@ -22,5 +22,5 @@ class Issue(models.Model): ordering = ('num',) -class UnicodeReferenceModel(models.Model): - others = models.ManyToManyField("UnicodeReferenceModel") +class StringReferenceModel(models.Model): + others = models.ManyToManyField('StringReferenceModel') diff --git a/tests/m2m_and_m2o/tests.py b/tests/m2m_and_m2o/tests.py index 2c84a7f2d4..aa5daa9d1d 100644 --- a/tests/m2m_and_m2o/tests.py +++ b/tests/m2m_and_m2o/tests.py @@ -1,7 +1,7 @@ from django.db.models import Q from django.test import TestCase -from .models import Issue, UnicodeReferenceModel, User +from .models import Issue, StringReferenceModel, User class RelatedObjectTests(TestCase): @@ -84,11 +84,11 @@ class RelatedObjectTests(TestCase): class RelatedObjectUnicodeTests(TestCase): def test_m2m_with_unicode_reference(self): """ - Regression test for #6045: references to other models can be unicode + Regression test for #6045: references to other models can be strings, providing they are directly convertible to ASCII. """ - m1 = UnicodeReferenceModel.objects.create() - m2 = UnicodeReferenceModel.objects.create() + m1 = StringReferenceModel.objects.create() + m2 = StringReferenceModel.objects.create() m2.others.add(m1) # used to cause an error (see ticket #6045) m2.save() list(m2.others.all()) # Force retrieval. diff --git a/tests/many_to_many/models.py b/tests/many_to_many/models.py index cf3add7848..22911654ab 100644 --- a/tests/many_to_many/models.py +++ b/tests/many_to_many/models.py @@ -29,7 +29,7 @@ class Tag(models.Model): class Article(models.Model): headline = models.CharField(max_length=100) - # Assign a unicode string as name to make sure the intermediary model is + # Assign a string as name to make sure the intermediary model is # correctly created. Refs #20207 publications = models.ManyToManyField(Publication, name='publications') tags = models.ManyToManyField(Tag, related_name='tags') diff --git a/tests/many_to_one/tests.py b/tests/many_to_one/tests.py index 478a746669..52ddcc8cfe 100644 --- a/tests/many_to_one/tests.py +++ b/tests/many_to_one/tests.py @@ -28,9 +28,6 @@ class ManyToOneTests(TestCase): # Article objects have access to their related Reporter objects. r = self.a.reporter self.assertEqual(r.id, self.r.id) - # These are strings instead of unicode strings because that's what was used in - # the creation of this reporter (and we haven't refreshed the data from the - # database, which always returns unicode strings). self.assertEqual((r.first_name, self.r.last_name), ('John', 'Smith')) def test_create(self): @@ -200,7 +197,7 @@ class ManyToOneTests(TestCase): where=["many_to_one_reporter.last_name='Smith'"]), ["", ""] ) - # ... and should work fine with the unicode that comes out of forms.Form.cleaned_data + # ... and should work fine with the string that comes out of forms.Form.cleaned_data self.assertQuerysetEqual( (Article.objects .filter(reporter__first_name__exact='John') diff --git a/tests/model_regress/models.py b/tests/model_regress/models.py index 3208db90b8..7af20e44d3 100644 --- a/tests/model_regress/models.py +++ b/tests/model_regress/models.py @@ -52,7 +52,7 @@ class Worker(models.Model): return self.name -class BrokenUnicodeMethod(models.Model): +class BrokenStrMethod(models.Model): name = models.CharField(max_length=7) def __str__(self): diff --git a/tests/model_regress/tests.py b/tests/model_regress/tests.py index e9374d9d93..1988a3fd09 100644 --- a/tests/model_regress/tests.py +++ b/tests/model_regress/tests.py @@ -8,7 +8,7 @@ from django.test import TestCase, skipUnlessDBFeature from django.utils.timezone import get_fixed_timezone from .models import ( - Article, BrokenUnicodeMethod, Department, Event, Model1, Model2, Model3, + Article, BrokenStrMethod, Department, Event, Model1, Model2, Model3, NonAutoPK, Party, Worker, ) @@ -187,9 +187,9 @@ class ModelTests(TestCase): self.assertEqual(str(w), "Full-time") def test_broken_unicode(self): - # Models with broken unicode methods should still have a printable repr - b = BrokenUnicodeMethod.objects.create(name="Jerry") - self.assertEqual(repr(b), "") + # Models with broken __str__() methods have a printable repr(). + b = BrokenStrMethod.objects.create(name='Jerry') + self.assertEqual(repr(b), '') @skipUnlessDBFeature("supports_timezones") def test_timezones(self): diff --git a/tests/queries/tests.py b/tests/queries/tests.py index 4107dada0e..8fe2af644f 100644 --- a/tests/queries/tests.py +++ b/tests/queries/tests.py @@ -553,9 +553,6 @@ class Queries1Tests(TestCase): s.reverse() params.reverse() - # This slightly odd comparison works around the fact that PostgreSQL will - # return 'one' and 'two' as strings, not Unicode objects. It's a side-effect of - # using constants here and not a real concern. d = Item.objects.extra(select=OrderedDict(s), select_params=params).values('a', 'b')[0] self.assertEqual(d, {'a': 'one', 'b': 'two'}) diff --git a/tests/signing/tests.py b/tests/signing/tests.py index a55457efdd..01dd55fcfe 100644 --- a/tests/signing/tests.py +++ b/tests/signing/tests.py @@ -69,7 +69,7 @@ class TestSigner(SimpleTestCase): "dumps and loads be reversible for any JSON serializable object" objects = [ ['a', 'list'], - 'a unicode string \u2019', + 'a string \u2019', {'a': 'dictionary'}, ] for o in objects: diff --git a/tests/template_tests/syntax_tests/test_filter_syntax.py b/tests/template_tests/syntax_tests/test_filter_syntax.py index c8d764659a..738b3ed978 100644 --- a/tests/template_tests/syntax_tests/test_filter_syntax.py +++ b/tests/template_tests/syntax_tests/test_filter_syntax.py @@ -160,8 +160,7 @@ class FilterSyntaxTests(SimpleTestCase): @setup({'filter-syntax18': r'{{ var }}'}) def test_filter_syntax18(self): """ - Make sure that any unicode strings are converted to bytestrings - in the final output. + Strings are converted to bytestrings in the final output. """ output = self.engine.render_to_string('filter-syntax18', {'var': UTF8Class()}) self.assertEqual(output, '\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111') diff --git a/tests/template_tests/test_loaders.py b/tests/template_tests/test_loaders.py index b90586a078..5c81164bb5 100644 --- a/tests/template_tests/test_loaders.py +++ b/tests/template_tests/test_loaders.py @@ -158,7 +158,7 @@ class FileSystemLoaderTests(SimpleTestCase): with self.source_checker(['/dir1', '/dir2']) as check_sources: # UTF-8 bytestrings are permitted. check_sources(b'\xc3\x85ngstr\xc3\xb6m', ['/dir1/Ångström', '/dir2/Ångström']) - # Unicode strings are permitted. + # Strings are permitted. check_sources('Ångström', ['/dir1/Ångström', '/dir2/Ångström']) def test_utf8_bytestring(self): diff --git a/tests/template_tests/test_unicode.py b/tests/template_tests/test_unicode.py index dbd18eb495..42682166f5 100644 --- a/tests/template_tests/test_unicode.py +++ b/tests/template_tests/test_unicode.py @@ -7,7 +7,7 @@ from django.utils.safestring import SafeData class UnicodeTests(TestCase): def test_template(self): - # Templates can be created from unicode strings. + # Templates can be created from strings. engine = Engine() t1 = engine.from_string('ŠĐĆŽćžšđ {{ var }}') # Templates can also be created from bytestrings. These are assumed to @@ -17,14 +17,14 @@ class UnicodeTests(TestCase): with self.assertRaises(TemplateEncodingError): engine.from_string(b'\x80\xc5\xc0') - # Contexts can be constructed from unicode or UTF-8 bytestrings. + # Contexts can be constructed from strings or UTF-8 bytestrings. Context({b"var": b"foo"}) Context({"var": b"foo"}) c3 = Context({b"var": "Đđ"}) Context({"var": b"\xc4\x90\xc4\x91"}) # Since both templates and all four contexts represent the same thing, - # they all render the same (and are returned as unicode objects and + # they all render the same (and are returned as strings and # "safe" objects as well, for auto-escaping purposes). self.assertEqual(t1.render(c3), t2.render(c3)) self.assertIsInstance(t1.render(c3), str) diff --git a/tests/template_tests/utils.py b/tests/template_tests/utils.py index 3ebacf7bcb..66a173396c 100644 --- a/tests/template_tests/utils.py +++ b/tests/template_tests/utils.py @@ -169,7 +169,7 @@ class UTF8Class: return 'ŠĐĆŽćžšđ' -# These two classes are used to test auto-escaping of unicode output. +# These two classes are used to test auto-escaping of string output. class UnsafeClass: def __str__(self): return 'you & me' diff --git a/tests/test_client_regress/tests.py b/tests/test_client_regress/tests.py index d3263d07a6..e5f9eb97b9 100644 --- a/tests/test_client_regress/tests.py +++ b/tests/test_client_regress/tests.py @@ -1266,7 +1266,7 @@ class QueryStringTests(SimpleTestCase): class UnicodePayloadTests(SimpleTestCase): def test_simple_unicode_payload(self): - "A simple ASCII-only unicode JSON document can be POSTed" + "A simple ASCII-only JSON document can be POSTed" # Regression test for #10571 json = '{"english": "mountain pass"}' response = self.client.post("/parse_unicode_json/", json, content_type="application/json")