diff options
author | Steve Dower <steve.dower@python.org> | 2021-07-08 15:48:42 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-08 15:48:42 (GMT) |
commit | bbf2fb6c7ae78f40483606f467739a58cd747270 (patch) | |
tree | 3eeea60d9734f96f979017a3b09beb0a9ca5417f /Lib | |
parent | af4a2dcc40321de49bffec80bf6c6b5a7d43b134 (diff) | |
download | cpython-bbf2fb6c7ae78f40483606f467739a58cd747270.zip cpython-bbf2fb6c7ae78f40483606f467739a58cd747270.tar.gz cpython-bbf2fb6c7ae78f40483606f467739a58cd747270.tar.bz2 |
bpo-44582: Accelerate mimetypes.init on Windows with a native accelerator (GH-27059)
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/mimetypes.py | 27 | ||||
-rw-r--r-- | Lib/test/test_mimetypes.py | 21 |
2 files changed, 42 insertions, 6 deletions
diff --git a/Lib/mimetypes.py b/Lib/mimetypes.py index 4cd9404..b3d70e4 100644 --- a/Lib/mimetypes.py +++ b/Lib/mimetypes.py @@ -27,6 +27,12 @@ import os import sys import posixpath import urllib.parse + +try: + from _winapi import _mimetypes_read_windows_registry +except ImportError: + _mimetypes_read_windows_registry = None + try: import winreg as _winreg except ImportError: @@ -237,10 +243,21 @@ class MimeTypes: types. """ - # Windows only - if not _winreg: + if not _mimetypes_read_windows_registry and not _winreg: return + add_type = self.add_type + if strict: + add_type = lambda type, ext: self.add_type(type, ext, True) + + # Accelerated function if it is available + if _mimetypes_read_windows_registry: + _mimetypes_read_windows_registry(add_type) + elif _winreg: + self._read_windows_registry(add_type) + + @classmethod + def _read_windows_registry(cls, add_type): def enum_types(mimedb): i = 0 while True: @@ -265,7 +282,7 @@ class MimeTypes: subkey, 'Content Type') if datatype != _winreg.REG_SZ: continue - self.add_type(mimetype, subkeyname, strict) + add_type(mimetype, subkeyname) except OSError: continue @@ -349,8 +366,8 @@ def init(files=None): if files is None or _db is None: db = MimeTypes() - if _winreg: - db.read_windows_registry() + # Quick return if not supported + db.read_windows_registry() if files is None: files = knownfiles diff --git a/Lib/test/test_mimetypes.py b/Lib/test/test_mimetypes.py index f5c040a..fb9cb04 100644 --- a/Lib/test/test_mimetypes.py +++ b/Lib/test/test_mimetypes.py @@ -9,6 +9,11 @@ from test import support from test.support import os_helper from platform import win32_edition +try: + import _winapi +except ImportError: + _winapi = None + def setUpModule(): global knownfiles @@ -235,6 +240,21 @@ class Win32MimeTypesTestCase(unittest.TestCase): eq(self.db.guess_type("image.jpg"), ("image/jpeg", None)) eq(self.db.guess_type("image.png"), ("image/png", None)) + @unittest.skipIf(not hasattr(_winapi, "_mimetypes_read_windows_registry"), + "read_windows_registry accelerator unavailable") + def test_registry_accelerator(self): + from_accel = {} + from_reg = {} + _winapi._mimetypes_read_windows_registry( + lambda v, k: from_accel.setdefault(k, set()).add(v) + ) + mimetypes.MimeTypes._read_windows_registry( + lambda v, k: from_reg.setdefault(k, set()).add(v) + ) + self.assertEqual(list(from_reg), list(from_accel)) + for k in from_reg: + self.assertEqual(from_reg[k], from_accel[k]) + class MiscTestCase(unittest.TestCase): def test__all__(self): @@ -288,6 +308,5 @@ class MimetypesCliTestCase(unittest.TestCase): type_info = self.mimetypes_cmd("foo.pic") eq(type_info, "I don't know anything about type foo.pic") - if __name__ == "__main__": unittest.main() |