Mercurial > vim
comparison 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 |
comparison
equal
deleted
inserted
replaced
4850:6c1f3a6714bd | 4851:96e154e825a7 |
---|---|
313 the list of paths found in 'runtimepath': with this directory in sys.path and | 313 the list of paths found in 'runtimepath': with this directory in sys.path and |
314 vim.path_hooks in sys.path_hooks python will try to load module from | 314 vim.path_hooks in sys.path_hooks python will try to load module from |
315 {rtp}/python2 (or python3) and {rtp}/pythonx (for both python versions) for | 315 {rtp}/python2 (or python3) and {rtp}/pythonx (for both python versions) for |
316 each {rtp} found in 'runtimepath'. | 316 each {rtp} found in 'runtimepath'. |
317 | 317 |
318 Implementation for python 2 is the following: usual importing code with empty | 318 Implementation for python 2 is similar to the following, but written in C: > |
319 lists in place of sys.path_hooks and sys.meta_path. Code is similar to the | 319 |
320 below, but written in C: > | 320 from imp import find_module, load_module |
321 | 321 import vim |
322 # Assuming vim variable is already accessible and is set to the current | |
323 # module | |
324 import sys | 322 import sys |
325 | 323 |
326 def find_module(fullname): | 324 class VimModuleLoader(object): |
327 return vim | 325 def __init__(self, module): |
328 | 326 self.module = module |
329 def load_module(fullname): | 327 |
330 # see vim._get_paths below | 328 def load_module(self, fullname, path=None): |
331 new_path = _get_paths() | 329 return self.module |
332 | 330 |
333 try: old_path = sys.path | 331 def _find_module(fullname, oldtail, path): |
334 except: pass | 332 idx = oldtail.find('.') |
335 try: old_meta_path = sys.meta_path | 333 if idx > 0: |
336 except: pass | 334 name = oldtail[:idx] |
337 try: old_path_hooks = sys.path_hooks | 335 tail = oldtail[idx+1:] |
338 except: pass | 336 fmr = find_module(name, path) |
339 | 337 module = load_module(fullname[:-len(oldtail)] + name, *fmr) |
340 sys.meta_path = [] | 338 return _find_module(fullname, tail, module.__path__) |
341 sys.path_hooks = sys.meta_path | 339 else: |
342 sys.path = new_path | 340 fmr = find_module(fullname, path) |
343 | 341 return load_module(fullname, *fmr) |
344 try: | 342 |
345 exec ('import ' + fullname + ' as m') # No actual exec in C code | 343 # It uses vim module itself in place of VimPathFinder class: it does not |
346 return m | 344 # matter for python which object has find_module function attached to as |
347 finally: | 345 # an attribute. |
348 e = None | 346 class VimPathFinder(object): |
349 try: sys.path = old_path | 347 def find_module(cls, fullname, path=None): |
350 except Exception as e: pass | 348 try: |
351 try: sys.meta_path = old_meta_path | 349 return VimModuleLoader(_find_module(fullname, fullname, path or vim._get_paths())) |
352 except Exception as e: pass | 350 except ImportError: |
353 try: sys.path_hooks = old_path_hooks | 351 return None |
354 except Exception as e: pass | 352 find_module = classmethod(find_module) |
355 if e: | 353 |
356 raise e | 354 def load_module(cls, fullname, path=None): |
357 | 355 return _find_module(fullname, fullname, path or vim._get_paths()) |
358 def path_hook(d): | 356 load_module = classmethod(load_module) |
359 if d == VIM_SPECIAL_PATH: | 357 |
360 return vim | 358 def hook(path): |
361 raise ImportError | 359 if path == vim.VIM_SPECIAL_PATH: |
362 | 360 return VimPathFinder |
363 sys.path_hooks.append(path_hook) | 361 else: |
362 raise ImportError | |
363 | |
364 sys.path_hooks.append(hook) | |
364 | 365 |
365 Implementation for python 3 is cleaner: code is similar to the following, but, | 366 Implementation for python 3 is cleaner: code is similar to the following, but, |
366 again, written in C: > | 367 again, written in C: > |
367 | 368 |
368 from importlib.machinery import PathFinder | 369 from importlib.machinery import PathFinder |
393 case it uses special loader. | 394 case it uses special loader. |
394 | 395 |
395 Note: you must not use value of this constant directly, always use | 396 Note: you must not use value of this constant directly, always use |
396 vim.VIM_SPECIAL_PATH object. | 397 vim.VIM_SPECIAL_PATH object. |
397 | 398 |
398 vim.load_module(name) *python-load_module* | |
399 vim.find_module(...) *python-find_module* | 399 vim.find_module(...) *python-find_module* |
400 vim.path_hook(path) *python-path_hook* | 400 vim.path_hook(path) *python-path_hook* |
401 Methods or objects used to implement path loading as described above. | 401 Methods or objects used to implement path loading as described above. |
402 You should not be using any of these directly except for vim.path_hook | 402 You should not be using any of these directly except for vim.path_hook |
403 in case you need to do something with sys.meta_path. It is not | 403 in case you need to do something with sys.meta_path. It is not |
404 guaranteed that any of the objects will exist in the future vim | 404 guaranteed that any of the objects will exist in the future vim |
405 versions. In fact, load_module and find_module methods do not exists | 405 versions. In fact, find_module methods do not exists |
406 in python3. | 406 in python3. |
407 | 407 |
408 vim._get_paths *python-_get_paths* | 408 vim._get_paths *python-_get_paths* |
409 Methods returning a list of paths which will be searched for by path | 409 Methods returning a list of paths which will be searched for by path |
410 hook. You should not rely on this method being present in future | 410 hook. You should not rely on this method being present in future |