mirror of https://github.com/python/cpython
gh-102507 Remove invisible pagebreak characters (#102531)
Co-authored-by: AlexWaygood <alex.waygood@gmail.com>
This commit is contained in:
parent
401d7a7f00
commit
b097925858
|
@ -25,7 +25,6 @@ __all__ = [
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Some convenience routines. Don't import Parser and Message as side-effects
|
# Some convenience routines. Don't import Parser and Message as side-effects
|
||||||
# of importing email since those cascadingly import most of the rest of the
|
# of importing email since those cascadingly import most of the rest of the
|
||||||
# email package.
|
# email package.
|
||||||
|
|
|
@ -45,7 +45,6 @@ EMPTYSTRING = ''
|
||||||
MISC_LEN = 7
|
MISC_LEN = 7
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Helpers
|
# Helpers
|
||||||
def header_length(bytearray):
|
def header_length(bytearray):
|
||||||
"""Return the length of s when it is encoded with base64."""
|
"""Return the length of s when it is encoded with base64."""
|
||||||
|
@ -57,7 +56,6 @@ def header_length(bytearray):
|
||||||
return n
|
return n
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def header_encode(header_bytes, charset='iso-8859-1'):
|
def header_encode(header_bytes, charset='iso-8859-1'):
|
||||||
"""Encode a single header line with Base64 encoding in a given charset.
|
"""Encode a single header line with Base64 encoding in a given charset.
|
||||||
|
|
||||||
|
@ -72,7 +70,6 @@ def header_encode(header_bytes, charset='iso-8859-1'):
|
||||||
return '=?%s?b?%s?=' % (charset, encoded)
|
return '=?%s?b?%s?=' % (charset, encoded)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def body_encode(s, maxlinelen=76, eol=NL):
|
def body_encode(s, maxlinelen=76, eol=NL):
|
||||||
r"""Encode a string with base64.
|
r"""Encode a string with base64.
|
||||||
|
|
||||||
|
@ -98,7 +95,6 @@ def body_encode(s, maxlinelen=76, eol=NL):
|
||||||
return EMPTYSTRING.join(encvec)
|
return EMPTYSTRING.join(encvec)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def decode(string):
|
def decode(string):
|
||||||
"""Decode a raw base64 string, returning a bytes object.
|
"""Decode a raw base64 string, returning a bytes object.
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,6 @@ from email import errors
|
||||||
from email.encoders import encode_7or8bit
|
from email.encoders import encode_7or8bit
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Flags for types of header encodings
|
# Flags for types of header encodings
|
||||||
QP = 1 # Quoted-Printable
|
QP = 1 # Quoted-Printable
|
||||||
BASE64 = 2 # Base64
|
BASE64 = 2 # Base64
|
||||||
|
@ -32,7 +31,6 @@ UNKNOWN8BIT = 'unknown-8bit'
|
||||||
EMPTYSTRING = ''
|
EMPTYSTRING = ''
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Defaults
|
# Defaults
|
||||||
CHARSETS = {
|
CHARSETS = {
|
||||||
# input header enc body enc output conv
|
# input header enc body enc output conv
|
||||||
|
@ -104,7 +102,6 @@ CODEC_MAP = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Convenience functions for extending the above mappings
|
# Convenience functions for extending the above mappings
|
||||||
def add_charset(charset, header_enc=None, body_enc=None, output_charset=None):
|
def add_charset(charset, header_enc=None, body_enc=None, output_charset=None):
|
||||||
"""Add character set properties to the global registry.
|
"""Add character set properties to the global registry.
|
||||||
|
@ -153,7 +150,6 @@ def add_codec(charset, codecname):
|
||||||
CODEC_MAP[charset] = codecname
|
CODEC_MAP[charset] = codecname
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Convenience function for encoding strings, taking into account
|
# Convenience function for encoding strings, taking into account
|
||||||
# that they might be unknown-8bit (ie: have surrogate-escaped bytes)
|
# that they might be unknown-8bit (ie: have surrogate-escaped bytes)
|
||||||
def _encode(string, codec):
|
def _encode(string, codec):
|
||||||
|
@ -163,7 +159,6 @@ def _encode(string, codec):
|
||||||
return string.encode(codec)
|
return string.encode(codec)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Charset:
|
class Charset:
|
||||||
"""Map character sets to their email properties.
|
"""Map character sets to their email properties.
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ from base64 import encodebytes as _bencode
|
||||||
from quopri import encodestring as _encodestring
|
from quopri import encodestring as _encodestring
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _qencode(s):
|
def _qencode(s):
|
||||||
enc = _encodestring(s, quotetabs=True)
|
enc = _encodestring(s, quotetabs=True)
|
||||||
# Must encode spaces, which quopri.encodestring() doesn't do
|
# Must encode spaces, which quopri.encodestring() doesn't do
|
||||||
|
@ -34,7 +33,6 @@ def encode_base64(msg):
|
||||||
msg['Content-Transfer-Encoding'] = 'base64'
|
msg['Content-Transfer-Encoding'] = 'base64'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def encode_quopri(msg):
|
def encode_quopri(msg):
|
||||||
"""Encode the message's payload in quoted-printable.
|
"""Encode the message's payload in quoted-printable.
|
||||||
|
|
||||||
|
@ -46,7 +44,6 @@ def encode_quopri(msg):
|
||||||
msg['Content-Transfer-Encoding'] = 'quoted-printable'
|
msg['Content-Transfer-Encoding'] = 'quoted-printable'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def encode_7or8bit(msg):
|
def encode_7or8bit(msg):
|
||||||
"""Set the Content-Transfer-Encoding header to 7bit or 8bit."""
|
"""Set the Content-Transfer-Encoding header to 7bit or 8bit."""
|
||||||
orig = msg.get_payload(decode=True)
|
orig = msg.get_payload(decode=True)
|
||||||
|
@ -64,6 +61,5 @@ def encode_7or8bit(msg):
|
||||||
msg['Content-Transfer-Encoding'] = '7bit'
|
msg['Content-Transfer-Encoding'] = '7bit'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def encode_noop(msg):
|
def encode_noop(msg):
|
||||||
"""Do nothing."""
|
"""Do nothing."""
|
||||||
|
|
|
@ -41,7 +41,6 @@ NL = '\n'
|
||||||
NeedMoreData = object()
|
NeedMoreData = object()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BufferedSubFile(object):
|
class BufferedSubFile(object):
|
||||||
"""A file-ish object that can have new data loaded into it.
|
"""A file-ish object that can have new data loaded into it.
|
||||||
|
|
||||||
|
@ -132,7 +131,6 @@ class BufferedSubFile(object):
|
||||||
return line
|
return line
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class FeedParser:
|
class FeedParser:
|
||||||
"""A feed-style parser of email."""
|
"""A feed-style parser of email."""
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ NLCRE = re.compile(r'\r\n|\r|\n')
|
||||||
fcre = re.compile(r'^From ', re.MULTILINE)
|
fcre = re.compile(r'^From ', re.MULTILINE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Generator:
|
class Generator:
|
||||||
"""Generates output from a Message object tree.
|
"""Generates output from a Message object tree.
|
||||||
|
|
||||||
|
@ -392,7 +391,7 @@ class Generator:
|
||||||
def _compile_re(cls, s, flags):
|
def _compile_re(cls, s, flags):
|
||||||
return re.compile(s, flags)
|
return re.compile(s, flags)
|
||||||
|
|
||||||
|
|
||||||
class BytesGenerator(Generator):
|
class BytesGenerator(Generator):
|
||||||
"""Generates a bytes version of a Message object tree.
|
"""Generates a bytes version of a Message object tree.
|
||||||
|
|
||||||
|
@ -443,7 +442,6 @@ class BytesGenerator(Generator):
|
||||||
return re.compile(s.encode('ascii'), flags)
|
return re.compile(s.encode('ascii'), flags)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_FMT = '[Non-text (%(type)s) part of message omitted, filename %(filename)s]'
|
_FMT = '[Non-text (%(type)s) part of message omitted, filename %(filename)s]'
|
||||||
|
|
||||||
class DecodedGenerator(Generator):
|
class DecodedGenerator(Generator):
|
||||||
|
@ -503,7 +501,6 @@ class DecodedGenerator(Generator):
|
||||||
}, file=self)
|
}, file=self)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Helper used by Generator._make_boundary
|
# Helper used by Generator._make_boundary
|
||||||
_width = len(repr(sys.maxsize-1))
|
_width = len(repr(sys.maxsize-1))
|
||||||
_fmt = '%%0%dd' % _width
|
_fmt = '%%0%dd' % _width
|
||||||
|
|
|
@ -52,12 +52,10 @@ fcre = re.compile(r'[\041-\176]+:$')
|
||||||
_embedded_header = re.compile(r'\n[^ \t]+:')
|
_embedded_header = re.compile(r'\n[^ \t]+:')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Helpers
|
# Helpers
|
||||||
_max_append = email.quoprimime._max_append
|
_max_append = email.quoprimime._max_append
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def decode_header(header):
|
def decode_header(header):
|
||||||
"""Decode a message header value without converting charset.
|
"""Decode a message header value without converting charset.
|
||||||
|
|
||||||
|
@ -152,7 +150,6 @@ def decode_header(header):
|
||||||
return collapsed
|
return collapsed
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def make_header(decoded_seq, maxlinelen=None, header_name=None,
|
def make_header(decoded_seq, maxlinelen=None, header_name=None,
|
||||||
continuation_ws=' '):
|
continuation_ws=' '):
|
||||||
"""Create a Header from a sequence of pairs as returned by decode_header()
|
"""Create a Header from a sequence of pairs as returned by decode_header()
|
||||||
|
@ -175,7 +172,6 @@ def make_header(decoded_seq, maxlinelen=None, header_name=None,
|
||||||
return h
|
return h
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Header:
|
class Header:
|
||||||
def __init__(self, s=None, charset=None,
|
def __init__(self, s=None, charset=None,
|
||||||
maxlinelen=None, header_name=None,
|
maxlinelen=None, header_name=None,
|
||||||
|
@ -409,7 +405,6 @@ class Header:
|
||||||
self._chunks = chunks
|
self._chunks = chunks
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class _ValueFormatter:
|
class _ValueFormatter:
|
||||||
def __init__(self, headerlen, maxlen, continuation_ws, splitchars):
|
def __init__(self, headerlen, maxlen, continuation_ws, splitchars):
|
||||||
self._maxlen = maxlen
|
self._maxlen = maxlen
|
||||||
|
|
|
@ -15,7 +15,6 @@ import sys
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# This function will become a method of the Message class
|
# This function will become a method of the Message class
|
||||||
def walk(self):
|
def walk(self):
|
||||||
"""Walk over the message tree, yielding each subpart.
|
"""Walk over the message tree, yielding each subpart.
|
||||||
|
@ -29,7 +28,6 @@ def walk(self):
|
||||||
yield from subpart.walk()
|
yield from subpart.walk()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# These two functions are imported into the Iterators.py interface module.
|
# These two functions are imported into the Iterators.py interface module.
|
||||||
def body_line_iterator(msg, decode=False):
|
def body_line_iterator(msg, decode=False):
|
||||||
"""Iterate over the parts, returning string payloads line-by-line.
|
"""Iterate over the parts, returning string payloads line-by-line.
|
||||||
|
@ -55,7 +53,6 @@ def typed_subpart_iterator(msg, maintype='text', subtype=None):
|
||||||
yield subpart
|
yield subpart
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _structure(msg, fp=None, level=0, include_default=False):
|
def _structure(msg, fp=None, level=0, include_default=False):
|
||||||
"""A handy debugging aid"""
|
"""A handy debugging aid"""
|
||||||
if fp is None:
|
if fp is None:
|
||||||
|
|
|
@ -11,7 +11,6 @@ import email.policy
|
||||||
from email import message
|
from email import message
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MIMEBase(message.Message):
|
class MIMEBase(message.Message):
|
||||||
"""Base class for MIME specializations."""
|
"""Base class for MIME specializations."""
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ from email import message
|
||||||
from email.mime.nonmultipart import MIMENonMultipart
|
from email.mime.nonmultipart import MIMENonMultipart
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MIMEMessage(MIMENonMultipart):
|
class MIMEMessage(MIMENonMultipart):
|
||||||
"""Class representing message/* MIME documents."""
|
"""Class representing message/* MIME documents."""
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ __all__ = ['MIMEMultipart']
|
||||||
from email.mime.base import MIMEBase
|
from email.mime.base import MIMEBase
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MIMEMultipart(MIMEBase):
|
class MIMEMultipart(MIMEBase):
|
||||||
"""Base class for MIME multipart/* type messages."""
|
"""Base class for MIME multipart/* type messages."""
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ from email import errors
|
||||||
from email.mime.base import MIMEBase
|
from email.mime.base import MIMEBase
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MIMENonMultipart(MIMEBase):
|
class MIMENonMultipart(MIMEBase):
|
||||||
"""Base class for MIME non-multipart type messages."""
|
"""Base class for MIME non-multipart type messages."""
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ from email.charset import Charset
|
||||||
from email.mime.nonmultipart import MIMENonMultipart
|
from email.mime.nonmultipart import MIMENonMultipart
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class MIMEText(MIMENonMultipart):
|
class MIMEText(MIMENonMultipart):
|
||||||
"""Class for generating text/* type MIME documents."""
|
"""Class for generating text/* type MIME documents."""
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,6 @@ class Parser:
|
||||||
return self.parse(StringIO(text), headersonly=headersonly)
|
return self.parse(StringIO(text), headersonly=headersonly)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class HeaderParser(Parser):
|
class HeaderParser(Parser):
|
||||||
def parse(self, fp, headersonly=True):
|
def parse(self, fp, headersonly=True):
|
||||||
return Parser.parse(self, fp, True)
|
return Parser.parse(self, fp, True)
|
||||||
|
@ -72,7 +71,7 @@ class HeaderParser(Parser):
|
||||||
def parsestr(self, text, headersonly=True):
|
def parsestr(self, text, headersonly=True):
|
||||||
return Parser.parsestr(self, text, True)
|
return Parser.parsestr(self, text, True)
|
||||||
|
|
||||||
|
|
||||||
class BytesParser:
|
class BytesParser:
|
||||||
|
|
||||||
def __init__(self, *args, **kw):
|
def __init__(self, *args, **kw):
|
||||||
|
|
|
@ -1742,7 +1742,6 @@ _bufferedreader_peek_unlocked(buffered *self)
|
||||||
self->pos = 0;
|
self->pos = 0;
|
||||||
return PyBytes_FromStringAndSize(self->buffer, r);
|
return PyBytes_FromStringAndSize(self->buffer, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2052,7 +2051,6 @@ error:
|
||||||
LEAVE_BUFFERED(self)
|
LEAVE_BUFFERED(self)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2266,7 +2264,6 @@ bufferedrwpair_closed_get(rwpair *self, void *context)
|
||||||
}
|
}
|
||||||
return PyObject_GetAttr((PyObject *) self->writer, &_Py_ID(closed));
|
return PyObject_GetAttr((PyObject *) self->writer, &_Py_ID(closed));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -174,7 +174,6 @@ DEFAULTKEYWORDS = ', '.join(default_keywords)
|
||||||
EMPTYSTRING = ''
|
EMPTYSTRING = ''
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# The normal pot-file header. msgmerge and Emacs's po-mode work better if it's
|
# The normal pot-file header. msgmerge and Emacs's po-mode work better if it's
|
||||||
# there.
|
# there.
|
||||||
pot_header = _('''\
|
pot_header = _('''\
|
||||||
|
@ -196,7 +195,7 @@ msgstr ""
|
||||||
|
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
|
||||||
def usage(code, msg=''):
|
def usage(code, msg=''):
|
||||||
print(__doc__ % globals(), file=sys.stderr)
|
print(__doc__ % globals(), file=sys.stderr)
|
||||||
if msg:
|
if msg:
|
||||||
|
@ -204,7 +203,6 @@ def usage(code, msg=''):
|
||||||
sys.exit(code)
|
sys.exit(code)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def make_escapes(pass_nonascii):
|
def make_escapes(pass_nonascii):
|
||||||
global escapes, escape
|
global escapes, escape
|
||||||
if pass_nonascii:
|
if pass_nonascii:
|
||||||
|
@ -258,7 +256,7 @@ def normalize(s, encoding):
|
||||||
s = '""\n"' + lineterm.join(lines) + '"'
|
s = '""\n"' + lineterm.join(lines) + '"'
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
def containsAny(str, set):
|
def containsAny(str, set):
|
||||||
"""Check whether 'str' contains ANY of the chars in 'set'"""
|
"""Check whether 'str' contains ANY of the chars in 'set'"""
|
||||||
return 1 in [c in str for c in set]
|
return 1 in [c in str for c in set]
|
||||||
|
@ -307,7 +305,7 @@ def getFilesForName(name):
|
||||||
|
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
class TokenEater:
|
class TokenEater:
|
||||||
def __init__(self, options):
|
def __init__(self, options):
|
||||||
self.__options = options
|
self.__options = options
|
||||||
|
@ -515,7 +513,6 @@ class TokenEater:
|
||||||
print('msgstr ""\n', file=fp)
|
print('msgstr ""\n', file=fp)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global default_keywords
|
global default_keywords
|
||||||
try:
|
try:
|
||||||
|
@ -675,7 +672,7 @@ def main():
|
||||||
if closep:
|
if closep:
|
||||||
fp.close()
|
fp.close()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
# some more test strings
|
# some more test strings
|
||||||
|
|
Loading…
Reference in New Issue