17db96d56Sopenharmony_ci"""Policy framework for the email package.
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ciAllows fine grained feature control of how the package parses and emits data.
47db96d56Sopenharmony_ci"""
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ciimport abc
77db96d56Sopenharmony_cifrom email import header
87db96d56Sopenharmony_cifrom email import charset as _charset
97db96d56Sopenharmony_cifrom email.utils import _has_surrogates
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci__all__ = [
127db96d56Sopenharmony_ci    'Policy',
137db96d56Sopenharmony_ci    'Compat32',
147db96d56Sopenharmony_ci    'compat32',
157db96d56Sopenharmony_ci    ]
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ciclass _PolicyBase:
197db96d56Sopenharmony_ci
207db96d56Sopenharmony_ci    """Policy Object basic framework.
217db96d56Sopenharmony_ci
227db96d56Sopenharmony_ci    This class is useless unless subclassed.  A subclass should define
237db96d56Sopenharmony_ci    class attributes with defaults for any values that are to be
247db96d56Sopenharmony_ci    managed by the Policy object.  The constructor will then allow
257db96d56Sopenharmony_ci    non-default values to be set for these attributes at instance
267db96d56Sopenharmony_ci    creation time.  The instance will be callable, taking these same
277db96d56Sopenharmony_ci    attributes keyword arguments, and returning a new instance
287db96d56Sopenharmony_ci    identical to the called instance except for those values changed
297db96d56Sopenharmony_ci    by the keyword arguments.  Instances may be added, yielding new
307db96d56Sopenharmony_ci    instances with any non-default values from the right hand
317db96d56Sopenharmony_ci    operand overriding those in the left hand operand.  That is,
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ci        A + B == A(<non-default values of B>)
347db96d56Sopenharmony_ci
357db96d56Sopenharmony_ci    The repr of an instance can be used to reconstruct the object
367db96d56Sopenharmony_ci    if and only if the repr of the values can be used to reconstruct
377db96d56Sopenharmony_ci    those values.
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci    """
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci    def __init__(self, **kw):
427db96d56Sopenharmony_ci        """Create new Policy, possibly overriding some defaults.
437db96d56Sopenharmony_ci
447db96d56Sopenharmony_ci        See class docstring for a list of overridable attributes.
457db96d56Sopenharmony_ci
467db96d56Sopenharmony_ci        """
477db96d56Sopenharmony_ci        for name, value in kw.items():
487db96d56Sopenharmony_ci            if hasattr(self, name):
497db96d56Sopenharmony_ci                super(_PolicyBase,self).__setattr__(name, value)
507db96d56Sopenharmony_ci            else:
517db96d56Sopenharmony_ci                raise TypeError(
527db96d56Sopenharmony_ci                    "{!r} is an invalid keyword argument for {}".format(
537db96d56Sopenharmony_ci                        name, self.__class__.__name__))
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ci    def __repr__(self):
567db96d56Sopenharmony_ci        args = [ "{}={!r}".format(name, value)
577db96d56Sopenharmony_ci                 for name, value in self.__dict__.items() ]
587db96d56Sopenharmony_ci        return "{}({})".format(self.__class__.__name__, ', '.join(args))
597db96d56Sopenharmony_ci
607db96d56Sopenharmony_ci    def clone(self, **kw):
617db96d56Sopenharmony_ci        """Return a new instance with specified attributes changed.
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci        The new instance has the same attribute values as the current object,
647db96d56Sopenharmony_ci        except for the changes passed in as keyword arguments.
657db96d56Sopenharmony_ci
667db96d56Sopenharmony_ci        """
677db96d56Sopenharmony_ci        newpolicy = self.__class__.__new__(self.__class__)
687db96d56Sopenharmony_ci        for attr, value in self.__dict__.items():
697db96d56Sopenharmony_ci            object.__setattr__(newpolicy, attr, value)
707db96d56Sopenharmony_ci        for attr, value in kw.items():
717db96d56Sopenharmony_ci            if not hasattr(self, attr):
727db96d56Sopenharmony_ci                raise TypeError(
737db96d56Sopenharmony_ci                    "{!r} is an invalid keyword argument for {}".format(
747db96d56Sopenharmony_ci                        attr, self.__class__.__name__))
757db96d56Sopenharmony_ci            object.__setattr__(newpolicy, attr, value)
767db96d56Sopenharmony_ci        return newpolicy
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ci    def __setattr__(self, name, value):
797db96d56Sopenharmony_ci        if hasattr(self, name):
807db96d56Sopenharmony_ci            msg = "{!r} object attribute {!r} is read-only"
817db96d56Sopenharmony_ci        else:
827db96d56Sopenharmony_ci            msg = "{!r} object has no attribute {!r}"
837db96d56Sopenharmony_ci        raise AttributeError(msg.format(self.__class__.__name__, name))
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_ci    def __add__(self, other):
867db96d56Sopenharmony_ci        """Non-default values from right operand override those from left.
877db96d56Sopenharmony_ci
887db96d56Sopenharmony_ci        The object returned is a new instance of the subclass.
897db96d56Sopenharmony_ci
907db96d56Sopenharmony_ci        """
917db96d56Sopenharmony_ci        return self.clone(**other.__dict__)
927db96d56Sopenharmony_ci
937db96d56Sopenharmony_ci
947db96d56Sopenharmony_cidef _append_doc(doc, added_doc):
957db96d56Sopenharmony_ci    doc = doc.rsplit('\n', 1)[0]
967db96d56Sopenharmony_ci    added_doc = added_doc.split('\n', 1)[1]
977db96d56Sopenharmony_ci    return doc + '\n' + added_doc
987db96d56Sopenharmony_ci
997db96d56Sopenharmony_cidef _extend_docstrings(cls):
1007db96d56Sopenharmony_ci    if cls.__doc__ and cls.__doc__.startswith('+'):
1017db96d56Sopenharmony_ci        cls.__doc__ = _append_doc(cls.__bases__[0].__doc__, cls.__doc__)
1027db96d56Sopenharmony_ci    for name, attr in cls.__dict__.items():
1037db96d56Sopenharmony_ci        if attr.__doc__ and attr.__doc__.startswith('+'):
1047db96d56Sopenharmony_ci            for c in (c for base in cls.__bases__ for c in base.mro()):
1057db96d56Sopenharmony_ci                doc = getattr(getattr(c, name), '__doc__')
1067db96d56Sopenharmony_ci                if doc:
1077db96d56Sopenharmony_ci                    attr.__doc__ = _append_doc(doc, attr.__doc__)
1087db96d56Sopenharmony_ci                    break
1097db96d56Sopenharmony_ci    return cls
1107db96d56Sopenharmony_ci
1117db96d56Sopenharmony_ci
1127db96d56Sopenharmony_ciclass Policy(_PolicyBase, metaclass=abc.ABCMeta):
1137db96d56Sopenharmony_ci
1147db96d56Sopenharmony_ci    r"""Controls for how messages are interpreted and formatted.
1157db96d56Sopenharmony_ci
1167db96d56Sopenharmony_ci    Most of the classes and many of the methods in the email package accept
1177db96d56Sopenharmony_ci    Policy objects as parameters.  A Policy object contains a set of values and
1187db96d56Sopenharmony_ci    functions that control how input is interpreted and how output is rendered.
1197db96d56Sopenharmony_ci    For example, the parameter 'raise_on_defect' controls whether or not an RFC
1207db96d56Sopenharmony_ci    violation results in an error being raised or not, while 'max_line_length'
1217db96d56Sopenharmony_ci    controls the maximum length of output lines when a Message is serialized.
1227db96d56Sopenharmony_ci
1237db96d56Sopenharmony_ci    Any valid attribute may be overridden when a Policy is created by passing
1247db96d56Sopenharmony_ci    it as a keyword argument to the constructor.  Policy objects are immutable,
1257db96d56Sopenharmony_ci    but a new Policy object can be created with only certain values changed by
1267db96d56Sopenharmony_ci    calling the Policy instance with keyword arguments.  Policy objects can
1277db96d56Sopenharmony_ci    also be added, producing a new Policy object in which the non-default
1287db96d56Sopenharmony_ci    attributes set in the right hand operand overwrite those specified in the
1297db96d56Sopenharmony_ci    left operand.
1307db96d56Sopenharmony_ci
1317db96d56Sopenharmony_ci    Settable attributes:
1327db96d56Sopenharmony_ci
1337db96d56Sopenharmony_ci    raise_on_defect     -- If true, then defects should be raised as errors.
1347db96d56Sopenharmony_ci                           Default: False.
1357db96d56Sopenharmony_ci
1367db96d56Sopenharmony_ci    linesep             -- string containing the value to use as separation
1377db96d56Sopenharmony_ci                           between output lines.  Default '\n'.
1387db96d56Sopenharmony_ci
1397db96d56Sopenharmony_ci    cte_type            -- Type of allowed content transfer encodings
1407db96d56Sopenharmony_ci
1417db96d56Sopenharmony_ci                           7bit  -- ASCII only
1427db96d56Sopenharmony_ci                           8bit  -- Content-Transfer-Encoding: 8bit is allowed
1437db96d56Sopenharmony_ci
1447db96d56Sopenharmony_ci                           Default: 8bit.  Also controls the disposition of
1457db96d56Sopenharmony_ci                           (RFC invalid) binary data in headers; see the
1467db96d56Sopenharmony_ci                           documentation of the binary_fold method.
1477db96d56Sopenharmony_ci
1487db96d56Sopenharmony_ci    max_line_length     -- maximum length of lines, excluding 'linesep',
1497db96d56Sopenharmony_ci                           during serialization.  None or 0 means no line
1507db96d56Sopenharmony_ci                           wrapping is done.  Default is 78.
1517db96d56Sopenharmony_ci
1527db96d56Sopenharmony_ci    mangle_from_        -- a flag that, when True escapes From_ lines in the
1537db96d56Sopenharmony_ci                           body of the message by putting a `>' in front of
1547db96d56Sopenharmony_ci                           them. This is used when the message is being
1557db96d56Sopenharmony_ci                           serialized by a generator. Default: True.
1567db96d56Sopenharmony_ci
1577db96d56Sopenharmony_ci    message_factory     -- the class to use to create new message objects.
1587db96d56Sopenharmony_ci                           If the value is None, the default is Message.
1597db96d56Sopenharmony_ci
1607db96d56Sopenharmony_ci    """
1617db96d56Sopenharmony_ci
1627db96d56Sopenharmony_ci    raise_on_defect = False
1637db96d56Sopenharmony_ci    linesep = '\n'
1647db96d56Sopenharmony_ci    cte_type = '8bit'
1657db96d56Sopenharmony_ci    max_line_length = 78
1667db96d56Sopenharmony_ci    mangle_from_ = False
1677db96d56Sopenharmony_ci    message_factory = None
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ci    def handle_defect(self, obj, defect):
1707db96d56Sopenharmony_ci        """Based on policy, either raise defect or call register_defect.
1717db96d56Sopenharmony_ci
1727db96d56Sopenharmony_ci            handle_defect(obj, defect)
1737db96d56Sopenharmony_ci
1747db96d56Sopenharmony_ci        defect should be a Defect subclass, but in any case must be an
1757db96d56Sopenharmony_ci        Exception subclass.  obj is the object on which the defect should be
1767db96d56Sopenharmony_ci        registered if it is not raised.  If the raise_on_defect is True, the
1777db96d56Sopenharmony_ci        defect is raised as an error, otherwise the object and the defect are
1787db96d56Sopenharmony_ci        passed to register_defect.
1797db96d56Sopenharmony_ci
1807db96d56Sopenharmony_ci        This method is intended to be called by parsers that discover defects.
1817db96d56Sopenharmony_ci        The email package parsers always call it with Defect instances.
1827db96d56Sopenharmony_ci
1837db96d56Sopenharmony_ci        """
1847db96d56Sopenharmony_ci        if self.raise_on_defect:
1857db96d56Sopenharmony_ci            raise defect
1867db96d56Sopenharmony_ci        self.register_defect(obj, defect)
1877db96d56Sopenharmony_ci
1887db96d56Sopenharmony_ci    def register_defect(self, obj, defect):
1897db96d56Sopenharmony_ci        """Record 'defect' on 'obj'.
1907db96d56Sopenharmony_ci
1917db96d56Sopenharmony_ci        Called by handle_defect if raise_on_defect is False.  This method is
1927db96d56Sopenharmony_ci        part of the Policy API so that Policy subclasses can implement custom
1937db96d56Sopenharmony_ci        defect handling.  The default implementation calls the append method of
1947db96d56Sopenharmony_ci        the defects attribute of obj.  The objects used by the email package by
1957db96d56Sopenharmony_ci        default that get passed to this method will always have a defects
1967db96d56Sopenharmony_ci        attribute with an append method.
1977db96d56Sopenharmony_ci
1987db96d56Sopenharmony_ci        """
1997db96d56Sopenharmony_ci        obj.defects.append(defect)
2007db96d56Sopenharmony_ci
2017db96d56Sopenharmony_ci    def header_max_count(self, name):
2027db96d56Sopenharmony_ci        """Return the maximum allowed number of headers named 'name'.
2037db96d56Sopenharmony_ci
2047db96d56Sopenharmony_ci        Called when a header is added to a Message object.  If the returned
2057db96d56Sopenharmony_ci        value is not 0 or None, and there are already a number of headers with
2067db96d56Sopenharmony_ci        the name 'name' equal to the value returned, a ValueError is raised.
2077db96d56Sopenharmony_ci
2087db96d56Sopenharmony_ci        Because the default behavior of Message's __setitem__ is to append the
2097db96d56Sopenharmony_ci        value to the list of headers, it is easy to create duplicate headers
2107db96d56Sopenharmony_ci        without realizing it.  This method allows certain headers to be limited
2117db96d56Sopenharmony_ci        in the number of instances of that header that may be added to a
2127db96d56Sopenharmony_ci        Message programmatically.  (The limit is not observed by the parser,
2137db96d56Sopenharmony_ci        which will faithfully produce as many headers as exist in the message
2147db96d56Sopenharmony_ci        being parsed.)
2157db96d56Sopenharmony_ci
2167db96d56Sopenharmony_ci        The default implementation returns None for all header names.
2177db96d56Sopenharmony_ci        """
2187db96d56Sopenharmony_ci        return None
2197db96d56Sopenharmony_ci
2207db96d56Sopenharmony_ci    @abc.abstractmethod
2217db96d56Sopenharmony_ci    def header_source_parse(self, sourcelines):
2227db96d56Sopenharmony_ci        """Given a list of linesep terminated strings constituting the lines of
2237db96d56Sopenharmony_ci        a single header, return the (name, value) tuple that should be stored
2247db96d56Sopenharmony_ci        in the model.  The input lines should retain their terminating linesep
2257db96d56Sopenharmony_ci        characters.  The lines passed in by the email package may contain
2267db96d56Sopenharmony_ci        surrogateescaped binary data.
2277db96d56Sopenharmony_ci        """
2287db96d56Sopenharmony_ci        raise NotImplementedError
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci    @abc.abstractmethod
2317db96d56Sopenharmony_ci    def header_store_parse(self, name, value):
2327db96d56Sopenharmony_ci        """Given the header name and the value provided by the application
2337db96d56Sopenharmony_ci        program, return the (name, value) that should be stored in the model.
2347db96d56Sopenharmony_ci        """
2357db96d56Sopenharmony_ci        raise NotImplementedError
2367db96d56Sopenharmony_ci
2377db96d56Sopenharmony_ci    @abc.abstractmethod
2387db96d56Sopenharmony_ci    def header_fetch_parse(self, name, value):
2397db96d56Sopenharmony_ci        """Given the header name and the value from the model, return the value
2407db96d56Sopenharmony_ci        to be returned to the application program that is requesting that
2417db96d56Sopenharmony_ci        header.  The value passed in by the email package may contain
2427db96d56Sopenharmony_ci        surrogateescaped binary data if the lines were parsed by a BytesParser.
2437db96d56Sopenharmony_ci        The returned value should not contain any surrogateescaped data.
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ci        """
2467db96d56Sopenharmony_ci        raise NotImplementedError
2477db96d56Sopenharmony_ci
2487db96d56Sopenharmony_ci    @abc.abstractmethod
2497db96d56Sopenharmony_ci    def fold(self, name, value):
2507db96d56Sopenharmony_ci        """Given the header name and the value from the model, return a string
2517db96d56Sopenharmony_ci        containing linesep characters that implement the folding of the header
2527db96d56Sopenharmony_ci        according to the policy controls.  The value passed in by the email
2537db96d56Sopenharmony_ci        package may contain surrogateescaped binary data if the lines were
2547db96d56Sopenharmony_ci        parsed by a BytesParser.  The returned value should not contain any
2557db96d56Sopenharmony_ci        surrogateescaped data.
2567db96d56Sopenharmony_ci
2577db96d56Sopenharmony_ci        """
2587db96d56Sopenharmony_ci        raise NotImplementedError
2597db96d56Sopenharmony_ci
2607db96d56Sopenharmony_ci    @abc.abstractmethod
2617db96d56Sopenharmony_ci    def fold_binary(self, name, value):
2627db96d56Sopenharmony_ci        """Given the header name and the value from the model, return binary
2637db96d56Sopenharmony_ci        data containing linesep characters that implement the folding of the
2647db96d56Sopenharmony_ci        header according to the policy controls.  The value passed in by the
2657db96d56Sopenharmony_ci        email package may contain surrogateescaped binary data.
2667db96d56Sopenharmony_ci
2677db96d56Sopenharmony_ci        """
2687db96d56Sopenharmony_ci        raise NotImplementedError
2697db96d56Sopenharmony_ci
2707db96d56Sopenharmony_ci
2717db96d56Sopenharmony_ci@_extend_docstrings
2727db96d56Sopenharmony_ciclass Compat32(Policy):
2737db96d56Sopenharmony_ci
2747db96d56Sopenharmony_ci    """+
2757db96d56Sopenharmony_ci    This particular policy is the backward compatibility Policy.  It
2767db96d56Sopenharmony_ci    replicates the behavior of the email package version 5.1.
2777db96d56Sopenharmony_ci    """
2787db96d56Sopenharmony_ci
2797db96d56Sopenharmony_ci    mangle_from_ = True
2807db96d56Sopenharmony_ci
2817db96d56Sopenharmony_ci    def _sanitize_header(self, name, value):
2827db96d56Sopenharmony_ci        # If the header value contains surrogates, return a Header using
2837db96d56Sopenharmony_ci        # the unknown-8bit charset to encode the bytes as encoded words.
2847db96d56Sopenharmony_ci        if not isinstance(value, str):
2857db96d56Sopenharmony_ci            # Assume it is already a header object
2867db96d56Sopenharmony_ci            return value
2877db96d56Sopenharmony_ci        if _has_surrogates(value):
2887db96d56Sopenharmony_ci            return header.Header(value, charset=_charset.UNKNOWN8BIT,
2897db96d56Sopenharmony_ci                                 header_name=name)
2907db96d56Sopenharmony_ci        else:
2917db96d56Sopenharmony_ci            return value
2927db96d56Sopenharmony_ci
2937db96d56Sopenharmony_ci    def header_source_parse(self, sourcelines):
2947db96d56Sopenharmony_ci        """+
2957db96d56Sopenharmony_ci        The name is parsed as everything up to the ':' and returned unmodified.
2967db96d56Sopenharmony_ci        The value is determined by stripping leading whitespace off the
2977db96d56Sopenharmony_ci        remainder of the first line, joining all subsequent lines together, and
2987db96d56Sopenharmony_ci        stripping any trailing carriage return or linefeed characters.
2997db96d56Sopenharmony_ci
3007db96d56Sopenharmony_ci        """
3017db96d56Sopenharmony_ci        name, value = sourcelines[0].split(':', 1)
3027db96d56Sopenharmony_ci        value = value.lstrip(' \t') + ''.join(sourcelines[1:])
3037db96d56Sopenharmony_ci        return (name, value.rstrip('\r\n'))
3047db96d56Sopenharmony_ci
3057db96d56Sopenharmony_ci    def header_store_parse(self, name, value):
3067db96d56Sopenharmony_ci        """+
3077db96d56Sopenharmony_ci        The name and value are returned unmodified.
3087db96d56Sopenharmony_ci        """
3097db96d56Sopenharmony_ci        return (name, value)
3107db96d56Sopenharmony_ci
3117db96d56Sopenharmony_ci    def header_fetch_parse(self, name, value):
3127db96d56Sopenharmony_ci        """+
3137db96d56Sopenharmony_ci        If the value contains binary data, it is converted into a Header object
3147db96d56Sopenharmony_ci        using the unknown-8bit charset.  Otherwise it is returned unmodified.
3157db96d56Sopenharmony_ci        """
3167db96d56Sopenharmony_ci        return self._sanitize_header(name, value)
3177db96d56Sopenharmony_ci
3187db96d56Sopenharmony_ci    def fold(self, name, value):
3197db96d56Sopenharmony_ci        """+
3207db96d56Sopenharmony_ci        Headers are folded using the Header folding algorithm, which preserves
3217db96d56Sopenharmony_ci        existing line breaks in the value, and wraps each resulting line to the
3227db96d56Sopenharmony_ci        max_line_length.  Non-ASCII binary data are CTE encoded using the
3237db96d56Sopenharmony_ci        unknown-8bit charset.
3247db96d56Sopenharmony_ci
3257db96d56Sopenharmony_ci        """
3267db96d56Sopenharmony_ci        return self._fold(name, value, sanitize=True)
3277db96d56Sopenharmony_ci
3287db96d56Sopenharmony_ci    def fold_binary(self, name, value):
3297db96d56Sopenharmony_ci        """+
3307db96d56Sopenharmony_ci        Headers are folded using the Header folding algorithm, which preserves
3317db96d56Sopenharmony_ci        existing line breaks in the value, and wraps each resulting line to the
3327db96d56Sopenharmony_ci        max_line_length.  If cte_type is 7bit, non-ascii binary data is CTE
3337db96d56Sopenharmony_ci        encoded using the unknown-8bit charset.  Otherwise the original source
3347db96d56Sopenharmony_ci        header is used, with its existing line breaks and/or binary data.
3357db96d56Sopenharmony_ci
3367db96d56Sopenharmony_ci        """
3377db96d56Sopenharmony_ci        folded = self._fold(name, value, sanitize=self.cte_type=='7bit')
3387db96d56Sopenharmony_ci        return folded.encode('ascii', 'surrogateescape')
3397db96d56Sopenharmony_ci
3407db96d56Sopenharmony_ci    def _fold(self, name, value, sanitize):
3417db96d56Sopenharmony_ci        parts = []
3427db96d56Sopenharmony_ci        parts.append('%s: ' % name)
3437db96d56Sopenharmony_ci        if isinstance(value, str):
3447db96d56Sopenharmony_ci            if _has_surrogates(value):
3457db96d56Sopenharmony_ci                if sanitize:
3467db96d56Sopenharmony_ci                    h = header.Header(value,
3477db96d56Sopenharmony_ci                                      charset=_charset.UNKNOWN8BIT,
3487db96d56Sopenharmony_ci                                      header_name=name)
3497db96d56Sopenharmony_ci                else:
3507db96d56Sopenharmony_ci                    # If we have raw 8bit data in a byte string, we have no idea
3517db96d56Sopenharmony_ci                    # what the encoding is.  There is no safe way to split this
3527db96d56Sopenharmony_ci                    # string.  If it's ascii-subset, then we could do a normal
3537db96d56Sopenharmony_ci                    # ascii split, but if it's multibyte then we could break the
3547db96d56Sopenharmony_ci                    # string.  There's no way to know so the least harm seems to
3557db96d56Sopenharmony_ci                    # be to not split the string and risk it being too long.
3567db96d56Sopenharmony_ci                    parts.append(value)
3577db96d56Sopenharmony_ci                    h = None
3587db96d56Sopenharmony_ci            else:
3597db96d56Sopenharmony_ci                h = header.Header(value, header_name=name)
3607db96d56Sopenharmony_ci        else:
3617db96d56Sopenharmony_ci            # Assume it is a Header-like object.
3627db96d56Sopenharmony_ci            h = value
3637db96d56Sopenharmony_ci        if h is not None:
3647db96d56Sopenharmony_ci            # The Header class interprets a value of None for maxlinelen as the
3657db96d56Sopenharmony_ci            # default value of 78, as recommended by RFC 2822.
3667db96d56Sopenharmony_ci            maxlinelen = 0
3677db96d56Sopenharmony_ci            if self.max_line_length is not None:
3687db96d56Sopenharmony_ci                maxlinelen = self.max_line_length
3697db96d56Sopenharmony_ci            parts.append(h.encode(linesep=self.linesep, maxlinelen=maxlinelen))
3707db96d56Sopenharmony_ci        parts.append(self.linesep)
3717db96d56Sopenharmony_ci        return ''.join(parts)
3727db96d56Sopenharmony_ci
3737db96d56Sopenharmony_ci
3747db96d56Sopenharmony_cicompat32 = Compat32()
375