diff options
author | R David Murray <rdmurray@bitdance.com> | 2016-09-09 20:04:23 -0400 |
---|---|---|
committer | R David Murray <rdmurray@bitdance.com> | 2016-09-09 20:04:23 -0400 |
commit | 49fa3c615e442e15fbf2e73d9c1594481c293b78 (patch) | |
tree | a567c6e0296452007dcacccfce956d0d0bf1a1fa /Lib/mailcap.py | |
parent | da55208526e86c05fae92abd408dae9f72c8821a (diff) | |
download | cpython-49fa3c615e442e15fbf2e73d9c1594481c293b78.tar.gz |
#14977: Make mailcap respect the order of the lines in the mailcap file.
This is required by RFC 1542, so despite the subtle behavior change we
are treating it as a bug. Patch by Michael Lazar.
Diffstat (limited to 'Lib/mailcap.py')
-rw-r--r-- | Lib/mailcap.py | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/Lib/mailcap.py b/Lib/mailcap.py index 97e303522c..bd0fc0981c 100644 --- a/Lib/mailcap.py +++ b/Lib/mailcap.py @@ -1,9 +1,19 @@ """Mailcap file handling. See RFC 1524.""" import os +import warnings __all__ = ["getcaps","findmatch"] + +def lineno_sort_key(entry): + # Sort in ascending order, with unspecified entries at the end + if 'lineno' in entry: + return 0, entry['lineno'] + else: + return 1, 0 + + # Part 1: top-level interface. def getcaps(): @@ -17,13 +27,14 @@ def getcaps(): """ caps = {} + lineno = 0 for mailcap in listmailcapfiles(): try: fp = open(mailcap, 'r') except OSError: continue with fp: - morecaps = readmailcapfile(fp) + morecaps, lineno = _readmailcapfile(fp, lineno) for key, value in morecaps.items(): if not key in caps: caps[key] = value @@ -49,8 +60,15 @@ def listmailcapfiles(): # Part 2: the parser. - def readmailcapfile(fp): + """Read a mailcap file and return a dictionary keyed by MIME type.""" + warnings.warn('readmailcapfile is deprecated, use getcaps instead', + DeprecationWarning, 2) + caps, _ = _readmailcapfile(fp, None) + return caps + + +def _readmailcapfile(fp, lineno): """Read a mailcap file and return a dictionary keyed by MIME type. Each MIME type is mapped to an entry consisting of a list of @@ -76,6 +94,9 @@ def readmailcapfile(fp): key, fields = parseline(line) if not (key and fields): continue + if lineno is not None: + fields['lineno'] = lineno + lineno += 1 # Normalize the key types = key.split('/') for j in range(len(types)): @@ -86,7 +107,7 @@ def readmailcapfile(fp): caps[key].append(fields) else: caps[key] = [fields] - return caps + return caps, lineno def parseline(line): """Parse one entry in a mailcap file and return a dictionary. @@ -165,6 +186,7 @@ def lookup(caps, MIMEtype, key=None): entries = entries + caps[MIMEtype] if key is not None: entries = [e for e in entries if key in e] + entries = sorted(entries, key=lineno_sort_key) return entries def subst(field, MIMEtype, filename, plist=[]): |