summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorSteve Dower <steve.dower@python.org>2021-07-08 15:48:42 (GMT)
committerGitHub <noreply@github.com>2021-07-08 15:48:42 (GMT)
commitbbf2fb6c7ae78f40483606f467739a58cd747270 (patch)
tree3eeea60d9734f96f979017a3b09beb0a9ca5417f /Lib
parentaf4a2dcc40321de49bffec80bf6c6b5a7d43b134 (diff)
downloadcpython-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.py27
-rw-r--r--Lib/test/test_mimetypes.py21
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()