From ecabb1cb57e7e066a693653f485f2f687dcc7f6b Mon Sep 17 00:00:00 2001 From: "David K. Hess" Date: Sat, 13 May 2017 17:30:47 -0500 Subject: [PATCH 1/8] Addresses mimetypes initialization problems and non-deterministic behavior. --- Lib/mimetypes.py | 312 +++++++++++++++++++------------------ Lib/test/test_mimetypes.py | 51 ++++++ 2 files changed, 209 insertions(+), 154 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 3d6869486455964..157efa67f6c0d6e 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -32,6 +32,8 @@ except ImportError: _winreg = None +from collections import OrderedDict + __all__ = [ "knownfiles", "inited", "MimeTypes", "guess_type", "guess_all_extensions", "guess_extension", @@ -66,13 +68,13 @@ class MimeTypes: def __init__(self, filenames=(), strict=True): if not inited: init() - self.encodings_map = encodings_map.copy() - self.suffix_map = suffix_map.copy() + self.encodings_map = _encodings_map_default.copy() + self.suffix_map = _suffix_map_default.copy() self.types_map = ({}, {}) # dict for (non-strict, strict) self.types_map_inv = ({}, {}) - for (ext, type) in types_map.items(): + for (ext, type) in _types_map_default.items(): self.add_type(type, ext, True) - for (ext, type) in common_types.items(): + for (ext, type) in _common_types_default.items(): self.add_type(type, ext, False) for name in filenames: self.read(name, strict) @@ -345,11 +347,15 @@ def init(files=None): global suffix_map, types_map, encodings_map, common_types global inited, _db inited = True # so that MimeTypes.__init__() doesn't call us again - db = MimeTypes() + if files is None: + db = MimeTypes() if _winreg: db.read_windows_registry() files = knownfiles + else: + db = _db + for file in files: if os.path.isfile(file): db.read(file) @@ -373,12 +379,12 @@ def read_mime_types(file): def _default_mime_types(): - global suffix_map - global encodings_map - global types_map - global common_types + global suffix_map, _suffix_map_default + global encodings_map, _encodings_map_default + global types_map, _types_map_default + global common_types, _common_types_default - suffix_map = { + suffix_map = _suffix_map_default = { '.svgz': '.svg.gz', '.tgz': '.tar.gz', '.taz': '.tar.gz', @@ -387,7 +393,7 @@ def _default_mime_types(): '.txz': '.tar.xz', } - encodings_map = { + encodings_map = _encodings_map_default = { '.gz': 'gzip', '.Z': 'compress', '.bz2': 'bzip2', @@ -398,154 +404,152 @@ def _default_mime_types(): # at http://www.iana.org/assignments/media-types # or extensions, i.e. using the x- prefix - # If you add to these, please keep them sorted! - types_map = { - '.a' : 'application/octet-stream', - '.ai' : 'application/postscript', - '.aif' : 'audio/x-aiff', - '.aifc' : 'audio/x-aiff', - '.aiff' : 'audio/x-aiff', - '.au' : 'audio/basic', - '.avi' : 'video/x-msvideo', - '.bat' : 'text/plain', - '.bcpio' : 'application/x-bcpio', - '.bin' : 'application/octet-stream', - '.bmp' : 'image/x-ms-bmp', - '.c' : 'text/plain', - # Duplicates :( - '.cdf' : 'application/x-cdf', - '.cdf' : 'application/x-netcdf', - '.cpio' : 'application/x-cpio', - '.csh' : 'application/x-csh', - '.css' : 'text/css', - '.csv' : 'text/csv', - '.dll' : 'application/octet-stream', - '.doc' : 'application/msword', - '.dot' : 'application/msword', - '.dvi' : 'application/x-dvi', - '.eml' : 'message/rfc822', - '.eps' : 'application/postscript', - '.etx' : 'text/x-setext', - '.exe' : 'application/octet-stream', - '.gif' : 'image/gif', - '.gtar' : 'application/x-gtar', - '.h' : 'text/plain', - '.hdf' : 'application/x-hdf', - '.htm' : 'text/html', - '.html' : 'text/html', - '.ico' : 'image/vnd.microsoft.icon', - '.ief' : 'image/ief', - '.jpe' : 'image/jpeg', - '.jpeg' : 'image/jpeg', - '.jpg' : 'image/jpeg', - '.js' : 'application/javascript', - '.ksh' : 'text/plain', - '.latex' : 'application/x-latex', - '.m1v' : 'video/mpeg', - '.m3u' : 'application/vnd.apple.mpegurl', - '.m3u8' : 'application/vnd.apple.mpegurl', - '.man' : 'application/x-troff-man', - '.me' : 'application/x-troff-me', - '.mht' : 'message/rfc822', - '.mhtml' : 'message/rfc822', - '.mif' : 'application/x-mif', - '.mov' : 'video/quicktime', - '.movie' : 'video/x-sgi-movie', - '.mp2' : 'audio/mpeg', - '.mp3' : 'audio/mpeg', - '.mp4' : 'video/mp4', - '.mpa' : 'video/mpeg', - '.mpe' : 'video/mpeg', - '.mpeg' : 'video/mpeg', - '.mpg' : 'video/mpeg', - '.ms' : 'application/x-troff-ms', - '.nc' : 'application/x-netcdf', - '.nws' : 'message/rfc822', - '.o' : 'application/octet-stream', - '.obj' : 'application/octet-stream', - '.oda' : 'application/oda', - '.p12' : 'application/x-pkcs12', - '.p7c' : 'application/pkcs7-mime', - '.pbm' : 'image/x-portable-bitmap', - '.pdf' : 'application/pdf', - '.pfx' : 'application/x-pkcs12', - '.pgm' : 'image/x-portable-graymap', - '.pl' : 'text/plain', - '.png' : 'image/png', - '.pnm' : 'image/x-portable-anymap', - '.pot' : 'application/vnd.ms-powerpoint', - '.ppa' : 'application/vnd.ms-powerpoint', - '.ppm' : 'image/x-portable-pixmap', - '.pps' : 'application/vnd.ms-powerpoint', - '.ppt' : 'application/vnd.ms-powerpoint', - '.ps' : 'application/postscript', - '.pwz' : 'application/vnd.ms-powerpoint', - '.py' : 'text/x-python', - '.pyc' : 'application/x-python-code', - '.pyo' : 'application/x-python-code', - '.qt' : 'video/quicktime', - '.ra' : 'audio/x-pn-realaudio', - '.ram' : 'application/x-pn-realaudio', - '.ras' : 'image/x-cmu-raster', - '.rdf' : 'application/xml', - '.rgb' : 'image/x-rgb', - '.roff' : 'application/x-troff', - '.rtx' : 'text/richtext', - '.sgm' : 'text/x-sgml', - '.sgml' : 'text/x-sgml', - '.sh' : 'application/x-sh', - '.shar' : 'application/x-shar', - '.snd' : 'audio/basic', - '.so' : 'application/octet-stream', - '.src' : 'application/x-wais-source', - '.sv4cpio': 'application/x-sv4cpio', - '.sv4crc' : 'application/x-sv4crc', - '.svg' : 'image/svg+xml', - '.swf' : 'application/x-shockwave-flash', - '.t' : 'application/x-troff', - '.tar' : 'application/x-tar', - '.tcl' : 'application/x-tcl', - '.tex' : 'application/x-tex', - '.texi' : 'application/x-texinfo', - '.texinfo': 'application/x-texinfo', - '.tif' : 'image/tiff', - '.tiff' : 'image/tiff', - '.tr' : 'application/x-troff', - '.tsv' : 'text/tab-separated-values', - '.txt' : 'text/plain', - '.ustar' : 'application/x-ustar', - '.vcf' : 'text/x-vcard', - '.wav' : 'audio/x-wav', - '.webm' : 'video/webm', - '.wiz' : 'application/msword', - '.wsdl' : 'application/xml', - '.xbm' : 'image/x-xbitmap', - '.xlb' : 'application/vnd.ms-excel', - # Duplicates :( - '.xls' : 'application/excel', - '.xls' : 'application/vnd.ms-excel', - '.xml' : 'text/xml', - '.xpdl' : 'application/xml', - '.xpm' : 'image/x-xpixmap', - '.xsl' : 'application/xml', - '.xwd' : 'image/x-xwindowdump', - '.zip' : 'application/zip', - } + # If you add to these, please keep them sorted by mime type. + # Make sure the entry with the preferred file extension for a particular mime type + # appears before any others of the same mimetype. + types_map = _types_map_default = OrderedDict([ + ('.js' , 'application/javascript'), + ('.doc' , 'application/msword'), + ('.dot' , 'application/msword'), + ('.wiz' , 'application/msword'), + ('.bin' , 'application/octet-stream'), + ('.a' , 'application/octet-stream'), + ('.dll' , 'application/octet-stream'), + ('.exe' , 'application/octet-stream'), + ('.o' , 'application/octet-stream'), + ('.obj' , 'application/octet-stream'), + ('.so' , 'application/octet-stream'), + ('.oda' , 'application/oda'), + ('.pdf' , 'application/pdf'), + ('.p7c' , 'application/pkcs7-mime'), + ('.ps' , 'application/postscript'), + ('.ai' , 'application/postscript'), + ('.eps' , 'application/postscript'), + ('.m3u' , 'application/vnd.apple.mpegurl'), + ('.m3u8' , 'application/vnd.apple.mpegurl'), + ('.xls' , 'application/vnd.ms-excel'), + ('.xlb' , 'application/vnd.ms-excel'), + ('.ppt' , 'application/vnd.ms-powerpoint'), + ('.pot' , 'application/vnd.ms-powerpoint'), + ('.ppa' , 'application/vnd.ms-powerpoint'), + ('.pps' , 'application/vnd.ms-powerpoint'), + ('.pwz' , 'application/vnd.ms-powerpoint'), + ('.bcpio' , 'application/x-bcpio'), + ('.cpio' , 'application/x-cpio'), + ('.csh' , 'application/x-csh'), + ('.dvi' , 'application/x-dvi'), + ('.gtar' , 'application/x-gtar'), + ('.hdf' , 'application/x-hdf'), + ('.latex' , 'application/x-latex'), + ('.mif' , 'application/x-mif'), + ('.cdf' , 'application/x-netcdf'), + ('.nc' , 'application/x-netcdf'), + ('.p12' , 'application/x-pkcs12'), + ('.pfx' , 'application/x-pkcs12'), + ('.ram' , 'application/x-pn-realaudio'), + ('.pyc' , 'application/x-python-code'), + ('.pyo' , 'application/x-python-code'), + ('.sh' , 'application/x-sh'), + ('.shar' , 'application/x-shar'), + ('.swf' , 'application/x-shockwave-flash'), + ('.sv4cpio', 'application/x-sv4cpio'), + ('.sv4crc' , 'application/x-sv4crc'), + ('.tar' , 'application/x-tar'), + ('.tcl' , 'application/x-tcl'), + ('.tex' , 'application/x-tex'), + ('.texi' , 'application/x-texinfo'), + ('.texinfo', 'application/x-texinfo'), + ('.roff' , 'application/x-troff'), + ('.t' , 'application/x-troff'), + ('.tr' , 'application/x-troff'), + ('.man' , 'application/x-troff-man'), + ('.me' , 'application/x-troff-me'), + ('.ms' , 'application/x-troff-ms'), + ('.ustar' , 'application/x-ustar'), + ('.src' , 'application/x-wais-source'), + ('.xsl' , 'application/xml'), + ('.rdf' , 'application/xml'), + ('.wsdl' , 'application/xml'), + ('.xpdl' , 'application/xml'), + ('.zip' , 'application/zip'), + ('.au' , 'audio/basic'), + ('.snd' , 'audio/basic'), + ('.mp3' , 'audio/mpeg'), + ('.mp2' , 'audio/mpeg'), + ('.aif' , 'audio/x-aiff'), + ('.aifc' , 'audio/x-aiff'), + ('.aiff' , 'audio/x-aiff'), + ('.ra' , 'audio/x-pn-realaudio'), + ('.wav' , 'audio/x-wav'), + ('.gif' , 'image/gif'), + ('.ief' , 'image/ief'), + ('.jpg' , 'image/jpeg'), + ('.jpe' , 'image/jpeg'), + ('.jpeg' , 'image/jpeg'), + ('.png' , 'image/png'), + ('.svg' , 'image/svg+xml'), + ('.tiff' , 'image/tiff'), + ('.tif' , 'image/tiff'), + ('.ico' , 'image/vnd.microsoft.icon'), + ('.ras' , 'image/x-cmu-raster'), + ('.bmp' , 'image/x-ms-bmp'), + ('.pnm' , 'image/x-portable-anymap'), + ('.pbm' , 'image/x-portable-bitmap'), + ('.pgm' , 'image/x-portable-graymap'), + ('.ppm' , 'image/x-portable-pixmap'), + ('.rgb' , 'image/x-rgb'), + ('.xbm' , 'image/x-xbitmap'), + ('.xpm' , 'image/x-xpixmap'), + ('.xwd' , 'image/x-xwindowdump'), + ('.eml' , 'message/rfc822'), + ('.mht' , 'message/rfc822'), + ('.mhtml' , 'message/rfc822'), + ('.nws' , 'message/rfc822'), + ('.css' , 'text/css'), + ('.csv' , 'text/csv'), + ('.html' , 'text/html'), + ('.htm' , 'text/html'), + ('.txt' , 'text/plain'), + ('.bat' , 'text/plain'), + ('.c' , 'text/plain'), + ('.h' , 'text/plain'), + ('.ksh' , 'text/plain'), + ('.pl' , 'text/plain'), + ('.rtx' , 'text/richtext'), + ('.tsv' , 'text/tab-separated-values'), + ('.py' , 'text/x-python'), + ('.etx' , 'text/x-setext'), + ('.sgm' , 'text/x-sgml'), + ('.sgml' , 'text/x-sgml'), + ('.vcf' , 'text/x-vcard'), + ('.xml' , 'text/xml'), + ('.mp4' , 'video/mp4'), + ('.mpeg' , 'video/mpeg'), + ('.m1v' , 'video/mpeg'), + ('.mpa' , 'video/mpeg'), + ('.mpe' , 'video/mpeg'), + ('.mpg' , 'video/mpeg'), + ('.mov' , 'video/quicktime'), + ('.qt' , 'video/quicktime'), + ('.webm' , 'video/webm'), + ('.avi' , 'video/x-msvideo'), + ('.movie' , 'video/x-sgi-movie'), + ]) # These are non-standard types, commonly found in the wild. They will # only match if strict=0 flag is given to the API methods. # Please sort these too - common_types = { - '.jpg' : 'image/jpg', - '.mid' : 'audio/midi', - '.midi': 'audio/midi', - '.pct' : 'image/pict', - '.pic' : 'image/pict', - '.pict': 'image/pict', - '.rtf' : 'application/rtf', - '.xul' : 'text/xul' - } + common_types = _common_types_default = OrderedDict([ + ('.rtf' , 'application/rtf'), + ('.midi', 'audio/midi'), + ('.mid' , 'audio/midi'), + ('.jpg' , 'image/jpg'), + ('.pict', 'image/pict'), + ('.pct' , 'image/pict'), + ('.pic' , 'image/pict'), + ('.xul' , 'text/xul'), + ]) _default_mime_types() diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 4e2c9089b5737c2..5464b22306db46e 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -77,6 +77,57 @@ def test_encoding(self): strict=True) self.assertEqual(exts, ['.g3', '.g\xb3']) + def test_init_reinitializes(self): + # Issue 4936: make sure an init starts clean + # First, put some poison into the types table + mimetypes.add_type('foo/bar', '.foobar') + self.assertEqual(mimetypes.guess_extension('foo/bar'), '.foobar') + # Reinitialize + mimetypes.init() + # Poison should be gone. + self.assertEqual(mimetypes.guess_extension('foo/bar'), None) + + def test_preferred_extension(self): + def check_extensions(): + self.assertEqual(mimetypes.guess_extension('application/octet-stream'), '.bin') + self.assertEqual(mimetypes.guess_extension('application/postscript'), '.ps') + self.assertEqual(mimetypes.guess_extension('application/vnd.apple.mpegurl'), '.m3u') + self.assertEqual(mimetypes.guess_extension('application/vnd.ms-excel'), '.xls') + self.assertEqual(mimetypes.guess_extension('application/vnd.ms-powerpoint'), '.ppt') + self.assertEqual(mimetypes.guess_extension('application/x-texinfo'), '.texi') + self.assertEqual(mimetypes.guess_extension('application/x-troff'), '.roff') + self.assertEqual(mimetypes.guess_extension('application/xml'), '.xsl') + self.assertEqual(mimetypes.guess_extension('audio/mpeg'), '.mp3') + self.assertEqual(mimetypes.guess_extension('image/jpeg'), '.jpg') + self.assertEqual(mimetypes.guess_extension('image/tiff'), '.tiff') + self.assertEqual(mimetypes.guess_extension('message/rfc822'), '.eml') + self.assertEqual(mimetypes.guess_extension('text/html'), '.html') + self.assertEqual(mimetypes.guess_extension('text/plain'), '.txt') + self.assertEqual(mimetypes.guess_extension('video/mpeg'), '.mpeg') + self.assertEqual(mimetypes.guess_extension('video/quicktime'), '.mov') + + check_extensions() + mimetypes.init() + check_extensions() + + def test_init_stability(self): + mimetypes.init() + + suffix_map = mimetypes.suffix_map + encodings_map = mimetypes.encodings_map + types_map = mimetypes.types_map + common_types = mimetypes.common_types + + mimetypes.init() + self.assertIsNot(suffix_map, mimetypes.suffix_map) + self.assertIsNot(encodings_map, mimetypes.encodings_map) + self.assertIsNot(types_map, mimetypes.types_map) + self.assertIsNot(common_types, mimetypes.common_types) + self.assertEqual(suffix_map, mimetypes.suffix_map) + self.assertEqual(encodings_map, mimetypes.encodings_map) + self.assertEqual(types_map, mimetypes.types_map) + self.assertEqual(common_types, mimetypes.common_types) + @unittest.skipUnless(sys.platform.startswith("win"), "Windows only") class Win32MimeTypesTestCase(unittest.TestCase): From 0e8c48f6b3dfd42f55a837155e111bcc937fb9ec Mon Sep 17 00:00:00 2001 From: "David K. Hess" Date: Sat, 13 May 2017 19:37:43 -0500 Subject: [PATCH 2/8] Fix edge case with init. --- Lib/mimetypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 157efa67f6c0d6e..bbe81c8013e10c2 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -348,7 +348,7 @@ def init(files=None): global inited, _db inited = True # so that MimeTypes.__init__() doesn't call us again - if files is None: + if files is None or _db is None: db = MimeTypes() if _winreg: db.read_windows_registry() From 10abe194402bafdcc53ade6b822aee1794078007 Mon Sep 17 00:00:00 2001 From: "David K. Hess" Date: Sat, 13 May 2017 20:28:43 -0500 Subject: [PATCH 3/8] Fix another edge case. --- Lib/mimetypes.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index bbe81c8013e10c2..b622299c1849427 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -352,7 +352,11 @@ def init(files=None): db = MimeTypes() if _winreg: db.read_windows_registry() - files = knownfiles + + if files is None: + files = knownfiles + else: + files = knownfiles + list(files) else: db = _db From 2486b9241b611266e13b63efc040b551f2cc6097 Mon Sep 17 00:00:00 2001 From: "David K. Hess" Date: Thu, 10 Aug 2017 09:10:59 -0500 Subject: [PATCH 4/8] Fix whitespace issue with added test. --- Lib/test/test_mimetypes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index 5464b22306db46e..f5e1e7e05ea8c8b 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -88,7 +88,7 @@ def test_init_reinitializes(self): self.assertEqual(mimetypes.guess_extension('foo/bar'), None) def test_preferred_extension(self): - def check_extensions(): + def check_extensions(): self.assertEqual(mimetypes.guess_extension('application/octet-stream'), '.bin') self.assertEqual(mimetypes.guess_extension('application/postscript'), '.ps') self.assertEqual(mimetypes.guess_extension('application/vnd.apple.mpegurl'), '.m3u') From 384178cc041baec516fea28d6602a9483fe808c1 Mon Sep 17 00:00:00 2001 From: "David K. Hess" Date: Thu, 10 Aug 2017 09:19:39 -0500 Subject: [PATCH 5/8] Capture the new init() behavior in the documentation. --- Doc/library/mimetypes.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 464248c3ea7990c..1b1d38008122e11 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -88,6 +88,10 @@ behavior of the module. Specifying an empty list for *files* will prevent the system defaults from being applied: only the well-known values will be present from a built-in list. + If *files* is not specified or is ``None`` the internal data structure is completely + rebuilt to its initial default value. This is a stable operation and will produce + the same results when called multiple times. + .. versionchanged:: 3.2 Previously, Windows registry settings were ignored. From d2097be8234e6e83d382cd9f181531d56929bf12 Mon Sep 17 00:00:00 2001 From: "David K. Hess" Date: Fri, 11 Aug 2017 16:51:18 -0500 Subject: [PATCH 6/8] Tweak to the documentation per review feedback. --- Doc/library/mimetypes.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Doc/library/mimetypes.rst b/Doc/library/mimetypes.rst index 1b6bfecdb0e48f5..fab3a5230ce536f 100644 --- a/Doc/library/mimetypes.rst +++ b/Doc/library/mimetypes.rst @@ -88,9 +88,9 @@ behavior of the module. Specifying an empty list for *files* will prevent the system defaults from being applied: only the well-known values will be present from a built-in list. - If *files* is not specified or is ``None`` the internal data structure is completely - rebuilt to its initial default value. This is a stable operation and will produce - the same results when called multiple times. + If *files* is ``None`` the internal data structure is completely rebuilt to its + initial default value. This is a stable operation and will produce the same results + when called multiple times. .. versionchanged:: 3.2 Previously, Windows registry settings were ignored. From f9e59f940297997286b9559563aeaa192f80300b Mon Sep 17 00:00:00 2001 From: "David K. Hess" Date: Tue, 15 Aug 2017 11:25:04 -0500 Subject: [PATCH 7/8] Add news entry. --- .../NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst diff --git a/Misc/NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst b/Misc/NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst new file mode 100644 index 000000000000000..3b060052fd350c0 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2017-08-15-11-24-41.bpo-4963.LRYres.rst @@ -0,0 +1,2 @@ +Fixed non-deterministic behavior related to mimetypes extension mapping and +module reinitialization. From 59d1128f287347315a3561db8baa49360d05a1c8 Mon Sep 17 00:00:00 2001 From: "David K. Hess" Date: Tue, 21 May 2019 08:46:38 -0500 Subject: [PATCH 8/8] Remove use of OrderedDict --- Lib/mimetypes.py | 280 +++++++++++++++++++++++------------------------ 1 file changed, 139 insertions(+), 141 deletions(-) diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 2e401a5e67dc9ef..270e4a42c376e81 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -32,8 +32,6 @@ except ImportError: _winreg = None -from collections import OrderedDict - __all__ = [ "knownfiles", "inited", "MimeTypes", "guess_type", "guess_all_extensions", "guess_extension", @@ -411,150 +409,150 @@ def _default_mime_types(): # If you add to these, please keep them sorted by mime type. # Make sure the entry with the preferred file extension for a particular mime type # appears before any others of the same mimetype. - types_map = _types_map_default = OrderedDict([ - ('.js' , 'application/javascript'), - ('.json' , 'application/json'), - ('.doc' , 'application/msword'), - ('.dot' , 'application/msword'), - ('.wiz' , 'application/msword'), - ('.bin' , 'application/octet-stream'), - ('.a' , 'application/octet-stream'), - ('.dll' , 'application/octet-stream'), - ('.exe' , 'application/octet-stream'), - ('.o' , 'application/octet-stream'), - ('.obj' , 'application/octet-stream'), - ('.so' , 'application/octet-stream'), - ('.oda' , 'application/oda'), - ('.pdf' , 'application/pdf'), - ('.p7c' , 'application/pkcs7-mime'), - ('.ps' , 'application/postscript'), - ('.ai' , 'application/postscript'), - ('.eps' , 'application/postscript'), - ('.m3u' , 'application/vnd.apple.mpegurl'), - ('.m3u8' , 'application/vnd.apple.mpegurl'), - ('.xls' , 'application/vnd.ms-excel'), - ('.xlb' , 'application/vnd.ms-excel'), - ('.ppt' , 'application/vnd.ms-powerpoint'), - ('.pot' , 'application/vnd.ms-powerpoint'), - ('.ppa' , 'application/vnd.ms-powerpoint'), - ('.pps' , 'application/vnd.ms-powerpoint'), - ('.pwz' , 'application/vnd.ms-powerpoint'), - ('.bcpio' , 'application/x-bcpio'), - ('.cpio' , 'application/x-cpio'), - ('.csh' , 'application/x-csh'), - ('.dvi' , 'application/x-dvi'), - ('.gtar' , 'application/x-gtar'), - ('.hdf' , 'application/x-hdf'), - ('.latex' , 'application/x-latex'), - ('.mif' , 'application/x-mif'), - ('.cdf' , 'application/x-netcdf'), - ('.nc' , 'application/x-netcdf'), - ('.p12' , 'application/x-pkcs12'), - ('.pfx' , 'application/x-pkcs12'), - ('.ram' , 'application/x-pn-realaudio'), - ('.pyc' , 'application/x-python-code'), - ('.pyo' , 'application/x-python-code'), - ('.sh' , 'application/x-sh'), - ('.shar' , 'application/x-shar'), - ('.swf' , 'application/x-shockwave-flash'), - ('.sv4cpio', 'application/x-sv4cpio'), - ('.sv4crc' , 'application/x-sv4crc'), - ('.tar' , 'application/x-tar'), - ('.tcl' , 'application/x-tcl'), - ('.tex' , 'application/x-tex'), - ('.texi' , 'application/x-texinfo'), - ('.texinfo', 'application/x-texinfo'), - ('.roff' , 'application/x-troff'), - ('.t' , 'application/x-troff'), - ('.tr' , 'application/x-troff'), - ('.man' , 'application/x-troff-man'), - ('.me' , 'application/x-troff-me'), - ('.ms' , 'application/x-troff-ms'), - ('.ustar' , 'application/x-ustar'), - ('.src' , 'application/x-wais-source'), - ('.xsl' , 'application/xml'), - ('.rdf' , 'application/xml'), - ('.wsdl' , 'application/xml'), - ('.xpdl' , 'application/xml'), - ('.zip' , 'application/zip'), - ('.au' , 'audio/basic'), - ('.snd' , 'audio/basic'), - ('.mp3' , 'audio/mpeg'), - ('.mp2' , 'audio/mpeg'), - ('.aif' , 'audio/x-aiff'), - ('.aifc' , 'audio/x-aiff'), - ('.aiff' , 'audio/x-aiff'), - ('.ra' , 'audio/x-pn-realaudio'), - ('.wav' , 'audio/x-wav'), - ('.gif' , 'image/gif'), - ('.ief' , 'image/ief'), - ('.jpg' , 'image/jpeg'), - ('.jpe' , 'image/jpeg'), - ('.jpeg' , 'image/jpeg'), - ('.png' , 'image/png'), - ('.svg' , 'image/svg+xml'), - ('.tiff' , 'image/tiff'), - ('.tif' , 'image/tiff'), - ('.ico' , 'image/vnd.microsoft.icon'), - ('.ras' , 'image/x-cmu-raster'), - ('.bmp' , 'image/x-ms-bmp'), - ('.pnm' , 'image/x-portable-anymap'), - ('.pbm' , 'image/x-portable-bitmap'), - ('.pgm' , 'image/x-portable-graymap'), - ('.ppm' , 'image/x-portable-pixmap'), - ('.rgb' , 'image/x-rgb'), - ('.xbm' , 'image/x-xbitmap'), - ('.xpm' , 'image/x-xpixmap'), - ('.xwd' , 'image/x-xwindowdump'), - ('.eml' , 'message/rfc822'), - ('.mht' , 'message/rfc822'), - ('.mhtml' , 'message/rfc822'), - ('.nws' , 'message/rfc822'), - ('.css' , 'text/css'), - ('.csv' , 'text/csv'), - ('.html' , 'text/html'), - ('.htm' , 'text/html'), - ('.txt' , 'text/plain'), - ('.bat' , 'text/plain'), - ('.c' , 'text/plain'), - ('.h' , 'text/plain'), - ('.ksh' , 'text/plain'), - ('.pl' , 'text/plain'), - ('.rtx' , 'text/richtext'), - ('.tsv' , 'text/tab-separated-values'), - ('.py' , 'text/x-python'), - ('.etx' , 'text/x-setext'), - ('.sgm' , 'text/x-sgml'), - ('.sgml' , 'text/x-sgml'), - ('.vcf' , 'text/x-vcard'), - ('.xml' , 'text/xml'), - ('.mp4' , 'video/mp4'), - ('.mpeg' , 'video/mpeg'), - ('.m1v' , 'video/mpeg'), - ('.mpa' , 'video/mpeg'), - ('.mpe' , 'video/mpeg'), - ('.mpg' , 'video/mpeg'), - ('.mov' , 'video/quicktime'), - ('.qt' , 'video/quicktime'), - ('.webm' , 'video/webm'), - ('.avi' , 'video/x-msvideo'), - ('.movie' , 'video/x-sgi-movie'), - ]) + types_map = _types_map_default = { + '.js' : 'application/javascript', + '.json' : 'application/json', + '.doc' : 'application/msword', + '.dot' : 'application/msword', + '.wiz' : 'application/msword', + '.bin' : 'application/octet-stream', + '.a' : 'application/octet-stream', + '.dll' : 'application/octet-stream', + '.exe' : 'application/octet-stream', + '.o' : 'application/octet-stream', + '.obj' : 'application/octet-stream', + '.so' : 'application/octet-stream', + '.oda' : 'application/oda', + '.pdf' : 'application/pdf', + '.p7c' : 'application/pkcs7-mime', + '.ps' : 'application/postscript', + '.ai' : 'application/postscript', + '.eps' : 'application/postscript', + '.m3u' : 'application/vnd.apple.mpegurl', + '.m3u8' : 'application/vnd.apple.mpegurl', + '.xls' : 'application/vnd.ms-excel', + '.xlb' : 'application/vnd.ms-excel', + '.ppt' : 'application/vnd.ms-powerpoint', + '.pot' : 'application/vnd.ms-powerpoint', + '.ppa' : 'application/vnd.ms-powerpoint', + '.pps' : 'application/vnd.ms-powerpoint', + '.pwz' : 'application/vnd.ms-powerpoint', + '.bcpio' : 'application/x-bcpio', + '.cpio' : 'application/x-cpio', + '.csh' : 'application/x-csh', + '.dvi' : 'application/x-dvi', + '.gtar' : 'application/x-gtar', + '.hdf' : 'application/x-hdf', + '.latex' : 'application/x-latex', + '.mif' : 'application/x-mif', + '.cdf' : 'application/x-netcdf', + '.nc' : 'application/x-netcdf', + '.p12' : 'application/x-pkcs12', + '.pfx' : 'application/x-pkcs12', + '.ram' : 'application/x-pn-realaudio', + '.pyc' : 'application/x-python-code', + '.pyo' : 'application/x-python-code', + '.sh' : 'application/x-sh', + '.shar' : 'application/x-shar', + '.swf' : 'application/x-shockwave-flash', + '.sv4cpio': 'application/x-sv4cpio', + '.sv4crc' : 'application/x-sv4crc', + '.tar' : 'application/x-tar', + '.tcl' : 'application/x-tcl', + '.tex' : 'application/x-tex', + '.texi' : 'application/x-texinfo', + '.texinfo': 'application/x-texinfo', + '.roff' : 'application/x-troff', + '.t' : 'application/x-troff', + '.tr' : 'application/x-troff', + '.man' : 'application/x-troff-man', + '.me' : 'application/x-troff-me', + '.ms' : 'application/x-troff-ms', + '.ustar' : 'application/x-ustar', + '.src' : 'application/x-wais-source', + '.xsl' : 'application/xml', + '.rdf' : 'application/xml', + '.wsdl' : 'application/xml', + '.xpdl' : 'application/xml', + '.zip' : 'application/zip', + '.au' : 'audio/basic', + '.snd' : 'audio/basic', + '.mp3' : 'audio/mpeg', + '.mp2' : 'audio/mpeg', + '.aif' : 'audio/x-aiff', + '.aifc' : 'audio/x-aiff', + '.aiff' : 'audio/x-aiff', + '.ra' : 'audio/x-pn-realaudio', + '.wav' : 'audio/x-wav', + '.gif' : 'image/gif', + '.ief' : 'image/ief', + '.jpg' : 'image/jpeg', + '.jpe' : 'image/jpeg', + '.jpeg' : 'image/jpeg', + '.png' : 'image/png', + '.svg' : 'image/svg+xml', + '.tiff' : 'image/tiff', + '.tif' : 'image/tiff', + '.ico' : 'image/vnd.microsoft.icon', + '.ras' : 'image/x-cmu-raster', + '.bmp' : 'image/x-ms-bmp', + '.pnm' : 'image/x-portable-anymap', + '.pbm' : 'image/x-portable-bitmap', + '.pgm' : 'image/x-portable-graymap', + '.ppm' : 'image/x-portable-pixmap', + '.rgb' : 'image/x-rgb', + '.xbm' : 'image/x-xbitmap', + '.xpm' : 'image/x-xpixmap', + '.xwd' : 'image/x-xwindowdump', + '.eml' : 'message/rfc822', + '.mht' : 'message/rfc822', + '.mhtml' : 'message/rfc822', + '.nws' : 'message/rfc822', + '.css' : 'text/css', + '.csv' : 'text/csv', + '.html' : 'text/html', + '.htm' : 'text/html', + '.txt' : 'text/plain', + '.bat' : 'text/plain', + '.c' : 'text/plain', + '.h' : 'text/plain', + '.ksh' : 'text/plain', + '.pl' : 'text/plain', + '.rtx' : 'text/richtext', + '.tsv' : 'text/tab-separated-values', + '.py' : 'text/x-python', + '.etx' : 'text/x-setext', + '.sgm' : 'text/x-sgml', + '.sgml' : 'text/x-sgml', + '.vcf' : 'text/x-vcard', + '.xml' : 'text/xml', + '.mp4' : 'video/mp4', + '.mpeg' : 'video/mpeg', + '.m1v' : 'video/mpeg', + '.mpa' : 'video/mpeg', + '.mpe' : 'video/mpeg', + '.mpg' : 'video/mpeg', + '.mov' : 'video/quicktime', + '.qt' : 'video/quicktime', + '.webm' : 'video/webm', + '.avi' : 'video/x-msvideo', + '.movie' : 'video/x-sgi-movie', + } # These are non-standard types, commonly found in the wild. They will # only match if strict=0 flag is given to the API methods. # Please sort these too - common_types = _common_types_default = OrderedDict([ - ('.rtf' , 'application/rtf'), - ('.midi', 'audio/midi'), - ('.mid' , 'audio/midi'), - ('.jpg' , 'image/jpg'), - ('.pict', 'image/pict'), - ('.pct' , 'image/pict'), - ('.pic' , 'image/pict'), - ('.xul' , 'text/xul'), - ]) + common_types = _common_types_default = { + '.rtf' : 'application/rtf', + '.midi': 'audio/midi', + '.mid' : 'audio/midi', + '.jpg' : 'image/jpg', + '.pict': 'image/pict', + '.pct' : 'image/pict', + '.pic' : 'image/pict', + '.xul' : 'text/xul', + } _default_mime_types()