[Python-checkins] CVS: python/dist/src/Lib/email Message.py,1.1,1.2
Barry Warsaw
bwarsaw@users.sourceforge.net
Tue, 25 Sep 2001 22:41:54 -0700
Update of /cvsroot/python/python/dist/src/Lib/email
In directory usw-pr-cvs1:/tmp/cvs-serv28509
Modified Files:
Message.py
Log Message:
has_key(): Implement in terms of get().
get_type(): Use a compiled regular expression, which can be shared.
_get_params_preserve(): A helper method which extracts the header's
parameter list preserving value quoting. I'm not sure that this
needs to be a public method. It's necessary because we want
get_param() and friends to return the unquoted parameter value,
however we want the quote-preserved form for set_boundary().
get_params(), get_param(), set_boundary(): Implement in terms of
_get_params_preserve().
walk(): Yield ourself first, then recurse over our subparts (if any).
Index: Message.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/email/Message.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** Message.py 2001/09/23 03:17:28 1.1
--- Message.py 2001/09/26 05:41:51 1.2
***************
*** 13,22 ****
from types import ListType
- SEMISPACE = '; '
-
# Intrapackage imports
import Errors
import Utils
--- 13,23 ----
from types import ListType
# Intrapackage imports
import Errors
import Utils
+ SEMISPACE = '; '
+ paramre = re.compile(r';\s*')
+
***************
*** 136,140 ****
#
def __len__(self):
! """Get the total number of headers, including duplicates."""
return len(self._headers)
--- 137,141 ----
#
def __len__(self):
! """Return the total number of headers, including duplicates."""
return len(self._headers)
***************
*** 175,179 ****
def has_key(self, name):
"""Return true if the message contains the header."""
! return self[name] <> None
def keys(self):
--- 176,181 ----
def has_key(self, name):
"""Return true if the message contains the header."""
! missing = []
! return self.get(name, missing) is not missing
def keys(self):
***************
*** 268,272 ****
if value is missing:
return failobj
! return re.split(r';\s+', value)[0].lower()
def get_main_type(self, failobj=None):
--- 270,274 ----
if value is missing:
return failobj
! return paramre.split(value)[0].lower()
def get_main_type(self, failobj=None):
***************
*** 292,298 ****
--- 294,324 ----
return failobj
+ def _get_params_preserve(self, failobj, header):
+ # Like get_params() but preserves the quoting of values. BAW:
+ # should this be part of the public interface?
+ missing = []
+ value = self.get(header, missing)
+ if value is missing:
+ return failobj
+ params = []
+ for p in paramre.split(value):
+ try:
+ name, val = p.split('=', 1)
+ except ValueError:
+ # Must have been a bare attribute
+ name = p
+ val = ''
+ params.append((name, val))
+ return params
+
def get_params(self, failobj=None, header='content-type'):
"""Return the message's Content-Type: parameters, as a list.
+ The elements of the returned list are 2-tuples of key/value pairs, as
+ split on the `=' sign. The left hand side of the `=' is the key,
+ while the right hand side is the value. If there is no `=' sign in
+ the parameter the value is the empty string. The value is always
+ unquoted.
+
Optional failobj is the object to return if there is no Content-Type:
header. Optional header is the header to search instead of
***************
*** 300,307 ****
"""
missing = []
! value = self.get(header, missing)
! if value is missing:
return failobj
! return re.split(r';\s+', value)[1:]
def get_param(self, param, failobj=None, header='content-type'):
--- 326,333 ----
"""
missing = []
! params = self._get_params_preserve(missing, header)
! if params is missing:
return failobj
! return [(k, Utils.unquote(v)) for k, v in params]
def get_param(self, param, failobj=None, header='content-type'):
***************
*** 311,329 ****
header. Optional header is the header to search instead of
Content-Type:
"""
! param = param.lower()
! missing = []
! params = self.get_params(missing, header=header)
! if params is missing:
return failobj
! for p in params:
! try:
! name, val = p.split('=', 1)
! except ValueError:
! # Must have been a bare attribute
! name = p
! val = ''
! if name.lower() == param:
! return Utils.unquote(val)
return failobj
--- 337,349 ----
header. Optional header is the header to search instead of
Content-Type:
+
+ Parameter keys are always compared case insensitively. Values are
+ always unquoted.
"""
! if not self.has_key(header):
return failobj
! for k, v in self._get_params_preserve(failobj, header):
! if k.lower() == param.lower():
! return Utils.unquote(v)
return failobj
***************
*** 362,367 ****
HeaderParseError is raised if the message has no Content-Type: header.
"""
! params = self.get_params()
! if not params:
# There was no Content-Type: header, and we don't know what type
# to set it to, so raise an exception.
--- 382,388 ----
HeaderParseError is raised if the message has no Content-Type: header.
"""
! missing = []
! params = self._get_params_preserve(missing, 'content-type')
! if params is missing:
# There was no Content-Type: header, and we don't know what type
# to set it to, so raise an exception.
***************
*** 369,390 ****
newparams = []
foundp = 0
! for p in params:
! if p.lower().startswith('boundary='):
! newparams.append('boundary="%s"' % boundary)
foundp = 1
else:
! newparams.append(p)
if not foundp:
# The original Content-Type: header had no boundary attribute.
# Tack one one the end. BAW: should we raise an exception
# instead???
! newparams.append('boundary="%s"' % boundary)
# Replace the existing Content-Type: header with the new value
newheaders = []
for h, v in self._headers:
if h.lower() == 'content-type':
! value = v.split(';', 1)[0]
! newparams.insert(0, value)
! newheaders.append((h, SEMISPACE.join(newparams)))
else:
newheaders.append((h, v))
--- 390,416 ----
newparams = []
foundp = 0
! for pk, pv in params:
! if pk.lower() == 'boundary':
! newparams.append(('boundary', '"%s"' % boundary))
foundp = 1
else:
! newparams.append((pk, pv))
if not foundp:
# The original Content-Type: header had no boundary attribute.
# Tack one one the end. BAW: should we raise an exception
# instead???
! newparams.append(('boundary', '"%s"' % boundary))
# Replace the existing Content-Type: header with the new value
newheaders = []
for h, v in self._headers:
if h.lower() == 'content-type':
! parts = []
! for k, v in newparams:
! if v == '':
! parts.append(k)
! else:
! parts.append('%s=%s' % (k, v))
! newheaders.append((h, SEMISPACE.join(parts)))
!
else:
newheaders.append((h, v))
***************
*** 397,406 ****
generator.
"""
if self.is_multipart():
for subpart in self.get_payload():
for subsubpart in subpart.walk():
yield subsubpart
- else:
- yield self
def get_charsets(self, failobj=None):
--- 423,431 ----
generator.
"""
+ yield self
if self.is_multipart():
for subpart in self.get_payload():
for subsubpart in subpart.walk():
yield subsubpart
def get_charsets(self, failobj=None):