From b10ca0c9c40224ce8a2ae25518d1e1170e8405b2 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Tue, 4 Aug 2026 21:36:36 +0300 Subject: [PATCH] gh-62978: Use Python 3 terms in the email package docs Replace "Unicode string" with "string" and the unicode() built-in with str() in docstrings, comments and documentation of the email package. "byte string" is only replaced with "bytes" where other bytes-like objects are not accepted. Co-Authored-By: Claude Opus 5 (1M context) --- Doc/library/email.compat32-message.rst | 2 +- Doc/library/email.contentmanager.rst | 6 +++--- Doc/library/email.examples.rst | 2 +- Doc/library/email.header.rst | 4 ++-- Doc/library/email.headerregistry.rst | 14 +++++++------- Doc/library/email.policy.rst | 8 ++++---- Doc/library/email.rst | 4 ++-- Doc/library/email.utils.rst | 2 +- Lib/email/_encoded_words.py | 8 ++++---- Lib/email/_policybase.py | 2 +- Lib/email/charset.py | 10 +++++----- Lib/email/header.py | 10 +++++----- Lib/email/message.py | 8 ++++---- Lib/email/policy.py | 4 ++-- Lib/email/utils.py | 4 ++-- 15 files changed, 44 insertions(+), 44 deletions(-) diff --git a/Doc/library/email.compat32-message.rst b/Doc/library/email.compat32-message.rst index 5754c2b65b239f9..11b4d908fcd7d60 100644 --- a/Doc/library/email.compat32-message.rst +++ b/Doc/library/email.compat32-message.rst @@ -96,7 +96,7 @@ Here are the methods of the :class:`Message` class: text = fp.getvalue() If the message object contains binary data that is not encoded according - to RFC standards, the non-compliant data will be replaced by unicode + to RFC standards, the non-compliant data will be replaced by Unicode "unknown character" code points. (See also :meth:`.as_bytes` and :class:`~email.generator.BytesGenerator`.) diff --git a/Doc/library/email.contentmanager.rst b/Doc/library/email.contentmanager.rst index 04a41667f7dc2cd..b28160082f6858c 100644 --- a/Doc/library/email.contentmanager.rst +++ b/Doc/library/email.contentmanager.rst @@ -96,9 +96,9 @@ Currently the email package provides only one concrete content manager, This content manager provides only a minimum interface beyond that provided by :class:`~email.message.Message` itself: it deals only with text, raw - byte strings, and :class:`~email.message.Message` objects. Nevertheless, it + bytes, and :class:`~email.message.Message` objects. Nevertheless, it provides significant advantages compared to the base API: ``get_content`` on - a text part will return a unicode string without the application needing to + a text part will return a string without the application needing to manually decode it, ``set_content`` provides a rich set of options for controlling the headers added to a part and controlling the content transfer encoding, and it enables the use of the various ``add_`` methods, thereby @@ -111,7 +111,7 @@ Currently the email package provides only one concrete content manager, parts), or a ``bytes`` object (for all other non-multipart types). Raise a :exc:`KeyError` if called on a ``multipart``. If the part is a ``text`` part and *errors* is specified, use it as the error handler when - decoding the payload to unicode. The default error handler is + decoding the payload to a string. The default error handler is ``replace``. .. method:: set_content(msg, <'str'>, subtype="plain", charset='utf-8', \ diff --git a/Doc/library/email.examples.rst b/Doc/library/email.examples.rst index 492a8354d8bf852..7586cbd25f9f3be 100644 --- a/Doc/library/email.examples.rst +++ b/Doc/library/email.examples.rst @@ -7,7 +7,7 @@ Here are a few examples of how to use the :mod:`email` package to read, write, and send simple email messages, as well as more complex MIME messages. First, let's see how to create and send a simple text message (both the -text content and the addresses may contain unicode characters): +text content and the addresses may contain Unicode characters): .. literalinclude:: ../includes/email-simple.py diff --git a/Doc/library/email.header.rst b/Doc/library/email.header.rst index e7e21d036e07deb..65e2d0367fd7684 100644 --- a/Doc/library/email.header.rst +++ b/Doc/library/email.header.rst @@ -49,7 +49,7 @@ For example:: Notice here how we wanted the :mailheader:`Subject` field to contain a non-ASCII character? We did this by creating a :class:`Header` instance and passing in -the character set that the byte string was encoded in. When the subsequent +the character set to use when encoding it. When the subsequent :class:`~email.message.Message` instance was flattened, the :mailheader:`Subject` field was properly :rfc:`2047` encoded. MIME-aware mail readers would show this header using the embedded ISO-8859-1 character. @@ -150,7 +150,7 @@ Here is the :class:`Header` class description: .. method:: __str__() Returns an approximation of the :class:`Header` as a string, using an - unlimited line length. All pieces are converted to unicode using the + unlimited line length. All pieces are decoded using the specified encoding and joined together appropriately. Any pieces with a charset of ``'unknown-8bit'`` are decoded as ASCII using the ``'replace'`` error handler. diff --git a/Doc/library/email.headerregistry.rst b/Doc/library/email.headerregistry.rst index 619c17c98e8d89c..1cdc0b80c19dc5c 100644 --- a/Doc/library/email.headerregistry.rst +++ b/Doc/library/email.headerregistry.rst @@ -40,7 +40,7 @@ headers. *name* and *value* are passed to ``BaseHeader`` from the :attr:`~email.policy.EmailPolicy.header_factory` call. The string value of - any header object is the *value* fully decoded to unicode. + any header object is the *value* fully decoded to a string. This base class defines the following read-only properties: @@ -95,10 +95,10 @@ headers. defects to this list. On return, the ``kwds`` dictionary *must* contain values for at least the keys ``decoded``, ``defects`` and ``parse_tree``. ``decoded`` should be the string value for the header (that is, the header - value fully decoded to unicode). ``parse_tree`` is set to the parse tree obtained + value fully decoded to a string). ``parse_tree`` is set to the parse tree obtained from parsing the header. The parse method should assume that *string* may contain content-transfer-encoded parts, but should correctly handle all valid - unicode characters as well so that it can parse un-encoded header values. + Unicode characters as well so that it can parse un-encoded header values. ``BaseHeader``'s ``__new__`` then creates the header instance, and calls its ``init`` method. The specialized class only needs to provide an ``init`` @@ -126,7 +126,7 @@ headers. mechanism for encoding non-ASCII text as ASCII characters within a header value. When a *value* containing encoded words is passed to the constructor, the ``UnstructuredHeader`` parser converts such encoded words - into unicode, following the :rfc:`2047` rules for unstructured text. The + into a string, following the :rfc:`2047` rules for unstructured text. The parser uses heuristics to attempt to decode certain non-compliant encoded words. Defects are registered in such cases, as well as defects for issues such as invalid characters within the encoded words or the non-encoded text. @@ -203,8 +203,8 @@ headers. the list of addresses is "flattened" into a one dimensional list). The ``decoded`` value of the header will have all encoded words decoded to - unicode. :class:`~encodings.idna` encoded domain names are also decoded to - unicode. The ``decoded`` value is set by :ref:`joining ` the + a string. :class:`~encodings.idna` encoded domain names are also decoded to + a string. The ``decoded`` value is set by :ref:`joining ` the :class:`str` value of the elements of the ``groups`` attribute with ``', '``. @@ -392,7 +392,7 @@ construct structured values to assign to specific headers. *domain*, in which case *username* and *domain* will be parsed from the *addr_spec*. An *addr_spec* must be a properly RFC quoted string; if it is not ``Address`` will raise an error. Unicode characters are allowed and - will be property encoded when serialized. However, per the RFCs, unicode is + will be property encoded when serialized. However, per the RFCs, Unicode is *not* allowed in the username portion of the address. .. attribute:: display_name diff --git a/Doc/library/email.policy.rst b/Doc/library/email.policy.rst index 816d02d86f4fc4b..82a2b305f8daedb 100644 --- a/Doc/library/email.policy.rst +++ b/Doc/library/email.policy.rst @@ -505,7 +505,7 @@ added matters. To illustrate:: Otherwise the *name*, and the *value* with any CR or LF characters removed, are passed to the ``header_factory``, and the resulting header object is returned. Any surrogateescaped bytes get turned into - the unicode unknown-character glyph. + the Unicode unknown-character glyph. .. method:: fold(name, value) @@ -600,10 +600,10 @@ the email package is changed from the Python 3.2 API in the following ways: From the application view, this means that any header obtained through the :class:`~email.message.EmailMessage` is a header object with extra -attributes, whose string value is the fully decoded unicode value of the +attributes, whose string value is the fully decoded value of the header. Likewise, a header may be assigned a new value, or a new header -created, using a unicode string, and the policy will take care of converting -the unicode string into the correct RFC encoded form. +created, using a string, and the policy will take care of converting +the string into the correct RFC encoded form. The header objects and their attributes are described in :mod:`~email.headerregistry`. diff --git a/Doc/library/email.rst b/Doc/library/email.rst index 98b47ffd74096c0..d1a3d9a63eca2ee 100644 --- a/Doc/library/email.rst +++ b/Doc/library/email.rst @@ -54,7 +54,7 @@ server. The email package does its best to hide the details of the various governing RFCs from the application. Conceptually the application should be able to -treat the email message as a structured tree of unicode text and binary +treat the email message as a structured tree of Unicode text and binary attachments, without having to worry about how these are represented when serialized. In practice, however, it is often necessary to be aware of at least some of the rules governing MIME messages and their structure, @@ -84,7 +84,7 @@ to advanced applications. Following those is a set of examples of using the fundamental parts of the APIs covered in the preceding sections. -The foregoing represent the modern (unicode friendly) API of the email package. +The foregoing represent the modern (Unicode friendly) API of the email package. The remaining sections, starting with the :class:`~email.message.Message` class, cover the legacy :data:`~email.policy.compat32` API that deals much more directly with the details of how email messages are represented. The diff --git a/Doc/library/email.utils.rst b/Doc/library/email.utils.rst index 0a96dbfd196a051..acf7093ae10a807 100644 --- a/Doc/library/email.utils.rst +++ b/Doc/library/email.utils.rst @@ -212,7 +212,7 @@ of the new API. When a header parameter is encoded in :rfc:`2231` format, :meth:`Message.get_param ` may return a 3-tuple containing the character set, - language, and value. :func:`collapse_rfc2231_value` turns this into a unicode + language, and value. :func:`collapse_rfc2231_value` turns this into a string. Optional *errors* is passed to the *errors* argument of :class:`str`'s :func:`~str.encode` method; it defaults to ``'replace'``. Optional *fallback_charset* specifies the character set to use if the one in the diff --git a/Lib/email/_encoded_words.py b/Lib/email/_encoded_words.py index 05a34a4c1052336..ecbaecb7a68ed5b 100644 --- a/Lib/email/_encoded_words.py +++ b/Lib/email/_encoded_words.py @@ -161,10 +161,10 @@ def decode(ew): This function expects exactly such a string (that is, it does not check the syntax and may raise errors if the string is not well formed), and returns the encoded_string decoded first from its Content Transfer Encoding and - then from the resulting bytes into unicode using the specified charset. If - the cte-decoded string does not successfully decode using the specified + then from the resulting bytes into a string using the specified charset. + If the cte-decoded string does not successfully decode using the specified character set, a defect is added to the defects list and the unknown octets - are replaced by the unicode 'unknown' character \\uFDFF. + are replaced by the Unicode 'unknown' character \\uFDFF. The specified charset and language are returned. The default for language, which is rarely if ever encountered, is the empty string. @@ -176,7 +176,7 @@ def decode(ew): # Recover the original bytes and do CTE decoding. bstring = cte_string.encode('ascii', 'surrogateescape') bstring, defects = _cte_decoders[cte](bstring) - # Turn the CTE decoded bytes into unicode. + # Turn the CTE decoded bytes into a string. try: string = bstring.decode(charset) except UnicodeDecodeError: diff --git a/Lib/email/_policybase.py b/Lib/email/_policybase.py index e23843df44881f3..ab40be6b9204f41 100644 --- a/Lib/email/_policybase.py +++ b/Lib/email/_policybase.py @@ -365,7 +365,7 @@ def _fold(self, name, value, sanitize): charset=_charset.UNKNOWN8BIT, header_name=name) else: - # If we have raw 8bit data in a byte string, we have no idea + # If we have raw 8bit data in a string, we have no idea # what the encoding is. There is no safe way to split this # string. If it's ascii-subset, then we could do a normal # ascii split, but if it's multibyte then we could break the diff --git a/Lib/email/charset.py b/Lib/email/charset.py index 5981791820e740c..44fe0794bb73f39 100644 --- a/Lib/email/charset.py +++ b/Lib/email/charset.py @@ -177,8 +177,8 @@ def add_codec(charset, codecname): """Add a codec that map characters in the given charset to/from Unicode. charset is the canonical name of a character set. codecname is the name - of a Python codec, as appropriate for the second argument to the unicode() - built-in, or to the encode() method of a Unicode string. + of a Python codec, as appropriate for the second argument to the str() + built-in, or to the encode() method of a string. """ CODEC_MAP[charset] = codecname @@ -238,8 +238,8 @@ class Charset: """ def __init__(self, input_charset=DEFAULT_CHARSET): # RFC 2046, $4.1.2 says charsets are not case sensitive. We coerce to - # unicode because its .lower() is locale insensitive. If the argument - # is already a unicode, we leave it at that, but ensure that the + # str because its .lower() is locale insensitive. If the argument + # is already a str, we leave it at that, but ensure that the # charset is ASCII, as the standard (RFC XXX) requires. try: if isinstance(input_charset, str): @@ -365,7 +365,7 @@ def header_encode_lines(self, string, maxlengths): # encoded word must stand on its own. So the problem is you have to # encode to bytes to figure out this word's length, but you must split # on characters. This causes two problems: first, we don't know how - # many octets a specific substring of unicode characters will get + # many octets a specific substring of characters will get # encoded to, and second, we don't know how many ASCII characters # those octets will get encoded to. Unless we try it. Which seems # inefficient. In the interest of being correct rather than fast (and diff --git a/Lib/email/header.py b/Lib/email/header.py index 220a84a7454b214..ea1f84ea964ca60 100644 --- a/Lib/email/header.py +++ b/Lib/email/header.py @@ -189,7 +189,7 @@ def __init__(self, s=None, charset=None, Optional s is the initial header value. If None, the initial header value is not set. You can later append to the header with .append() - method calls. s may be a byte string or a Unicode string, but see the + method calls. s may be a byte string or a string, but see the .append() documentation for semantics. Optional charset serves two purposes: it has the same meaning as the @@ -263,7 +263,7 @@ def __str__(self): # have or explicitly disable <, <=, >, >= operators? def __eq__(self, other): # other may be a Header or a string. Both are fine so coerce - # ourselves to a unicode (of the unencoded header value), swap the + # ourselves to a str (of the unencoded header value), swap the # args and do another comparison. return other == str(self) @@ -275,10 +275,10 @@ def append(self, s, charset=None, errors='strict'): value of None (the default) means that the charset given in the constructor is used. - s may be a byte string or a Unicode string. If it is a byte string + s may be a byte string or a string. If it is a byte string (i.e. isinstance(s, str) is false), then charset is the encoding of that byte string, and a UnicodeError will be raised if the string - cannot be decoded with that charset. If s is a Unicode string, then + cannot be decoded with that charset. If s is a string, then charset is a hint specifying the character set of the characters in the string. In either case, when producing an RFC 2822 compliant header using RFC 2047 rules, the string will be encoded using the @@ -397,7 +397,7 @@ def encode(self, splitchars=';, \t', maxlinelen=None, linesep='\n'): def _normalize(self): # Step 1: Normalize the chunks so that all runs of identical charsets - # get collapsed into a single unicode string. + # get collapsed into a single string. chunks = [] last_charset = None last_chunk = [] diff --git a/Lib/email/message.py b/Lib/email/message.py index 641fb2e944d4311..64e6c1e23cfb47f 100644 --- a/Lib/email/message.py +++ b/Lib/email/message.py @@ -98,7 +98,7 @@ def _parseparam(s): def _unquotevalue(value): # This is different than utils.collapse_rfc2231_value() because it doesn't - # try to convert the value to a unicode. Message.get_param() and + # try to convert the value to a str. Message.get_param() and # Message.get_params() are both currently defined to return the tuple in # the face of RFC 2231 parameters. if isinstance(value, tuple): @@ -182,7 +182,7 @@ def as_string(self, unixfrom=False, maxheaderlen=0, policy=None): If the message object contains binary data that is not encoded according to RFC standards, the non-compliant data will be replaced by - unicode "unknown character" code points. + Unicode "unknown character" code points. """ from email.generator import Generator policy = self.policy if policy is None else policy @@ -315,7 +315,7 @@ def get_payload(self, i=None, decode=False): bpayload = payload.encode('ascii', 'surrogateescape') except UnicodeEncodeError: # This won't happen for RFC compliant messages (messages - # containing only ASCII code points in the unicode input). + # containing only ASCII code points in the string input). # If it does happen, turn the string into bytes in a way # guaranteed not to fail. bpayload = payload.encode('raw-unicode-escape') @@ -395,7 +395,7 @@ def set_charset(self, charset): try: cte(self) except TypeError: - # This 'if' is for backward compatibility, it allows unicode + # This 'if' is for backward compatibility, it allows str # through even though that won't work correctly if the # message is serialized. payload = self._payload diff --git a/Lib/email/policy.py b/Lib/email/policy.py index 4169150101a29d6..d09d2f5238d40b2 100644 --- a/Lib/email/policy.py +++ b/Lib/email/policy.py @@ -160,7 +160,7 @@ def header_fetch_parse(self, name, value): Otherwise the name and the value with any linesep characters removed are passed to the header_factory method, and the resulting custom header object is returned. Any surrogateescaped bytes get turned - into the unicode unknown-character glyph. + into the Unicode unknown-character glyph. """ if hasattr(value, 'name'): @@ -201,7 +201,7 @@ def fold_binary(self, name, value): data consists of single byte characters or multibyte characters. If utf8 is true, headers are encoded to utf8, otherwise to ascii with - non-ASCII unicode rendered as encoded words. + non-ASCII characters rendered as encoded words. """ folded = self._fold(name, value, refold_binary=self.cte_type=='7bit') diff --git a/Lib/email/utils.py b/Lib/email/utils.py index 6889c5591bf0306..c8a6d0af37532c9 100644 --- a/Lib/email/utils.py +++ b/Lib/email/utils.py @@ -58,7 +58,7 @@ def _has_surrogates(s): # How to deal with a string containing bytes before handing it to the # application through the 'normal' interface. def _sanitize(string): - # Turn any escaped bytes into unicode 'unknown' char. If the escaped + # Turn any escaped bytes into the Unicode 'unknown' char. If the escaped # bytes happen to be utf-8 they will instead get decoded, even if they # were invalid in the charset the source was supposed to be in. This # seems like it is not a bad thing; a defect was still registered. @@ -460,7 +460,7 @@ def collapse_rfc2231_value(value, errors='replace', fallback_charset='us-ascii'): if not isinstance(value, tuple) or len(value) != 3: return unquote(value) - # While value comes to us as a unicode string, we need it to be a bytes + # While value comes to us as a string, we need it to be a bytes # object. We do not want bytes() normal utf-8 decoder, we want a straight # interpretation of the string as character bytes. charset, language, text = value