ยปCore Development>Code coverage>Lib/email/policy.py

Python code coverage for Lib/email/policy.py

#countcontent
1n/a"""This will be the home for the policy that hooks in the new
2n/acode that adds all the email6 features.
3n/a"""
4n/a
5n/aimport re
6n/afrom email._policybase import Policy, Compat32, compat32, _extend_docstrings
7n/afrom email.utils import _has_surrogates
8n/afrom email.headerregistry import HeaderRegistry as HeaderRegistry
9n/afrom email.contentmanager import raw_data_manager
10n/afrom email.message import EmailMessage
11n/a
12n/a__all__ = [
13n/a 'Compat32',
14n/a 'compat32',
15n/a 'Policy',
16n/a 'EmailPolicy',
17n/a 'default',
18n/a 'strict',
19n/a 'SMTP',
20n/a 'HTTP',
21n/a ]
22n/a
23n/alinesep_splitter = re.compile(r'\n|\r')
24n/a
25n/a@_extend_docstrings
26n/aclass EmailPolicy(Policy):
27n/a
28n/a """+
29n/a PROVISIONAL
30n/a
31n/a The API extensions enabled by this policy are currently provisional.
32n/a Refer to the documentation for details.
33n/a
34n/a This policy adds new header parsing and folding algorithms. Instead of
35n/a simple strings, headers are custom objects with custom attributes
36n/a depending on the type of the field. The folding algorithm fully
37n/a implements RFCs 2047 and 5322.
38n/a
39n/a In addition to the settable attributes listed above that apply to
40n/a all Policies, this policy adds the following additional attributes:
41n/a
42n/a utf8 -- if False (the default) message headers will be
43n/a serialized as ASCII, using encoded words to encode
44n/a any non-ASCII characters in the source strings. If
45n/a True, the message headers will be serialized using
46n/a utf8 and will not contain encoded words (see RFC
47n/a 6532 for more on this serialization format).
48n/a
49n/a refold_source -- if the value for a header in the Message object
50n/a came from the parsing of some source, this attribute
51n/a indicates whether or not a generator should refold
52n/a that value when transforming the message back into
53n/a stream form. The possible values are:
54n/a
55n/a none -- all source values use original folding
56n/a long -- source values that have any line that is
57n/a longer than max_line_length will be
58n/a refolded
59n/a all -- all values are refolded.
60n/a
61n/a The default is 'long'.
62n/a
63n/a header_factory -- a callable that takes two arguments, 'name' and
64n/a 'value', where 'name' is a header field name and
65n/a 'value' is an unfolded header field value, and
66n/a returns a string-like object that represents that
67n/a header. A default header_factory is provided that
68n/a understands some of the RFC5322 header field types.
69n/a (Currently address fields and date fields have
70n/a special treatment, while all other fields are
71n/a treated as unstructured. This list will be
72n/a completed before the extension is marked stable.)
73n/a
74n/a content_manager -- an object with at least two methods: get_content
75n/a and set_content. When the get_content or
76n/a set_content method of a Message object is called,
77n/a it calls the corresponding method of this object,
78n/a passing it the message object as its first argument,
79n/a and any arguments or keywords that were passed to
80n/a it as additional arguments. The default
81n/a content_manager is
82n/a :data:`~email.contentmanager.raw_data_manager`.
83n/a
84n/a """
85n/a
86n/a message_factory = EmailMessage
87n/a utf8 = False
88n/a refold_source = 'long'
89n/a header_factory = HeaderRegistry()
90n/a content_manager = raw_data_manager
91n/a
92n/a def __init__(self, **kw):
93n/a # Ensure that each new instance gets a unique header factory
94n/a # (as opposed to clones, which share the factory).
95n/a if 'header_factory' not in kw:
96n/a object.__setattr__(self, 'header_factory', HeaderRegistry())
97n/a super().__init__(**kw)
98n/a
99n/a def header_max_count(self, name):
100n/a """+
101n/a The implementation for this class returns the max_count attribute from
102n/a the specialized header class that would be used to construct a header
103n/a of type 'name'.
104n/a """
105n/a return self.header_factory[name].max_count
106n/a
107n/a # The logic of the next three methods is chosen such that it is possible to
108n/a # switch a Message object between a Compat32 policy and a policy derived
109n/a # from this class and have the results stay consistent. This allows a
110n/a # Message object constructed with this policy to be passed to a library
111n/a # that only handles Compat32 objects, or to receive such an object and
112n/a # convert it to use the newer style by just changing its policy. It is
113n/a # also chosen because it postpones the relatively expensive full rfc5322
114n/a # parse until as late as possible when parsing from source, since in many
115n/a # applications only a few headers will actually be inspected.
116n/a
117n/a def header_source_parse(self, sourcelines):
118n/a """+
119n/a The name is parsed as everything up to the ':' and returned unmodified.
120n/a The value is determined by stripping leading whitespace off the
121n/a remainder of the first line, joining all subsequent lines together, and
122n/a stripping any trailing carriage return or linefeed characters. (This
123n/a is the same as Compat32).
124n/a
125n/a """
126n/a name, value = sourcelines[0].split(':', 1)
127n/a value = value.lstrip(' \t') + ''.join(sourcelines[1:])
128n/a return (name, value.rstrip('\r\n'))
129n/a
130n/a def header_store_parse(self, name, value):
131n/a """+
132n/a The name is returned unchanged. If the input value has a 'name'
133n/a attribute and it matches the name ignoring case, the value is returned
134n/a unchanged. Otherwise the name and value are passed to header_factory
135n/a method, and the resulting custom header object is returned as the
136n/a value. In this case a ValueError is raised if the input value contains
137n/a CR or LF characters.
138n/a
139n/a """
140n/a if hasattr(value, 'name') and value.name.lower() == name.lower():
141n/a return (name, value)
142n/a if isinstance(value, str) and len(value.splitlines())>1:
143n/a # XXX this error message isn't quite right when we use splitlines
144n/a # (see issue 22233), but I'm not sure what should happen here.
145n/a raise ValueError("Header values may not contain linefeed "
146n/a "or carriage return characters")
147n/a return (name, self.header_factory(name, value))
148n/a
149n/a def header_fetch_parse(self, name, value):
150n/a """+
151n/a If the value has a 'name' attribute, it is returned to unmodified.
152n/a Otherwise the name and the value with any linesep characters removed
153n/a are passed to the header_factory method, and the resulting custom
154n/a header object is returned. Any surrogateescaped bytes get turned
155n/a into the unicode unknown-character glyph.
156n/a
157n/a """
158n/a if hasattr(value, 'name'):
159n/a return value
160n/a # We can't use splitlines here because it splits on more than \r and \n.
161n/a value = ''.join(linesep_splitter.split(value))
162n/a return self.header_factory(name, value)
163n/a
164n/a def fold(self, name, value):
165n/a """+
166n/a Header folding is controlled by the refold_source policy setting. A
167n/a value is considered to be a 'source value' if and only if it does not
168n/a have a 'name' attribute (having a 'name' attribute means it is a header
169n/a object of some sort). If a source value needs to be refolded according
170n/a to the policy, it is converted into a custom header object by passing
171n/a the name and the value with any linesep characters removed to the
172n/a header_factory method. Folding of a custom header object is done by
173n/a calling its fold method with the current policy.
174n/a
175n/a Source values are split into lines using splitlines. If the value is
176n/a not to be refolded, the lines are rejoined using the linesep from the
177n/a policy and returned. The exception is lines containing non-ascii
178n/a binary data. In that case the value is refolded regardless of the
179n/a refold_source setting, which causes the binary data to be CTE encoded
180n/a using the unknown-8bit charset.
181n/a
182n/a """
183n/a return self._fold(name, value, refold_binary=True)
184n/a
185n/a def fold_binary(self, name, value):
186n/a """+
187n/a The same as fold if cte_type is 7bit, except that the returned value is
188n/a bytes.
189n/a
190n/a If cte_type is 8bit, non-ASCII binary data is converted back into
191n/a bytes. Headers with binary data are not refolded, regardless of the
192n/a refold_header setting, since there is no way to know whether the binary
193n/a data consists of single byte characters or multibyte characters.
194n/a
195n/a If utf8 is true, headers are encoded to utf8, otherwise to ascii with
196n/a non-ASCII unicode rendered as encoded words.
197n/a
198n/a """
199n/a folded = self._fold(name, value, refold_binary=self.cte_type=='7bit')
200n/a charset = 'utf8' if self.utf8 else 'ascii'
201n/a return folded.encode(charset, 'surrogateescape')
202n/a
203n/a def _fold(self, name, value, refold_binary=False):
204n/a if hasattr(value, 'name'):
205n/a return value.fold(policy=self)
206n/a maxlen = self.max_line_length if self.max_line_length else float('inf')
207n/a lines = value.splitlines()
208n/a refold = (self.refold_source == 'all' or
209n/a self.refold_source == 'long' and
210n/a (lines and len(lines[0])+len(name)+2 > maxlen or
211n/a any(len(x) > maxlen for x in lines[1:])))
212n/a if refold or refold_binary and _has_surrogates(value):
213n/a return self.header_factory(name, ''.join(lines)).fold(policy=self)
214n/a return name + ': ' + self.linesep.join(lines) + self.linesep
215n/a
216n/a
217n/adefault = EmailPolicy()
218n/a# Make the default policy use the class default header_factory
219n/adel default.header_factory
220n/astrict = default.clone(raise_on_defect=True)
221n/aSMTP = default.clone(linesep='\r\n')
222n/aHTTP = default.clone(linesep='\r\n', max_line_length=None)
223n/aSMTPUTF8 = SMTP.clone(utf8=True)