Mercurial > vim
diff runtime/doc/if_pyth.txt @ 4851:96e154e825a7 v7.3.1172
updated for version 7.3.1172
Problem: Python 2: loading modules doesn't work well.
Solution: Fix the code. Add more tests. (ZyX)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Wed, 12 Jun 2013 14:20:36 +0200 |
parents | 70b1178dec79 |
children | 52850ef928f8 |
line wrap: on
line diff
--- a/runtime/doc/if_pyth.txt +++ b/runtime/doc/if_pyth.txt @@ -315,52 +315,53 @@ vim.path_hooks in sys.path_hooks python {rtp}/python2 (or python3) and {rtp}/pythonx (for both python versions) for each {rtp} found in 'runtimepath'. -Implementation for python 2 is the following: usual importing code with empty -lists in place of sys.path_hooks and sys.meta_path. Code is similar to the -below, but written in C: > +Implementation for python 2 is similar to the following, but written in C: > - # Assuming vim variable is already accessible and is set to the current - # module + from imp import find_module, load_module + import vim import sys - def find_module(fullname): - return vim + class VimModuleLoader(object): + def __init__(self, module): + self.module = module - def load_module(fullname): - # see vim._get_paths below - new_path = _get_paths() + def load_module(self, fullname, path=None): + return self.module - try: old_path = sys.path - except: pass - try: old_meta_path = sys.meta_path - except: pass - try: old_path_hooks = sys.path_hooks - except: pass - - sys.meta_path = [] - sys.path_hooks = sys.meta_path - sys.path = new_path + def _find_module(fullname, oldtail, path): + idx = oldtail.find('.') + if idx > 0: + name = oldtail[:idx] + tail = oldtail[idx+1:] + fmr = find_module(name, path) + module = load_module(fullname[:-len(oldtail)] + name, *fmr) + return _find_module(fullname, tail, module.__path__) + else: + fmr = find_module(fullname, path) + return load_module(fullname, *fmr) - try: - exec ('import ' + fullname + ' as m') # No actual exec in C code - return m - finally: - e = None - try: sys.path = old_path - except Exception as e: pass - try: sys.meta_path = old_meta_path - except Exception as e: pass - try: sys.path_hooks = old_path_hooks - except Exception as e: pass - if e: - raise e + # It uses vim module itself in place of VimPathFinder class: it does not + # matter for python which object has find_module function attached to as + # an attribute. + class VimPathFinder(object): + def find_module(cls, fullname, path=None): + try: + return VimModuleLoader(_find_module(fullname, fullname, path or vim._get_paths())) + except ImportError: + return None + find_module = classmethod(find_module) - def path_hook(d): - if d == VIM_SPECIAL_PATH: - return vim - raise ImportError + def load_module(cls, fullname, path=None): + return _find_module(fullname, fullname, path or vim._get_paths()) + load_module = classmethod(load_module) - sys.path_hooks.append(path_hook) + def hook(path): + if path == vim.VIM_SPECIAL_PATH: + return VimPathFinder + else: + raise ImportError + + sys.path_hooks.append(hook) Implementation for python 3 is cleaner: code is similar to the following, but, again, written in C: > @@ -395,14 +396,13 @@ vim.VIM_SPECIAL_PATH *python-VIM_SPE Note: you must not use value of this constant directly, always use vim.VIM_SPECIAL_PATH object. -vim.load_module(name) *python-load_module* vim.find_module(...) *python-find_module* vim.path_hook(path) *python-path_hook* Methods or objects used to implement path loading as described above. You should not be using any of these directly except for vim.path_hook in case you need to do something with sys.meta_path. It is not guaranteed that any of the objects will exist in the future vim - versions. In fact, load_module and find_module methods do not exists + versions. In fact, find_module methods do not exists in python3. vim._get_paths *python-_get_paths*