[Python-checkins] cpython: Issue #14578: Support modules registered in the Windows registry again.

martin.v.loewis python-checkins at python.org
Sat Jul 28 21:34:09 CEST 2012


http://hg.python.org/cpython/rev/bd58c421057c
changeset:   78308:bd58c421057c
user:        Martin v. Löwis <martin at v.loewis.de>
date:        Sat Jul 28 21:33:05 2012 +0200
summary:
  Issue #14578: Support modules registered in the Windows registry again.
Patch by Amaury Forgeot d'Arc.

files:
  Lib/importlib/_bootstrap.py |    78 +-
  Misc/NEWS                   |     2 +
  Python/importlib.h          |  8135 +++++++++++-----------
  3 files changed, 4235 insertions(+), 3980 deletions(-)


diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py
--- a/Lib/importlib/_bootstrap.py
+++ b/Lib/importlib/_bootstrap.py
@@ -722,6 +722,56 @@
         return _imp.init_frozen(fullname)
 
 
+class WindowsRegistryImporter:
+
+    """Meta path import for modules declared in the Windows registry.
+    """
+
+    REGISTRY_KEY = (
+        "Software\\Python\\PythonCore\\{sys_version}"
+        "\\Modules\\{fullname}")
+    REGISTRY_KEY_DEBUG = (
+        "Software\\Python\\PythonCore\\{sys_version}"
+        "\\Modules\\{fullname}\\Debug")
+    DEBUG_BUILD = False  # Changed in _setup()
+
+    @classmethod
+    def _open_registry(cls, key):
+        try:
+            return _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, key)
+        except WindowsError:
+            return _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, key)
+
+    @classmethod
+    def _search_registry(cls, fullname):
+        if cls.DEBUG_BUILD:
+            registry_key = cls.REGISTRY_KEY_DEBUG
+        else:
+            registry_key = cls.REGISTRY_KEY
+        key = registry_key.format(fullname=fullname,
+                                  sys_version=sys.version[:3])
+        try:
+            with cls._open_registry(key) as hkey:
+                filepath = _winreg.QueryValue(hkey, "")
+        except WindowsError:
+            return None
+        return filepath
+
+    @classmethod
+    def find_module(cls, fullname, path=None):
+        """Find module named in the registry."""
+        filepath = cls._search_registry(fullname)
+        if filepath is None:
+            return None
+        try:
+            _os.stat(filepath)
+        except OSError:
+            return None
+        for loader, suffixes, _ in _get_supported_file_loaders():
+            if filepath.endswith(tuple(suffixes)):
+                return loader(fullname, filepath)
+
+
 class _LoaderBasics:
 
     """Base class of common code needed by both SourceLoader and
@@ -1538,6 +1588,17 @@
     return package
 
 
+def _get_supported_file_loaders():
+    """Returns a list of file-based module loaders.
+
+    Each item is a tuple (loader, suffixes, allow_packages).
+    """
+    extensions = ExtensionFileLoader, _imp.extension_suffixes(), False
+    source = SourceFileLoader, SOURCE_SUFFIXES, True
+    bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES, True
+    return [extensions, source, bytecode]
+
+
 def __import__(name, globals={}, locals={}, fromlist=[], level=0):
     """Import a module.
 
@@ -1620,6 +1681,10 @@
         thread_module = None
     weakref_module = BuiltinImporter.load_module('_weakref')
 
+    if builtin_os == 'nt':
+        winreg_module = BuiltinImporter.load_module('winreg')
+        setattr(self_module, '_winreg', winreg_module)
+
     setattr(self_module, '_os', os_module)
     setattr(self_module, '_thread', thread_module)
     setattr(self_module, '_weakref', weakref_module)
@@ -1629,14 +1694,17 @@
     setattr(self_module, '_relax_case', _make_relax_case())
     if builtin_os == 'nt':
         SOURCE_SUFFIXES.append('.pyw')
+        if '_d.pyd' in _imp.extension_suffixes():
+            WindowsRegistryImporter.DEBUG_BUILD = True
 
 
 def _install(sys_module, _imp_module):
     """Install importlib as the implementation of import."""
     _setup(sys_module, _imp_module)
-    extensions = ExtensionFileLoader, _imp_module.extension_suffixes(), False
-    source = SourceFileLoader, SOURCE_SUFFIXES, True
-    bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES, True
-    supported_loaders = [extensions, source, bytecode]
+    supported_loaders = _get_supported_file_loaders()
     sys.path_hooks.extend([FileFinder.path_hook(*supported_loaders)])
-    sys.meta_path.extend([BuiltinImporter, FrozenImporter, PathFinder])
+    sys.meta_path.append(BuiltinImporter)
+    sys.meta_path.append(FrozenImporter)
+    if _os.__name__ == 'nt':
+        sys.meta_path.append(WindowsRegistryImporter)
+    sys.meta_path.append(PathFinder)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@
 Core and Builtins
 -----------------
 
+- Issue #14578: Support modules registered in the Windows registry again.
+
 - Issue #15466: Stop using TYPE_INT64 in marshal, to make importlib.h
   (and other byte code files) equal between 32-bit and 64-bit systems.
 
diff --git a/Python/importlib.h b/Python/importlib.h
--- a/Python/importlib.h
+++ b/Python/importlib.h
[stripped]

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list