Complete a merge of the mimelib project and the Python cvs codebases

for the email package.  The former is now just a shell project that
has some extra files for packaging for independent use (e.g. setup.py
and README).

Added a compatibility layer so that the same API can be used in Python
2.1 and 2.2/2.3 with the major differences shuffled off into helper
modules (_compat21.py and _compat22.py).

Also bumped the package version number to 2.0.3 for some fixes to be
checked in momentarily.
This commit is contained in:
Barry Warsaw 2002-05-19 23:44:19 +00:00
parent 2ae87539aa
commit 8c1aac2476
7 changed files with 168 additions and 45 deletions

View File

@ -5,15 +5,34 @@
"""
import base64
from quopri import encodestring as _encodestring
# Helpers
def _qencode(s):
enc = _encodestring(s, quotetabs=1)
# Must encode spaces, which quopri.encodestring() doesn't do
return enc.replace(' ', '=20')
try:
from quopri import encodestring as _encodestring
def _qencode(s):
enc = _encodestring(s, quotetabs=1)
# Must encode spaces, which quopri.encodestring() doesn't do
return enc.replace(' ', '=20')
except ImportError:
# Python 2.1 doesn't have quopri.encodestring()
from cStringIO import StringIO
import quopri as _quopri
def _qencode(s):
if not s:
return s
hasnewline = (s[-1] == '\n')
infp = StringIO(s)
outfp = StringIO()
_quopri.encode(infp, outfp, quotetabs=1)
# Python 2.x's encode() doesn't encode spaces even when quotetabs==1
value = outfp.getvalue().replace(' ', '=20')
if not hasnewline and value[-1] == '\n':
return value[:-1]
return value
def _bencode(s):

View File

@ -4,30 +4,8 @@
"""Various types of useful iterators and generators.
"""
from __future__ import generators
from cStringIO import StringIO
from types import StringType
def body_line_iterator(msg):
"""Iterate over the parts, returning string payloads line-by-line."""
for subpart in msg.walk():
payload = subpart.get_payload()
if type(payload) is StringType:
for line in StringIO(payload):
yield line
def typed_subpart_iterator(msg, maintype='text', subtype=None):
"""Iterate over the subparts with a given MIME type.
Use `maintype' as the main MIME type to match against; this defaults to
"text". Optional `subtype' is the MIME subtype to match against; if
omitted, only the main type is matched.
"""
for subpart in msg.walk():
if subpart.get_main_type('text') == maintype:
if subtype is None or subpart.get_subtype('plain') == subtype:
yield subpart
try:
from email._compat22 import body_line_iterator, typed_subpart_iterator
except SyntaxError:
# Python 2.1 doesn't have generators
from email._compat21 import body_line_iterator, typed_subpart_iterator

View File

@ -607,17 +607,11 @@ class Message:
newheaders.append((h, v))
self._headers = newheaders
def walk(self):
"""Walk over the message tree, yielding each subpart.
The walk is performed in depth-first order. This method is a
generator.
"""
yield self
if self.is_multipart():
for subpart in self.get_payload():
for subsubpart in subpart.walk():
yield subsubpart
try:
from email._compat22 import walk
except SyntaxError:
# Must be using Python 2.1
from email._compat21 import walk
def get_charsets(self, failobj=None):
"""Return a list containing the charset(s) used in this message.

View File

@ -21,7 +21,24 @@ from rfc822 import mktime_tz
from rfc822 import parsedate as _parsedate
from rfc822 import parsedate_tz as _parsedate_tz
from quopri import decodestring as _qdecode
try:
from quopri import decodestring as _qdecode
except ImportError:
# Python 2.1 doesn't have quopri.decodestring()
def _qdecode(s):
import quopri as _quopri
if not s:
return s
hasnewline = (s[-1] == '\n')
infp = StringIO(s)
outfp = StringIO()
_quopri.decode(infp, outfp)
value = outfp.getvalue()
if not hasnewline and value[-1] =='\n':
return value[:-1]
return value
import base64
# Intrapackage imports

View File

@ -4,7 +4,7 @@
"""A package for parsing, handling, and generating email messages.
"""
__version__ = '2.0'
__version__ = '2.0.3'
__all__ = ['Charset',
'Encoders',

59
Lib/email/_compat21.py Normal file
View File

@ -0,0 +1,59 @@
# Copyright (C) 2002 Python Software Foundation
# Author: barry@zope.com
"""Module containing compatibility functions for Python 2.1.
"""
from cStringIO import StringIO
from types import StringType, UnicodeType
# This function will become a method of the Message class
def walk(self):
"""Walk over the message tree, yielding each subpart.
The walk is performed in depth-first order. This method is a
generator.
"""
parts = []
parts.append(self)
if self.is_multipart():
for subpart in self.get_payload():
parts.extend(subpart.walk())
return parts
# Used internally by the Header class
def _intdiv2(i):
"""Do an integer divide by 2."""
return i / 2
# These two functions are imported into the Iterators.py interface module.
# The Python 2.2 version uses generators for efficiency.
def body_line_iterator(msg):
"""Iterate over the parts, returning string payloads line-by-line."""
lines = []
for subpart in msg.walk():
payload = subpart.get_payload()
if isinstance(payload, StringType) or isinstance(payload, UnicodeType):
for line in StringIO(payload).readlines():
lines.append(line)
return lines
def typed_subpart_iterator(msg, maintype='text', subtype=None):
"""Iterate over the subparts with a given MIME type.
Use `maintype' as the main MIME type to match against; this defaults to
"text". Optional `subtype' is the MIME subtype to match against; if
omitted, only the main type is matched.
"""
parts = []
for subpart in msg.walk():
if subpart.get_main_type('text') == maintype:
if subtype is None or subpart.get_subtype('plain') == subtype:
parts.append(subpart)
return parts

56
Lib/email/_compat22.py Normal file
View File

@ -0,0 +1,56 @@
# Copyright (C) 2002 Python Software Foundation
# Author: barry@zope.com
"""Module containing compatibility functions for Python 2.1.
"""
from __future__ import generators
from __future__ import division
from cStringIO import StringIO
from types import StringTypes
# This function will become a method of the Message class
def walk(self):
"""Walk over the message tree, yielding each subpart.
The walk is performed in depth-first order. This method is a
generator.
"""
yield self
if self.is_multipart():
for subpart in self.get_payload():
for subsubpart in subpart.walk():
yield subsubpart
# Used internally by the Header class
def _intdiv2(i):
"""Do an integer divide by 2."""
return i // 2
# These two functions are imported into the Iterators.py interface module.
# The Python 2.2 version uses generators for efficiency.
def body_line_iterator(msg):
"""Iterate over the parts, returning string payloads line-by-line."""
for subpart in msg.walk():
payload = subpart.get_payload()
if isinstance(payload, StringTypes):
for line in StringIO(payload):
yield line
def typed_subpart_iterator(msg, maintype='text', subtype=None):
"""Iterate over the subparts with a given MIME type.
Use `maintype' as the main MIME type to match against; this defaults to
"text". Optional `subtype' is the MIME subtype to match against; if
omitted, only the main type is matched.
"""
for subpart in msg.walk():
if subpart.get_main_type('text') == maintype:
if subtype is None or subpart.get_subtype('plain') == subtype:
yield subpart