diff options
author | Barry Warsaw <barry@python.org> | 2012-07-29 20:40:04 (GMT) |
---|---|---|
committer | Barry Warsaw <barry@python.org> | 2012-07-29 20:40:04 (GMT) |
commit | dee609c09fb9a09d5e341e2f5975150016f85f00 (patch) | |
tree | d2bed8f6bc932a2b4a6787827cb38cadbe92deba /Lib/importlib | |
parent | dde56f4aa321edb293f64f0dfc519ef48b3dfece (diff) | |
parent | a264384fe6de357680ca0cf02cd6024bbba0ba45 (diff) | |
download | cpython-dee609c09fb9a09d5e341e2f5975150016f85f00.zip cpython-dee609c09fb9a09d5e341e2f5975150016f85f00.tar.gz cpython-dee609c09fb9a09d5e341e2f5975150016f85f00.tar.bz2 |
merged
Diffstat (limited to 'Lib/importlib')
-rw-r--r-- | Lib/importlib/_bootstrap.py | 89 |
1 files changed, 82 insertions, 7 deletions
diff --git a/Lib/importlib/_bootstrap.py b/Lib/importlib/_bootstrap.py index 780928a..6a869f7 100644 --- a/Lib/importlib/_bootstrap.py +++ b/Lib/importlib/_bootstrap.py @@ -722,6 +722,56 @@ class FrozenImporter: 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 @@ -1422,7 +1472,7 @@ def _find_and_load_unlocked(name, import_): parent = name.rpartition('.')[0] if parent: if parent not in sys.modules: - import_(parent) + _recursive_import(import_, parent) # Crazy side-effects! if name in sys.modules: return sys.modules[name] @@ -1500,6 +1550,12 @@ def _gcd_import(name, package=None, level=0): _lock_unlock_module(name) return module +def _recursive_import(import_, name): + """Common exit point for recursive calls to the import machinery + + This simplifies the process of stripping importlib from tracebacks + """ + return import_(name) def _handle_fromlist(module, fromlist, import_): """Figure out what __import__ should return. @@ -1519,7 +1575,8 @@ def _handle_fromlist(module, fromlist, import_): fromlist.extend(module.__all__) for x in fromlist: if not hasattr(module, x): - import_('{}.{}'.format(module.__name__, x)) + _recursive_import(import_, + '{}.{}'.format(module.__name__, x)) return module @@ -1538,6 +1595,17 @@ def _calc___package__(globals): 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 +1688,10 @@ def _setup(sys_module, _imp_module): 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 +1701,17 @@ def _setup(sys_module, _imp_module): 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) |