xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/email/_policybase.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker"""Policy framework for the email package.
2*cda5da8dSAndroid Build Coastguard Worker
3*cda5da8dSAndroid Build Coastguard WorkerAllows fine grained feature control of how the package parses and emits data.
4*cda5da8dSAndroid Build Coastguard Worker"""
5*cda5da8dSAndroid Build Coastguard Worker
6*cda5da8dSAndroid Build Coastguard Workerimport abc
7*cda5da8dSAndroid Build Coastguard Workerfrom email import header
8*cda5da8dSAndroid Build Coastguard Workerfrom email import charset as _charset
9*cda5da8dSAndroid Build Coastguard Workerfrom email.utils import _has_surrogates
10*cda5da8dSAndroid Build Coastguard Worker
11*cda5da8dSAndroid Build Coastguard Worker__all__ = [
12*cda5da8dSAndroid Build Coastguard Worker    'Policy',
13*cda5da8dSAndroid Build Coastguard Worker    'Compat32',
14*cda5da8dSAndroid Build Coastguard Worker    'compat32',
15*cda5da8dSAndroid Build Coastguard Worker    ]
16*cda5da8dSAndroid Build Coastguard Worker
17*cda5da8dSAndroid Build Coastguard Worker
18*cda5da8dSAndroid Build Coastguard Workerclass _PolicyBase:
19*cda5da8dSAndroid Build Coastguard Worker
20*cda5da8dSAndroid Build Coastguard Worker    """Policy Object basic framework.
21*cda5da8dSAndroid Build Coastguard Worker
22*cda5da8dSAndroid Build Coastguard Worker    This class is useless unless subclassed.  A subclass should define
23*cda5da8dSAndroid Build Coastguard Worker    class attributes with defaults for any values that are to be
24*cda5da8dSAndroid Build Coastguard Worker    managed by the Policy object.  The constructor will then allow
25*cda5da8dSAndroid Build Coastguard Worker    non-default values to be set for these attributes at instance
26*cda5da8dSAndroid Build Coastguard Worker    creation time.  The instance will be callable, taking these same
27*cda5da8dSAndroid Build Coastguard Worker    attributes keyword arguments, and returning a new instance
28*cda5da8dSAndroid Build Coastguard Worker    identical to the called instance except for those values changed
29*cda5da8dSAndroid Build Coastguard Worker    by the keyword arguments.  Instances may be added, yielding new
30*cda5da8dSAndroid Build Coastguard Worker    instances with any non-default values from the right hand
31*cda5da8dSAndroid Build Coastguard Worker    operand overriding those in the left hand operand.  That is,
32*cda5da8dSAndroid Build Coastguard Worker
33*cda5da8dSAndroid Build Coastguard Worker        A + B == A(<non-default values of B>)
34*cda5da8dSAndroid Build Coastguard Worker
35*cda5da8dSAndroid Build Coastguard Worker    The repr of an instance can be used to reconstruct the object
36*cda5da8dSAndroid Build Coastguard Worker    if and only if the repr of the values can be used to reconstruct
37*cda5da8dSAndroid Build Coastguard Worker    those values.
38*cda5da8dSAndroid Build Coastguard Worker
39*cda5da8dSAndroid Build Coastguard Worker    """
40*cda5da8dSAndroid Build Coastguard Worker
41*cda5da8dSAndroid Build Coastguard Worker    def __init__(self, **kw):
42*cda5da8dSAndroid Build Coastguard Worker        """Create new Policy, possibly overriding some defaults.
43*cda5da8dSAndroid Build Coastguard Worker
44*cda5da8dSAndroid Build Coastguard Worker        See class docstring for a list of overridable attributes.
45*cda5da8dSAndroid Build Coastguard Worker
46*cda5da8dSAndroid Build Coastguard Worker        """
47*cda5da8dSAndroid Build Coastguard Worker        for name, value in kw.items():
48*cda5da8dSAndroid Build Coastguard Worker            if hasattr(self, name):
49*cda5da8dSAndroid Build Coastguard Worker                super(_PolicyBase,self).__setattr__(name, value)
50*cda5da8dSAndroid Build Coastguard Worker            else:
51*cda5da8dSAndroid Build Coastguard Worker                raise TypeError(
52*cda5da8dSAndroid Build Coastguard Worker                    "{!r} is an invalid keyword argument for {}".format(
53*cda5da8dSAndroid Build Coastguard Worker                        name, self.__class__.__name__))
54*cda5da8dSAndroid Build Coastguard Worker
55*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
56*cda5da8dSAndroid Build Coastguard Worker        args = [ "{}={!r}".format(name, value)
57*cda5da8dSAndroid Build Coastguard Worker                 for name, value in self.__dict__.items() ]
58*cda5da8dSAndroid Build Coastguard Worker        return "{}({})".format(self.__class__.__name__, ', '.join(args))
59*cda5da8dSAndroid Build Coastguard Worker
60*cda5da8dSAndroid Build Coastguard Worker    def clone(self, **kw):
61*cda5da8dSAndroid Build Coastguard Worker        """Return a new instance with specified attributes changed.
62*cda5da8dSAndroid Build Coastguard Worker
63*cda5da8dSAndroid Build Coastguard Worker        The new instance has the same attribute values as the current object,
64*cda5da8dSAndroid Build Coastguard Worker        except for the changes passed in as keyword arguments.
65*cda5da8dSAndroid Build Coastguard Worker
66*cda5da8dSAndroid Build Coastguard Worker        """
67*cda5da8dSAndroid Build Coastguard Worker        newpolicy = self.__class__.__new__(self.__class__)
68*cda5da8dSAndroid Build Coastguard Worker        for attr, value in self.__dict__.items():
69*cda5da8dSAndroid Build Coastguard Worker            object.__setattr__(newpolicy, attr, value)
70*cda5da8dSAndroid Build Coastguard Worker        for attr, value in kw.items():
71*cda5da8dSAndroid Build Coastguard Worker            if not hasattr(self, attr):
72*cda5da8dSAndroid Build Coastguard Worker                raise TypeError(
73*cda5da8dSAndroid Build Coastguard Worker                    "{!r} is an invalid keyword argument for {}".format(
74*cda5da8dSAndroid Build Coastguard Worker                        attr, self.__class__.__name__))
75*cda5da8dSAndroid Build Coastguard Worker            object.__setattr__(newpolicy, attr, value)
76*cda5da8dSAndroid Build Coastguard Worker        return newpolicy
77*cda5da8dSAndroid Build Coastguard Worker
78*cda5da8dSAndroid Build Coastguard Worker    def __setattr__(self, name, value):
79*cda5da8dSAndroid Build Coastguard Worker        if hasattr(self, name):
80*cda5da8dSAndroid Build Coastguard Worker            msg = "{!r} object attribute {!r} is read-only"
81*cda5da8dSAndroid Build Coastguard Worker        else:
82*cda5da8dSAndroid Build Coastguard Worker            msg = "{!r} object has no attribute {!r}"
83*cda5da8dSAndroid Build Coastguard Worker        raise AttributeError(msg.format(self.__class__.__name__, name))
84*cda5da8dSAndroid Build Coastguard Worker
85*cda5da8dSAndroid Build Coastguard Worker    def __add__(self, other):
86*cda5da8dSAndroid Build Coastguard Worker        """Non-default values from right operand override those from left.
87*cda5da8dSAndroid Build Coastguard Worker
88*cda5da8dSAndroid Build Coastguard Worker        The object returned is a new instance of the subclass.
89*cda5da8dSAndroid Build Coastguard Worker
90*cda5da8dSAndroid Build Coastguard Worker        """
91*cda5da8dSAndroid Build Coastguard Worker        return self.clone(**other.__dict__)
92*cda5da8dSAndroid Build Coastguard Worker
93*cda5da8dSAndroid Build Coastguard Worker
94*cda5da8dSAndroid Build Coastguard Workerdef _append_doc(doc, added_doc):
95*cda5da8dSAndroid Build Coastguard Worker    doc = doc.rsplit('\n', 1)[0]
96*cda5da8dSAndroid Build Coastguard Worker    added_doc = added_doc.split('\n', 1)[1]
97*cda5da8dSAndroid Build Coastguard Worker    return doc + '\n' + added_doc
98*cda5da8dSAndroid Build Coastguard Worker
99*cda5da8dSAndroid Build Coastguard Workerdef _extend_docstrings(cls):
100*cda5da8dSAndroid Build Coastguard Worker    if cls.__doc__ and cls.__doc__.startswith('+'):
101*cda5da8dSAndroid Build Coastguard Worker        cls.__doc__ = _append_doc(cls.__bases__[0].__doc__, cls.__doc__)
102*cda5da8dSAndroid Build Coastguard Worker    for name, attr in cls.__dict__.items():
103*cda5da8dSAndroid Build Coastguard Worker        if attr.__doc__ and attr.__doc__.startswith('+'):
104*cda5da8dSAndroid Build Coastguard Worker            for c in (c for base in cls.__bases__ for c in base.mro()):
105*cda5da8dSAndroid Build Coastguard Worker                doc = getattr(getattr(c, name), '__doc__')
106*cda5da8dSAndroid Build Coastguard Worker                if doc:
107*cda5da8dSAndroid Build Coastguard Worker                    attr.__doc__ = _append_doc(doc, attr.__doc__)
108*cda5da8dSAndroid Build Coastguard Worker                    break
109*cda5da8dSAndroid Build Coastguard Worker    return cls
110*cda5da8dSAndroid Build Coastguard Worker
111*cda5da8dSAndroid Build Coastguard Worker
112*cda5da8dSAndroid Build Coastguard Workerclass Policy(_PolicyBase, metaclass=abc.ABCMeta):
113*cda5da8dSAndroid Build Coastguard Worker
114*cda5da8dSAndroid Build Coastguard Worker    r"""Controls for how messages are interpreted and formatted.
115*cda5da8dSAndroid Build Coastguard Worker
116*cda5da8dSAndroid Build Coastguard Worker    Most of the classes and many of the methods in the email package accept
117*cda5da8dSAndroid Build Coastguard Worker    Policy objects as parameters.  A Policy object contains a set of values and
118*cda5da8dSAndroid Build Coastguard Worker    functions that control how input is interpreted and how output is rendered.
119*cda5da8dSAndroid Build Coastguard Worker    For example, the parameter 'raise_on_defect' controls whether or not an RFC
120*cda5da8dSAndroid Build Coastguard Worker    violation results in an error being raised or not, while 'max_line_length'
121*cda5da8dSAndroid Build Coastguard Worker    controls the maximum length of output lines when a Message is serialized.
122*cda5da8dSAndroid Build Coastguard Worker
123*cda5da8dSAndroid Build Coastguard Worker    Any valid attribute may be overridden when a Policy is created by passing
124*cda5da8dSAndroid Build Coastguard Worker    it as a keyword argument to the constructor.  Policy objects are immutable,
125*cda5da8dSAndroid Build Coastguard Worker    but a new Policy object can be created with only certain values changed by
126*cda5da8dSAndroid Build Coastguard Worker    calling the Policy instance with keyword arguments.  Policy objects can
127*cda5da8dSAndroid Build Coastguard Worker    also be added, producing a new Policy object in which the non-default
128*cda5da8dSAndroid Build Coastguard Worker    attributes set in the right hand operand overwrite those specified in the
129*cda5da8dSAndroid Build Coastguard Worker    left operand.
130*cda5da8dSAndroid Build Coastguard Worker
131*cda5da8dSAndroid Build Coastguard Worker    Settable attributes:
132*cda5da8dSAndroid Build Coastguard Worker
133*cda5da8dSAndroid Build Coastguard Worker    raise_on_defect     -- If true, then defects should be raised as errors.
134*cda5da8dSAndroid Build Coastguard Worker                           Default: False.
135*cda5da8dSAndroid Build Coastguard Worker
136*cda5da8dSAndroid Build Coastguard Worker    linesep             -- string containing the value to use as separation
137*cda5da8dSAndroid Build Coastguard Worker                           between output lines.  Default '\n'.
138*cda5da8dSAndroid Build Coastguard Worker
139*cda5da8dSAndroid Build Coastguard Worker    cte_type            -- Type of allowed content transfer encodings
140*cda5da8dSAndroid Build Coastguard Worker
141*cda5da8dSAndroid Build Coastguard Worker                           7bit  -- ASCII only
142*cda5da8dSAndroid Build Coastguard Worker                           8bit  -- Content-Transfer-Encoding: 8bit is allowed
143*cda5da8dSAndroid Build Coastguard Worker
144*cda5da8dSAndroid Build Coastguard Worker                           Default: 8bit.  Also controls the disposition of
145*cda5da8dSAndroid Build Coastguard Worker                           (RFC invalid) binary data in headers; see the
146*cda5da8dSAndroid Build Coastguard Worker                           documentation of the binary_fold method.
147*cda5da8dSAndroid Build Coastguard Worker
148*cda5da8dSAndroid Build Coastguard Worker    max_line_length     -- maximum length of lines, excluding 'linesep',
149*cda5da8dSAndroid Build Coastguard Worker                           during serialization.  None or 0 means no line
150*cda5da8dSAndroid Build Coastguard Worker                           wrapping is done.  Default is 78.
151*cda5da8dSAndroid Build Coastguard Worker
152*cda5da8dSAndroid Build Coastguard Worker    mangle_from_        -- a flag that, when True escapes From_ lines in the
153*cda5da8dSAndroid Build Coastguard Worker                           body of the message by putting a `>' in front of
154*cda5da8dSAndroid Build Coastguard Worker                           them. This is used when the message is being
155*cda5da8dSAndroid Build Coastguard Worker                           serialized by a generator. Default: True.
156*cda5da8dSAndroid Build Coastguard Worker
157*cda5da8dSAndroid Build Coastguard Worker    message_factory     -- the class to use to create new message objects.
158*cda5da8dSAndroid Build Coastguard Worker                           If the value is None, the default is Message.
159*cda5da8dSAndroid Build Coastguard Worker
160*cda5da8dSAndroid Build Coastguard Worker    """
161*cda5da8dSAndroid Build Coastguard Worker
162*cda5da8dSAndroid Build Coastguard Worker    raise_on_defect = False
163*cda5da8dSAndroid Build Coastguard Worker    linesep = '\n'
164*cda5da8dSAndroid Build Coastguard Worker    cte_type = '8bit'
165*cda5da8dSAndroid Build Coastguard Worker    max_line_length = 78
166*cda5da8dSAndroid Build Coastguard Worker    mangle_from_ = False
167*cda5da8dSAndroid Build Coastguard Worker    message_factory = None
168*cda5da8dSAndroid Build Coastguard Worker
169*cda5da8dSAndroid Build Coastguard Worker    def handle_defect(self, obj, defect):
170*cda5da8dSAndroid Build Coastguard Worker        """Based on policy, either raise defect or call register_defect.
171*cda5da8dSAndroid Build Coastguard Worker
172*cda5da8dSAndroid Build Coastguard Worker            handle_defect(obj, defect)
173*cda5da8dSAndroid Build Coastguard Worker
174*cda5da8dSAndroid Build Coastguard Worker        defect should be a Defect subclass, but in any case must be an
175*cda5da8dSAndroid Build Coastguard Worker        Exception subclass.  obj is the object on which the defect should be
176*cda5da8dSAndroid Build Coastguard Worker        registered if it is not raised.  If the raise_on_defect is True, the
177*cda5da8dSAndroid Build Coastguard Worker        defect is raised as an error, otherwise the object and the defect are
178*cda5da8dSAndroid Build Coastguard Worker        passed to register_defect.
179*cda5da8dSAndroid Build Coastguard Worker
180*cda5da8dSAndroid Build Coastguard Worker        This method is intended to be called by parsers that discover defects.
181*cda5da8dSAndroid Build Coastguard Worker        The email package parsers always call it with Defect instances.
182*cda5da8dSAndroid Build Coastguard Worker
183*cda5da8dSAndroid Build Coastguard Worker        """
184*cda5da8dSAndroid Build Coastguard Worker        if self.raise_on_defect:
185*cda5da8dSAndroid Build Coastguard Worker            raise defect
186*cda5da8dSAndroid Build Coastguard Worker        self.register_defect(obj, defect)
187*cda5da8dSAndroid Build Coastguard Worker
188*cda5da8dSAndroid Build Coastguard Worker    def register_defect(self, obj, defect):
189*cda5da8dSAndroid Build Coastguard Worker        """Record 'defect' on 'obj'.
190*cda5da8dSAndroid Build Coastguard Worker
191*cda5da8dSAndroid Build Coastguard Worker        Called by handle_defect if raise_on_defect is False.  This method is
192*cda5da8dSAndroid Build Coastguard Worker        part of the Policy API so that Policy subclasses can implement custom
193*cda5da8dSAndroid Build Coastguard Worker        defect handling.  The default implementation calls the append method of
194*cda5da8dSAndroid Build Coastguard Worker        the defects attribute of obj.  The objects used by the email package by
195*cda5da8dSAndroid Build Coastguard Worker        default that get passed to this method will always have a defects
196*cda5da8dSAndroid Build Coastguard Worker        attribute with an append method.
197*cda5da8dSAndroid Build Coastguard Worker
198*cda5da8dSAndroid Build Coastguard Worker        """
199*cda5da8dSAndroid Build Coastguard Worker        obj.defects.append(defect)
200*cda5da8dSAndroid Build Coastguard Worker
201*cda5da8dSAndroid Build Coastguard Worker    def header_max_count(self, name):
202*cda5da8dSAndroid Build Coastguard Worker        """Return the maximum allowed number of headers named 'name'.
203*cda5da8dSAndroid Build Coastguard Worker
204*cda5da8dSAndroid Build Coastguard Worker        Called when a header is added to a Message object.  If the returned
205*cda5da8dSAndroid Build Coastguard Worker        value is not 0 or None, and there are already a number of headers with
206*cda5da8dSAndroid Build Coastguard Worker        the name 'name' equal to the value returned, a ValueError is raised.
207*cda5da8dSAndroid Build Coastguard Worker
208*cda5da8dSAndroid Build Coastguard Worker        Because the default behavior of Message's __setitem__ is to append the
209*cda5da8dSAndroid Build Coastguard Worker        value to the list of headers, it is easy to create duplicate headers
210*cda5da8dSAndroid Build Coastguard Worker        without realizing it.  This method allows certain headers to be limited
211*cda5da8dSAndroid Build Coastguard Worker        in the number of instances of that header that may be added to a
212*cda5da8dSAndroid Build Coastguard Worker        Message programmatically.  (The limit is not observed by the parser,
213*cda5da8dSAndroid Build Coastguard Worker        which will faithfully produce as many headers as exist in the message
214*cda5da8dSAndroid Build Coastguard Worker        being parsed.)
215*cda5da8dSAndroid Build Coastguard Worker
216*cda5da8dSAndroid Build Coastguard Worker        The default implementation returns None for all header names.
217*cda5da8dSAndroid Build Coastguard Worker        """
218*cda5da8dSAndroid Build Coastguard Worker        return None
219*cda5da8dSAndroid Build Coastguard Worker
220*cda5da8dSAndroid Build Coastguard Worker    @abc.abstractmethod
221*cda5da8dSAndroid Build Coastguard Worker    def header_source_parse(self, sourcelines):
222*cda5da8dSAndroid Build Coastguard Worker        """Given a list of linesep terminated strings constituting the lines of
223*cda5da8dSAndroid Build Coastguard Worker        a single header, return the (name, value) tuple that should be stored
224*cda5da8dSAndroid Build Coastguard Worker        in the model.  The input lines should retain their terminating linesep
225*cda5da8dSAndroid Build Coastguard Worker        characters.  The lines passed in by the email package may contain
226*cda5da8dSAndroid Build Coastguard Worker        surrogateescaped binary data.
227*cda5da8dSAndroid Build Coastguard Worker        """
228*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError
229*cda5da8dSAndroid Build Coastguard Worker
230*cda5da8dSAndroid Build Coastguard Worker    @abc.abstractmethod
231*cda5da8dSAndroid Build Coastguard Worker    def header_store_parse(self, name, value):
232*cda5da8dSAndroid Build Coastguard Worker        """Given the header name and the value provided by the application
233*cda5da8dSAndroid Build Coastguard Worker        program, return the (name, value) that should be stored in the model.
234*cda5da8dSAndroid Build Coastguard Worker        """
235*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError
236*cda5da8dSAndroid Build Coastguard Worker
237*cda5da8dSAndroid Build Coastguard Worker    @abc.abstractmethod
238*cda5da8dSAndroid Build Coastguard Worker    def header_fetch_parse(self, name, value):
239*cda5da8dSAndroid Build Coastguard Worker        """Given the header name and the value from the model, return the value
240*cda5da8dSAndroid Build Coastguard Worker        to be returned to the application program that is requesting that
241*cda5da8dSAndroid Build Coastguard Worker        header.  The value passed in by the email package may contain
242*cda5da8dSAndroid Build Coastguard Worker        surrogateescaped binary data if the lines were parsed by a BytesParser.
243*cda5da8dSAndroid Build Coastguard Worker        The returned value should not contain any surrogateescaped data.
244*cda5da8dSAndroid Build Coastguard Worker
245*cda5da8dSAndroid Build Coastguard Worker        """
246*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError
247*cda5da8dSAndroid Build Coastguard Worker
248*cda5da8dSAndroid Build Coastguard Worker    @abc.abstractmethod
249*cda5da8dSAndroid Build Coastguard Worker    def fold(self, name, value):
250*cda5da8dSAndroid Build Coastguard Worker        """Given the header name and the value from the model, return a string
251*cda5da8dSAndroid Build Coastguard Worker        containing linesep characters that implement the folding of the header
252*cda5da8dSAndroid Build Coastguard Worker        according to the policy controls.  The value passed in by the email
253*cda5da8dSAndroid Build Coastguard Worker        package may contain surrogateescaped binary data if the lines were
254*cda5da8dSAndroid Build Coastguard Worker        parsed by a BytesParser.  The returned value should not contain any
255*cda5da8dSAndroid Build Coastguard Worker        surrogateescaped data.
256*cda5da8dSAndroid Build Coastguard Worker
257*cda5da8dSAndroid Build Coastguard Worker        """
258*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError
259*cda5da8dSAndroid Build Coastguard Worker
260*cda5da8dSAndroid Build Coastguard Worker    @abc.abstractmethod
261*cda5da8dSAndroid Build Coastguard Worker    def fold_binary(self, name, value):
262*cda5da8dSAndroid Build Coastguard Worker        """Given the header name and the value from the model, return binary
263*cda5da8dSAndroid Build Coastguard Worker        data containing linesep characters that implement the folding of the
264*cda5da8dSAndroid Build Coastguard Worker        header according to the policy controls.  The value passed in by the
265*cda5da8dSAndroid Build Coastguard Worker        email package may contain surrogateescaped binary data.
266*cda5da8dSAndroid Build Coastguard Worker
267*cda5da8dSAndroid Build Coastguard Worker        """
268*cda5da8dSAndroid Build Coastguard Worker        raise NotImplementedError
269*cda5da8dSAndroid Build Coastguard Worker
270*cda5da8dSAndroid Build Coastguard Worker
271*cda5da8dSAndroid Build Coastguard Worker@_extend_docstrings
272*cda5da8dSAndroid Build Coastguard Workerclass Compat32(Policy):
273*cda5da8dSAndroid Build Coastguard Worker
274*cda5da8dSAndroid Build Coastguard Worker    """+
275*cda5da8dSAndroid Build Coastguard Worker    This particular policy is the backward compatibility Policy.  It
276*cda5da8dSAndroid Build Coastguard Worker    replicates the behavior of the email package version 5.1.
277*cda5da8dSAndroid Build Coastguard Worker    """
278*cda5da8dSAndroid Build Coastguard Worker
279*cda5da8dSAndroid Build Coastguard Worker    mangle_from_ = True
280*cda5da8dSAndroid Build Coastguard Worker
281*cda5da8dSAndroid Build Coastguard Worker    def _sanitize_header(self, name, value):
282*cda5da8dSAndroid Build Coastguard Worker        # If the header value contains surrogates, return a Header using
283*cda5da8dSAndroid Build Coastguard Worker        # the unknown-8bit charset to encode the bytes as encoded words.
284*cda5da8dSAndroid Build Coastguard Worker        if not isinstance(value, str):
285*cda5da8dSAndroid Build Coastguard Worker            # Assume it is already a header object
286*cda5da8dSAndroid Build Coastguard Worker            return value
287*cda5da8dSAndroid Build Coastguard Worker        if _has_surrogates(value):
288*cda5da8dSAndroid Build Coastguard Worker            return header.Header(value, charset=_charset.UNKNOWN8BIT,
289*cda5da8dSAndroid Build Coastguard Worker                                 header_name=name)
290*cda5da8dSAndroid Build Coastguard Worker        else:
291*cda5da8dSAndroid Build Coastguard Worker            return value
292*cda5da8dSAndroid Build Coastguard Worker
293*cda5da8dSAndroid Build Coastguard Worker    def header_source_parse(self, sourcelines):
294*cda5da8dSAndroid Build Coastguard Worker        """+
295*cda5da8dSAndroid Build Coastguard Worker        The name is parsed as everything up to the ':' and returned unmodified.
296*cda5da8dSAndroid Build Coastguard Worker        The value is determined by stripping leading whitespace off the
297*cda5da8dSAndroid Build Coastguard Worker        remainder of the first line, joining all subsequent lines together, and
298*cda5da8dSAndroid Build Coastguard Worker        stripping any trailing carriage return or linefeed characters.
299*cda5da8dSAndroid Build Coastguard Worker
300*cda5da8dSAndroid Build Coastguard Worker        """
301*cda5da8dSAndroid Build Coastguard Worker        name, value = sourcelines[0].split(':', 1)
302*cda5da8dSAndroid Build Coastguard Worker        value = value.lstrip(' \t') + ''.join(sourcelines[1:])
303*cda5da8dSAndroid Build Coastguard Worker        return (name, value.rstrip('\r\n'))
304*cda5da8dSAndroid Build Coastguard Worker
305*cda5da8dSAndroid Build Coastguard Worker    def header_store_parse(self, name, value):
306*cda5da8dSAndroid Build Coastguard Worker        """+
307*cda5da8dSAndroid Build Coastguard Worker        The name and value are returned unmodified.
308*cda5da8dSAndroid Build Coastguard Worker        """
309*cda5da8dSAndroid Build Coastguard Worker        return (name, value)
310*cda5da8dSAndroid Build Coastguard Worker
311*cda5da8dSAndroid Build Coastguard Worker    def header_fetch_parse(self, name, value):
312*cda5da8dSAndroid Build Coastguard Worker        """+
313*cda5da8dSAndroid Build Coastguard Worker        If the value contains binary data, it is converted into a Header object
314*cda5da8dSAndroid Build Coastguard Worker        using the unknown-8bit charset.  Otherwise it is returned unmodified.
315*cda5da8dSAndroid Build Coastguard Worker        """
316*cda5da8dSAndroid Build Coastguard Worker        return self._sanitize_header(name, value)
317*cda5da8dSAndroid Build Coastguard Worker
318*cda5da8dSAndroid Build Coastguard Worker    def fold(self, name, value):
319*cda5da8dSAndroid Build Coastguard Worker        """+
320*cda5da8dSAndroid Build Coastguard Worker        Headers are folded using the Header folding algorithm, which preserves
321*cda5da8dSAndroid Build Coastguard Worker        existing line breaks in the value, and wraps each resulting line to the
322*cda5da8dSAndroid Build Coastguard Worker        max_line_length.  Non-ASCII binary data are CTE encoded using the
323*cda5da8dSAndroid Build Coastguard Worker        unknown-8bit charset.
324*cda5da8dSAndroid Build Coastguard Worker
325*cda5da8dSAndroid Build Coastguard Worker        """
326*cda5da8dSAndroid Build Coastguard Worker        return self._fold(name, value, sanitize=True)
327*cda5da8dSAndroid Build Coastguard Worker
328*cda5da8dSAndroid Build Coastguard Worker    def fold_binary(self, name, value):
329*cda5da8dSAndroid Build Coastguard Worker        """+
330*cda5da8dSAndroid Build Coastguard Worker        Headers are folded using the Header folding algorithm, which preserves
331*cda5da8dSAndroid Build Coastguard Worker        existing line breaks in the value, and wraps each resulting line to the
332*cda5da8dSAndroid Build Coastguard Worker        max_line_length.  If cte_type is 7bit, non-ascii binary data is CTE
333*cda5da8dSAndroid Build Coastguard Worker        encoded using the unknown-8bit charset.  Otherwise the original source
334*cda5da8dSAndroid Build Coastguard Worker        header is used, with its existing line breaks and/or binary data.
335*cda5da8dSAndroid Build Coastguard Worker
336*cda5da8dSAndroid Build Coastguard Worker        """
337*cda5da8dSAndroid Build Coastguard Worker        folded = self._fold(name, value, sanitize=self.cte_type=='7bit')
338*cda5da8dSAndroid Build Coastguard Worker        return folded.encode('ascii', 'surrogateescape')
339*cda5da8dSAndroid Build Coastguard Worker
340*cda5da8dSAndroid Build Coastguard Worker    def _fold(self, name, value, sanitize):
341*cda5da8dSAndroid Build Coastguard Worker        parts = []
342*cda5da8dSAndroid Build Coastguard Worker        parts.append('%s: ' % name)
343*cda5da8dSAndroid Build Coastguard Worker        if isinstance(value, str):
344*cda5da8dSAndroid Build Coastguard Worker            if _has_surrogates(value):
345*cda5da8dSAndroid Build Coastguard Worker                if sanitize:
346*cda5da8dSAndroid Build Coastguard Worker                    h = header.Header(value,
347*cda5da8dSAndroid Build Coastguard Worker                                      charset=_charset.UNKNOWN8BIT,
348*cda5da8dSAndroid Build Coastguard Worker                                      header_name=name)
349*cda5da8dSAndroid Build Coastguard Worker                else:
350*cda5da8dSAndroid Build Coastguard Worker                    # If we have raw 8bit data in a byte string, we have no idea
351*cda5da8dSAndroid Build Coastguard Worker                    # what the encoding is.  There is no safe way to split this
352*cda5da8dSAndroid Build Coastguard Worker                    # string.  If it's ascii-subset, then we could do a normal
353*cda5da8dSAndroid Build Coastguard Worker                    # ascii split, but if it's multibyte then we could break the
354*cda5da8dSAndroid Build Coastguard Worker                    # string.  There's no way to know so the least harm seems to
355*cda5da8dSAndroid Build Coastguard Worker                    # be to not split the string and risk it being too long.
356*cda5da8dSAndroid Build Coastguard Worker                    parts.append(value)
357*cda5da8dSAndroid Build Coastguard Worker                    h = None
358*cda5da8dSAndroid Build Coastguard Worker            else:
359*cda5da8dSAndroid Build Coastguard Worker                h = header.Header(value, header_name=name)
360*cda5da8dSAndroid Build Coastguard Worker        else:
361*cda5da8dSAndroid Build Coastguard Worker            # Assume it is a Header-like object.
362*cda5da8dSAndroid Build Coastguard Worker            h = value
363*cda5da8dSAndroid Build Coastguard Worker        if h is not None:
364*cda5da8dSAndroid Build Coastguard Worker            # The Header class interprets a value of None for maxlinelen as the
365*cda5da8dSAndroid Build Coastguard Worker            # default value of 78, as recommended by RFC 2822.
366*cda5da8dSAndroid Build Coastguard Worker            maxlinelen = 0
367*cda5da8dSAndroid Build Coastguard Worker            if self.max_line_length is not None:
368*cda5da8dSAndroid Build Coastguard Worker                maxlinelen = self.max_line_length
369*cda5da8dSAndroid Build Coastguard Worker            parts.append(h.encode(linesep=self.linesep, maxlinelen=maxlinelen))
370*cda5da8dSAndroid Build Coastguard Worker        parts.append(self.linesep)
371*cda5da8dSAndroid Build Coastguard Worker        return ''.join(parts)
372*cda5da8dSAndroid Build Coastguard Worker
373*cda5da8dSAndroid Build Coastguard Worker
374*cda5da8dSAndroid Build Coastguard Workercompat32 = Compat32()
375