Merged revisions 76306 via svnmerge from

svn+ssh://pythondev@svn.python.org/python/trunk

........
  r76306 | antoine.pitrou | 2009-11-15 15:10:48 +0100 (dim., 15 nov. 2009) | 4 lines

  Issue #4969: The mimetypes module now reads the MIME database from
  the registry under Windows.  Patch by Gabriel Genellina.
........
This commit is contained in:
Antoine Pitrou 2009-11-15 14:25:16 +00:00
parent 6f1d04945b
commit b8108e2425
4 changed files with 89 additions and 5 deletions

View File

@ -76,9 +76,13 @@ behavior of the module.
Initialize the internal data structures. If given, *files* must be a sequence
of file names which should be used to augment the default type map. If omitted,
the file names to use are taken from :const:`knownfiles`. Each file named in
*files* or :const:`knownfiles` takes precedence over those named before it.
Calling :func:`init` repeatedly is allowed.
the file names to use are taken from :const:`knownfiles`; on Windows, the
current registry settings are loaded. Each file named in *files* or
:const:`knownfiles` takes precedence over those named before it. Calling
:func:`init` repeatedly is allowed.
.. versionchanged:: 3.2
Previously, Windows registry settings were ignored.
.. function:: read_mime_types(filename)
@ -228,3 +232,9 @@ MimeTypes Objects
Load MIME type information from an open file. The file must have the format of
the standard :file:`mime.types` files.
.. method:: MimeTypes.read_windows_registry()
Load MIME type information from the Windows registry. Availability: Windows.
.. versionadded:: 3.2

View File

@ -18,13 +18,19 @@ types_map -- dictionary mapping suffixes to types
Functions:
init([files]) -- parse a list of files, default knownfiles
init([files]) -- parse a list of files, default knownfiles (on Windows, the
default values are taken from the registry)
read_mime_types(file) -- parse one file, return a dictionary or None
"""
import os
import sys
import posixpath
import urllib.parse
try:
import winreg as _winreg
except ImportError:
_winreg = None
__all__ = [
"guess_type","guess_extension","guess_all_extensions",
@ -220,6 +226,44 @@ class MimeTypes:
for suff in suffixes:
self.add_type(type, '.' + suff, strict)
def read_windows_registry(self, strict=True):
"""
Load the MIME types database from Windows registry.
If strict is true, information will be added to
list of standard types, else to the list of non-standard
types.
"""
# Windows only
if not _winreg:
return
def enum_types(mimedb):
i = 0
while True:
try:
ctype = _winreg.EnumKey(mimedb, i)
except EnvironmentError:
break
else:
yield ctype
i += 1
default_encoding = sys.getdefaultencoding()
with _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT,
r'MIME\Database\Content Type') as mimedb:
for ctype in enum_types(mimedb):
with _winreg.OpenKey(mimedb, ctype) as key:
try:
suffix, datatype = _winreg.QueryValueEx(key, 'Extension')
except EnvironmentError:
continue
if datatype != _winreg.REG_SZ:
continue
self.add_type(ctype, suffix, strict)
def guess_type(url, strict=True):
"""Guess the type of a file based on its URL.
@ -299,6 +343,8 @@ def init(files=None):
inited = True # so that MimeTypes.__init__() doesn't call us again
db = MimeTypes()
if files is None:
if _winreg:
db.read_windows_registry()
files = knownfiles
for file in files:
if os.path.isfile(file):

View File

@ -1,6 +1,7 @@
import mimetypes
import io
import unittest
import sys
from test import support
@ -62,8 +63,32 @@ class MimeTypesTestCase(unittest.TestCase):
eq(all, [])
@unittest.skipUnless(sys.platform.startswith("win"), "Windows only")
class Win32MimeTypesTestCase(unittest.TestCase):
def setUp(self):
# ensure all entries actually come from the Windows registry
self.original_types_map = mimetypes.types_map.copy()
mimetypes.types_map.clear()
mimetypes.init()
self.db = mimetypes.MimeTypes()
def tearDown(self):
# restore default settings
mimetypes.types_map.clear()
mimetypes.types_map.update(self.original_types_map)
def test_registry_parsing(self):
# the original, minimum contents of the MIME database in the
# Windows registry is undocumented AFAIK.
# Use file types that should *always* exist:
eq = self.assertEqual
eq(self.db.guess_type("foo.txt"), ("text/plain", None))
def test_main():
support.run_unittest(MimeTypesTestCase)
support.run_unittest(MimeTypesTestCase,
Win32MimeTypesTestCase
)
if __name__ == "__main__":

View File

@ -132,6 +132,9 @@ C-API
Library
-------
- Issue #4969: The mimetypes module now reads the MIME database from
the registry under Windows. Patch by Gabriel Genellina.
- Issue #7318: multiprocessing now uses a timeout when it fails to establish
a connection with another process, rather than looping endlessly. The
default timeout is 20 seconds, which should be amply sufficient for