this will be the home for the policy that hooks in the new code that adds all the email6 features provisional the api extensions enabled by this policy are currently provisional refer to the documentation for details this policy adds new header parsing and folding algorithms instead of simple strings headers are custom objects with custom attributes depending on the type of the field the folding algorithm fully implements rfcs 2047 and 5322 in addition to the settable attributes listed above that apply to all policies this policy adds the following additional attributes utf8 if false the default message headers will be serialized as ascii using encoded words to encode any nonascii characters in the source strings if true the message headers will be serialized using utf8 and will not contain encoded words see rfc 6532 for more on this serialization format refoldsource if the value for a header in the message object came from the parsing of some source this attribute indicates whether or not a generator should refold that value when transforming the message back into stream form the possible values are none all source values use original folding long source values that have any line that is longer than maxlinelength will be refolded all all values are refolded the default is long headerfactory a callable that takes two arguments name and value where name is a header field name and value is an unfolded header field value and returns a stringlike object that represents that header a default headerfactory is provided that understands some of the rfc5322 header field types currently address fields and date fields have special treatment while all other fields are treated as unstructured this list will be completed before the extension is marked stable contentmanager an object with at least two methods getcontent and setcontent when the getcontent or setcontent method of a message object is called it calls the corresponding method of this object passing it the message object as its first argument and any arguments or keywords that were passed to it as additional arguments the default contentmanager is data email contentmanager rawdatamanager ensure that each new instance gets a unique header factory as opposed to clones which share the factory the implementation for this class returns the maxcount attribute from the specialized header class that would be used to construct a header of type name the logic of the next three methods is chosen such that it is possible to switch a message object between a compat32 policy and a policy derived from this class and have the results stay consistent this allows a message object constructed with this policy to be passed to a library that only handles compat32 objects or to receive such an object and convert it to use the newer style by just changing its policy it is also chosen because it postpones the relatively expensive full rfc5322 parse until as late as possible when parsing from source since in many applications only a few headers will actually be inspected the name is parsed as everything up to the and returned unmodified the value is determined by stripping leading whitespace off the remainder of the first line joining all subsequent lines together and stripping any trailing carriage return or linefeed characters this is the same as compat32 the name is returned unchanged if the input value has a name attribute and it matches the name ignoring case the value is returned unchanged otherwise the name and value are passed to headerfactory method and the resulting custom header object is returned as the value in this case a valueerror is raised if the input value contains cr or lf characters xxx this error message isn t quite right when we use splitlines see issue 22233 but i m not sure what should happen here if the value has a name attribute it is returned to unmodified otherwise the name and the value with any linesep characters removed are passed to the headerfactory method and the resulting custom header object is returned any surrogateescaped bytes get turned into the unicode unknowncharacter glyph we can t use splitlines here because it splits on more than r and n header folding is controlled by the refoldsource policy setting a value is considered to be a source value if and only if it does not have a name attribute having a name attribute means it is a header object of some sort if a source value needs to be refolded according to the policy it is converted into a custom header object by passing the name and the value with any linesep characters removed to the headerfactory method folding of a custom header object is done by calling its fold method with the current policy source values are split into lines using splitlines if the value is not to be refolded the lines are rejoined using the linesep from the policy and returned the exception is lines containing nonascii binary data in that case the value is refolded regardless of the refoldsource setting which causes the binary data to be cte encoded using the unknown8bit charset the same as fold if ctetype is 7bit except that the returned value is bytes if ctetype is 8bit nonascii binary data is converted back into bytes headers with binary data are not refolded regardless of the refoldheader setting since there is no way to know whether the binary data consists of single byte characters or multibyte characters if utf8 is true headers are encoded to utf8 otherwise to ascii with nonascii unicode rendered as encoded words make the default policy use the class default headerfactory provisional the api extensions enabled by this policy are currently provisional refer to the documentation for details this policy adds new header parsing and folding algorithms instead of simple strings headers are custom objects with custom attributes depending on the type of the field the folding algorithm fully implements rfcs 2047 and 5322 in addition to the settable attributes listed above that apply to all policies this policy adds the following additional attributes utf8 if false the default message headers will be serialized as ascii using encoded words to encode any non ascii characters in the source strings if true the message headers will be serialized using utf8 and will not contain encoded words see rfc 6532 for more on this serialization format refold_source if the value for a header in the message object came from the parsing of some source this attribute indicates whether or not a generator should refold that value when transforming the message back into stream form the possible values are none all source values use original folding long source values that have any line that is longer than max_line_length will be refolded all all values are refolded the default is long header_factory a callable that takes two arguments name and value where name is a header field name and value is an unfolded header field value and returns a string like object that represents that header a default header_factory is provided that understands some of the rfc5322 header field types currently address fields and date fields have special treatment while all other fields are treated as unstructured this list will be completed before the extension is marked stable content_manager an object with at least two methods get_content and set_content when the get_content or set_content method of a message object is called it calls the corresponding method of this object passing it the message object as its first argument and any arguments or keywords that were passed to it as additional arguments the default content_manager is data email contentmanager raw_data_manager ensure that each new instance gets a unique header factory as opposed to clones which share the factory the implementation for this class returns the max_count attribute from the specialized header class that would be used to construct a header of type name the logic of the next three methods is chosen such that it is possible to switch a message object between a compat32 policy and a policy derived from this class and have the results stay consistent this allows a message object constructed with this policy to be passed to a library that only handles compat32 objects or to receive such an object and convert it to use the newer style by just changing its policy it is also chosen because it postpones the relatively expensive full rfc5322 parse until as late as possible when parsing from source since in many applications only a few headers will actually be inspected the name is parsed as everything up to the and returned unmodified the value is determined by stripping leading whitespace off the remainder of the first line joining all subsequent lines together and stripping any trailing carriage return or linefeed characters this is the same as compat32 the name is returned unchanged if the input value has a name attribute and it matches the name ignoring case the value is returned unchanged otherwise the name and value are passed to header_factory method and the resulting custom header object is returned as the value in this case a valueerror is raised if the input value contains cr or lf characters xxx this error message isn t quite right when we use splitlines see issue 22233 but i m not sure what should happen here if the value has a name attribute it is returned to unmodified 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 we can t use splitlines here because it splits on more than r and n header folding is controlled by the refold_source policy setting a value is considered to be a source value if and only if it does not have a name attribute having a name attribute means it is a header object of some sort if a source value needs to be refolded according to the policy it is converted into a custom header object by passing the name and the value with any linesep characters removed to the header_factory method folding of a custom header object is done by calling its fold method with the current policy source values are split into lines using splitlines if the value is not to be refolded the lines are rejoined using the linesep from the policy and returned the exception is lines containing non ascii binary data in that case the value is refolded regardless of the refold_source setting which causes the binary data to be cte encoded using the unknown 8bit charset the same as fold if cte_type is 7bit except that the returned value is bytes if cte_type is 8bit non ascii binary data is converted back into bytes headers with binary data are not refolded regardless of the refold_header setting since there is no way to know whether the binary 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 make the default policy use the class default header_factory
import re
import sys
from email._policybase import Policy, Compat32, compat32, _extend_docstrings
from email.utils import _has_surrogates
from email.headerregistry import HeaderRegistry as HeaderRegistry
from email.contentmanager import raw_data_manager
from email.message import EmailMessage

__all__ = [
    'Compat32',
    'compat32',
    'Policy',
    'EmailPolicy',
    'default',
    'strict',
    'SMTP',
    'HTTP',
    ]

linesep_splitter = re.compile(r'\n|\r')

@_extend_docstrings
class EmailPolicy(Policy):

    

    message_factory = EmailMessage
    utf8 = False
    refold_source = 'long'
    header_factory = HeaderRegistry()
    content_manager = raw_data_manager

    def __init__(self, **kw):
        
        
        if 'header_factory' not in kw:
            object.__setattr__(self, 'header_factory', HeaderRegistry())
        super().__init__(**kw)

    def header_max_count(self, name):
        
        return self.header_factory[name].max_count

    
    
    
    
    
    
    
    
    

    def header_source_parse(self, sourcelines):
        
        name, value = sourcelines[0].split(':', 1)
        value = value.lstrip(' \t') + ''.join(sourcelines[1:])
        return (name, value.rstrip('\r\n'))

    def header_store_parse(self, name, value):
        
        if hasattr(value, 'name') and value.name.lower() == name.lower():
            return (name, value)
        if isinstance(value, str) and len(value.splitlines())>1:
            
            
            raise ValueError("Header values may not contain linefeed "
                             "or carriage return characters")
        return (name, self.header_factory(name, value))

    def header_fetch_parse(self, name, value):
        
        if hasattr(value, 'name'):
            return value
        
        value = ''.join(linesep_splitter.split(value))
        return self.header_factory(name, value)

    def fold(self, name, value):
        
        return self._fold(name, value, refold_binary=True)

    def fold_binary(self, name, value):
        
        folded = self._fold(name, value, refold_binary=self.cte_type=='7bit')
        charset = 'utf8' if self.utf8 else 'ascii'
        return folded.encode(charset, 'surrogateescape')

    def _fold(self, name, value, refold_binary=False):
        if hasattr(value, 'name'):
            return value.fold(policy=self)
        maxlen = self.max_line_length if self.max_line_length else sys.maxsize
        lines = value.splitlines()
        refold = (self.refold_source == 'all' or
                  self.refold_source == 'long' and
                    (lines and len(lines[0])+len(name)+2 > maxlen or
                     any(len(x) > maxlen for x in lines[1:])))
        if refold or refold_binary and _has_surrogates(value):
            return self.header_factory(name, ''.join(lines)).fold(policy=self)
        return name + ': ' + self.linesep.join(lines) + self.linesep


default = EmailPolicy()

del default.header_factory
strict = default.clone(raise_on_defect=True)
SMTP = default.clone(linesep='\r\n')
HTTP = default.clone(linesep='\r\n', max_line_length=None)
SMTPUTF8 = SMTP.clone(utf8=True)