1
0
forked from aniani/vim

updated for version 7.3.1172

Problem:    Python 2: loading modules doesn't work well.
Solution:   Fix the code. Add more tests. (ZyX)
This commit is contained in:
Bram Moolenaar
2013-06-12 14:20:36 +02:00
parent 0ea4a6b94b
commit 9f3685a527
13 changed files with 243 additions and 107 deletions

View File

@@ -315,52 +315,53 @@ vim.path_hooks in sys.path_hooks python will try to load module from
{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
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)
sys.meta_path = []
sys.path_hooks = sys.meta_path
sys.path = new_path
# 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)
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
def load_module(cls, fullname, path=None):
return _find_module(fullname, fullname, path or vim._get_paths())
load_module = classmethod(load_module)
def path_hook(d):
if d == VIM_SPECIAL_PATH:
return vim
raise ImportError
def hook(path):
if path == vim.VIM_SPECIAL_PATH:
return VimPathFinder
else:
raise ImportError
sys.path_hooks.append(path_hook)
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_SPECIAL_PATH*
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*