home *** CD-ROM | disk | FTP | other *** search
/ vim.ftp.fu-berlin.de / 2015-02-03.vim.ftp.fu-berlin.de.tar / vim.ftp.fu-berlin.de / patches / 7.3 / 7.3.1163 < prev    next >
Encoding:
Internet Message Format  |  2013-06-09  |  40.9 KB

  1. To: vim_dev@googlegroups.com
  2. Subject: Patch 7.3.1163
  3. Fcc: outbox
  4. From: Bram Moolenaar <Bram@moolenaar.net>
  5. Mime-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. ------------
  9.  
  10. Patch 7.3.1163
  11. Problem:    Not easy to load Python modules.
  12. Solution:   Search "python2", "python3" and "pythonx" directories in
  13.         'runtimepath' for Python modules. (ZyX)
  14. Files:        runtime/doc/if_pyth.txt, src/configure.in, src/ex_cmds2.c,
  15.         src/if_py_both.h, src/if_python.c, src/if_python3.c,
  16.         src/testdir/test86.in, src/testdir/test87.in, src/auto/configure
  17.  
  18.  
  19. *** ../vim-7.3.1162/runtime/doc/if_pyth.txt    2013-06-02 18:20:12.000000000 +0200
  20. --- runtime/doc/if_pyth.txt    2013-06-10 20:51:21.000000000 +0200
  21. ***************
  22. *** 180,185 ****
  23. --- 180,191 ----
  24.       Like |strwidth()|: returns number of display cells str occupies, tab 
  25.       is counted as one cell.
  26.   
  27. + vim.foreach_rtp(callable)                *python-foreach_rtp*
  28. +     Call the given callable for each path in 'runtimepath' until either 
  29. +     callable returns something but None, the exception is raised or there 
  30. +     are no longer paths. If stopped in case callable returned non-None, 
  31. +     vim.foreach_rtp function returns the value returned by callable.
  32.   vim.chdir(*args, **kwargs)                *python-chdir*
  33.   vim.fchdir(*args, **kwargs)                *python-fchdir*
  34.       Run os.chdir or os.fchdir, then all appropriate vim stuff.
  35. ***************
  36. *** 300,305 ****
  37. --- 306,418 ----
  38.       supported, and may cause the program to crash.  This should probably be
  39.       fixed.
  40.   
  41. +             *python2-directory* *python3-directory* *pythonx-directory*
  42. + Python 'runtimepath' handling                *python-special-path*
  43. + In python vim.VIM_SPECIAL_PATH special directory is used as a replacement for 
  44. + the list of paths found in 'runtimepath': with this directory in sys.path and 
  45. + vim.path_hooks in sys.path_hooks python will try to load module from 
  46. + {rtp}/python2 (or python3) and {rtp}/pythonx (for both python versions) for 
  47. + each {rtp} found in 'runtimepath'.
  48. + Implementation for python 2 is the following: usual importing code with empty 
  49. + lists in place of sys.path_hooks and sys.meta_path. Code is similar to the 
  50. + below, but written in C: >
  51. +     # Assuming vim variable is already accessible and is set to the current 
  52. +     # module
  53. +     import sys
  54. +     def find_module(fullname):
  55. +         return vim
  56. +     def load_module(fullname):
  57. +         # see vim._get_paths below
  58. +         new_path = _get_paths()
  59. +         try:         old_path = sys.path
  60. +         except: pass
  61. +         try:         old_meta_path = sys.meta_path
  62. +         except: pass
  63. +         try:         old_path_hooks = sys.path_hooks
  64. +         except: pass
  65. +         sys.meta_path = []
  66. +         sys.path_hooks = sys.meta_path
  67. +         sys.path = new_path
  68. +         try:
  69. +             exec ('import ' + fullname + ' as m')  # No actual exec in C code
  70. +             return m
  71. +         finally:
  72. +             e = None
  73. +             try:                        sys.path = old_path
  74. +             except Exception as e: pass
  75. +             try:                        sys.meta_path = old_meta_path
  76. +             except Exception as e: pass
  77. +             try:                        sys.path_hooks = old_path_hooks
  78. +             except Exception as e: pass
  79. +             if e:
  80. +                 raise e
  81. +     def path_hook(d):
  82. +         if d == VIM_SPECIAL_PATH:
  83. +             return vim
  84. +         raise ImportError
  85. +     sys.path_hooks.append(path_hook)
  86. + Implementation for python 3 is cleaner: code is similar to the following, but, 
  87. + again, written in C: >
  88. +     from importlib.machinery import PathFinder
  89. +     import sys
  90. +     class Finder(PathFinder):
  91. +         @classmethod
  92. +         def find_module(cls, fullname):
  93. +             # see vim._get_paths below
  94. +             new_path = _get_paths()
  95. +             # super().find_module is also a class method
  96. +             # super() is not used because this variant is easier to implement 
  97. +             # in C
  98. +             return PathFinder.find_module(fullname, new_path)
  99. +     def path_hook(path):
  100. +         if path == VIM_SPECIAL_PATH:
  101. +             return Finder
  102. +         raise ImportError
  103. +     sys.path_hooks.append(path_hook)
  104. + vim.VIM_SPECIAL_PATH                    *python-VIM_SPECIAL_PATH*
  105. +     String constant used in conjunction with vim path hook. If path hook 
  106. +     installed by vim is requested to handle anything but path equal to 
  107. +     vim.VIM_SPECIAL_PATH constant it raises ImportError. In the only other 
  108. +     case it uses special loader.
  109. +     Note: you must not use value of this constant directly, always use 
  110. +           vim.VIM_SPECIAL_PATH object.
  111. + vim.load_module(name)                    *python-load_module*
  112. + vim.find_module(...)                    *python-find_module*
  113. + vim.path_hook(path)                    *python-path_hook*
  114. +     Methods or objects used to implement path loading as described above. 
  115. +     You should not be using any of these directly except for vim.path_hook 
  116. +     in case you need to do something with sys.meta_path. It is not 
  117. +     guaranteed that any of the objects will exist in the future vim 
  118. +     versions. In fact, load_module and find_module methods do not exists 
  119. +     in python3.
  120. + vim._get_paths                        *python-_get_paths*
  121. +     Methods returning a list of paths which will be searched for by path 
  122. +     hook. You should not rely on this method being present in future 
  123. +     versions, but can use it for debugging.
  124. +     It returns a list of {rtp}/python2 (or {rtp}/python3) and 
  125. +     {rtp}/pythonx directories for each {rtp} in 'runtimepath'.
  126.   ==============================================================================
  127.   3. Buffer objects                    *python-buffer*
  128.   
  129. ***************
  130. *** 340,346 ****
  131.               |BufFilePost| autocommands are launched.
  132.       b.number    Buffer number. Can be used as |python-buffers| key.
  133.               Read-only.
  134. !     b.valid        True or False. Buffer object becames invalid when 
  135.               corresponding buffer is wiped out.
  136.   
  137.   The buffer object methods are:
  138. --- 453,459 ----
  139.               |BufFilePost| autocommands are launched.
  140.       b.number    Buffer number. Can be used as |python-buffers| key.
  141.               Read-only.
  142. !     b.valid        True or False. Buffer object becomes invalid when 
  143.               corresponding buffer is wiped out.
  144.   
  145.   The buffer object methods are:
  146. ***************
  147. *** 446,452 ****
  148.       row, col (read-only)    On-screen window position in display cells.
  149.                   First position is zero.
  150.       tabpage (read-only)    Window tab page.
  151. !     valid (read-write)    True or False. Window object becames invalid 
  152.                   when corresponding window is closed.
  153.   
  154.   The height attribute is writable only if the screen is split horizontally.
  155. --- 559,565 ----
  156.       row, col (read-only)    On-screen window position in display cells.
  157.                   First position is zero.
  158.       tabpage (read-only)    Window tab page.
  159. !     valid (read-write)    True or False. Window object becomes invalid 
  160.                   when corresponding window is closed.
  161.   
  162.   The height attribute is writable only if the screen is split horizontally.
  163. ***************
  164. *** 471,477 ****
  165.       windows        Like |python-windows|, but for current tab page.
  166.       vars        The tab page |t:| variables.
  167.       window        Current tabpage window.
  168. !     valid        True or False. Tab page object becames invalid when 
  169.               corresponding tab page is closed.
  170.   
  171.   TabPage object type is available using "TabPage" attribute of vim module.
  172. --- 584,590 ----
  173.       windows        Like |python-windows|, but for current tab page.
  174.       vars        The tab page |t:| variables.
  175.       window        Current tabpage window.
  176. !     valid        True or False. Tab page object becomes invalid when 
  177.               corresponding tab page is closed.
  178.   
  179.   TabPage object type is available using "TabPage" attribute of vim module.
  180. *** ../vim-7.3.1162/src/configure.in    2013-06-02 19:14:11.000000000 +0200
  181. --- src/configure.in    2013-06-10 20:51:21.000000000 +0200
  182. ***************
  183. *** 863,872 ****
  184.           ${vi_cv_path_python} -c 'import sys; print sys.version[:3]'`
  185.       ]])
  186.   
  187. !     dnl -- it must be at least version 2.2
  188. !     AC_MSG_CHECKING(Python is 2.2 or better)
  189.       if ${vi_cv_path_python} -c \
  190. !     "import sys; sys.exit(${vi_cv_var_python_version} < 2.2)"
  191.       then
  192.         AC_MSG_RESULT(yep)
  193.   
  194. --- 863,872 ----
  195.           ${vi_cv_path_python} -c 'import sys; print sys.version[:3]'`
  196.       ]])
  197.   
  198. !     dnl -- it must be at least version 2.3
  199. !     AC_MSG_CHECKING(Python is 2.3 or better)
  200.       if ${vi_cv_path_python} -c \
  201. !     "import sys; sys.exit(${vi_cv_var_python_version} < 2.3)"
  202.       then
  203.         AC_MSG_RESULT(yep)
  204.   
  205. *** ../vim-7.3.1162/src/ex_cmds2.c    2013-06-10 20:10:40.000000000 +0200
  206. --- src/ex_cmds2.c    2013-06-10 20:51:21.000000000 +0200
  207. ***************
  208. *** 2737,2742 ****
  209. --- 2737,2746 ----
  210.    * When "all" is TRUE repeat for all matches, otherwise only the first one is
  211.    * used.
  212.    * Returns OK when at least one match found, FAIL otherwise.
  213. +  *
  214. +  * If "name" is NULL calls callback for each entry in runtimepath. Cookie is 
  215. +  * passed by reference in this case, setting it to NULL indicates that callback 
  216. +  * has done its job.
  217.    */
  218.       int
  219.   do_in_runtimepath(name, all, callback, cookie)
  220. ***************
  221. *** 2768,2774 ****
  222.       buf = alloc(MAXPATHL);
  223.       if (buf != NULL && rtp_copy != NULL)
  224.       {
  225. !     if (p_verbose > 1)
  226.       {
  227.           verbose_enter();
  228.           smsg((char_u *)_("Searching for \"%s\" in \"%s\""),
  229. --- 2772,2778 ----
  230.       buf = alloc(MAXPATHL);
  231.       if (buf != NULL && rtp_copy != NULL)
  232.       {
  233. !     if (p_verbose > 1 && name != NULL)
  234.       {
  235.           verbose_enter();
  236.           smsg((char_u *)_("Searching for \"%s\" in \"%s\""),
  237. ***************
  238. *** 2782,2788 ****
  239.       {
  240.           /* Copy the path from 'runtimepath' to buf[]. */
  241.           copy_option_part(&rtp, buf, MAXPATHL, ",");
  242. !         if (STRLEN(buf) + STRLEN(name) + 2 < MAXPATHL)
  243.           {
  244.           add_pathsep(buf);
  245.           tail = buf + STRLEN(buf);
  246. --- 2786,2798 ----
  247.       {
  248.           /* Copy the path from 'runtimepath' to buf[]. */
  249.           copy_option_part(&rtp, buf, MAXPATHL, ",");
  250. !         if (name == NULL)
  251. !         {
  252. !         (*callback)(buf, (void *) &cookie);
  253. !         if (!did_one)
  254. !             did_one = (cookie == NULL);
  255. !         }
  256. !         else if (STRLEN(buf) + STRLEN(name) + 2 < MAXPATHL)
  257.           {
  258.           add_pathsep(buf);
  259.           tail = buf + STRLEN(buf);
  260. ***************
  261. *** 2821,2827 ****
  262.       }
  263.       vim_free(buf);
  264.       vim_free(rtp_copy);
  265. !     if (p_verbose > 0 && !did_one)
  266.       {
  267.       verbose_enter();
  268.       smsg((char_u *)_("not found in 'runtimepath': \"%s\""), name);
  269. --- 2831,2837 ----
  270.       }
  271.       vim_free(buf);
  272.       vim_free(rtp_copy);
  273. !     if (p_verbose > 0 && !did_one && name != NULL)
  274.       {
  275.       verbose_enter();
  276.       smsg((char_u *)_("not found in 'runtimepath': \"%s\""), name);
  277. *** ../vim-7.3.1162/src/if_py_both.h    2013-06-10 20:47:33.000000000 +0200
  278. --- src/if_py_both.h    2013-06-10 20:55:17.000000000 +0200
  279. ***************
  280. *** 24,29 ****
  281. --- 24,31 ----
  282.   #endif
  283.   #define DOPY_FUNC "_vim_pydo"
  284.   
  285. + static const char *vim_special_path = "_vim_path_";
  286.   #define PyErr_SetVim(str) PyErr_SetString(VimError, str)
  287.   
  288.   #define RAISE_NO_EMPTY_KEYS PyErr_SetString(PyExc_ValueError, \
  289. ***************
  290. *** 55,60 ****
  291. --- 57,64 ----
  292.   static PyObject *py_chdir;
  293.   static PyObject *py_fchdir;
  294.   static PyObject *py_getcwd;
  295. + static PyObject *vim_module;
  296. + static PyObject *vim_special_path_object;
  297.   
  298.   /*
  299.    * obtain a lock on the Vim data structures
  300. ***************
  301. *** 779,797 ****
  302.       return _VimChdir(py_fchdir, args, kwargs);
  303.   }
  304.   
  305.   /*
  306.    * Vim module - Definitions
  307.    */
  308.   
  309.   static struct PyMethodDef VimMethods[] = {
  310. !     /* name,         function,            calling,            documentation */
  311. !     {"command",         VimCommand,        METH_VARARGS,            "Execute a Vim ex-mode command" },
  312. !     {"eval",         VimEval,            METH_VARARGS,            "Evaluate an expression using Vim evaluator" },
  313. !     {"bindeval",     VimEvalPy,            METH_VARARGS,            "Like eval(), but returns objects attached to vim ones"},
  314. !     {"strwidth",     VimStrwidth,        METH_VARARGS,            "Screen string width, counts <Tab> as having width 1"},
  315. !     {"chdir",         (PyCFunction)VimChdir,    METH_VARARGS|METH_KEYWORDS,    "Change directory"},
  316. !     {"fchdir",         (PyCFunction)VimFchdir,    METH_VARARGS|METH_KEYWORDS,    "Change directory"},
  317. !     { NULL,         NULL,            0,                NULL }
  318.   };
  319.   
  320.   /*
  321. --- 783,950 ----
  322.       return _VimChdir(py_fchdir, args, kwargs);
  323.   }
  324.   
  325. + typedef struct {
  326. +     PyObject    *callable;
  327. +     PyObject    *result;
  328. + } map_rtp_data;
  329. +     static void
  330. + map_rtp_callback(char_u *path, void *_data)
  331. + {
  332. +     void    **data = (void **) _data;
  333. +     PyObject    *pathObject;
  334. +     map_rtp_data    *mr_data = *((map_rtp_data **) data);
  335. +     if (!(pathObject = PyString_FromString((char *) path)))
  336. +     {
  337. +     *data = NULL;
  338. +     return;
  339. +     }
  340. +     mr_data->result = PyObject_CallFunctionObjArgs(mr_data->callable,
  341. +                            pathObject, NULL);
  342. +     Py_DECREF(pathObject);
  343. +     if (!mr_data->result || mr_data->result != Py_None)
  344. +     *data = NULL;
  345. +     else
  346. +     {
  347. +     Py_DECREF(mr_data->result);
  348. +     mr_data->result = NULL;
  349. +     }
  350. + }
  351. +     static PyObject *
  352. + VimForeachRTP(PyObject *self UNUSED, PyObject *args)
  353. + {
  354. +     map_rtp_data    data;
  355. +     if (!PyArg_ParseTuple(args, "O", &data.callable))
  356. +     return NULL;
  357. +     data.result = NULL;
  358. +     do_in_runtimepath(NULL, FALSE, &map_rtp_callback, &data);
  359. +     if (data.result == NULL)
  360. +     {
  361. +     if (PyErr_Occurred())
  362. +         return NULL;
  363. +     else
  364. +     {
  365. +         Py_INCREF(Py_None);
  366. +         return Py_None;
  367. +     }
  368. +     }
  369. +     return data.result;
  370. + }
  371. + /*
  372. +  * _vim_runtimepath_ special path implementation.
  373. +  */
  374. +     static void
  375. + map_finder_callback(char_u *path, void *_data)
  376. + {
  377. +     void    **data = (void **) _data;
  378. +     PyObject    *list = *((PyObject **) data);
  379. +     PyObject    *pathObject1, *pathObject2;
  380. +     char    *pathbuf;
  381. +     size_t    pathlen;
  382. +     pathlen = STRLEN(path);
  383. + #if PY_MAJOR_VERSION < 3
  384. + # define PY_MAIN_DIR_STRING "python2"
  385. + #else
  386. + # define PY_MAIN_DIR_STRING "python3"
  387. + #endif
  388. + #define PY_ALTERNATE_DIR_STRING "pythonx"
  389. + #define PYTHONX_STRING_LENGTH 7 /* STRLEN("pythonx") */
  390. +     if (!(pathbuf = PyMem_New(char,
  391. +             pathlen + STRLEN(PATHSEPSTR) + PYTHONX_STRING_LENGTH + 1)))
  392. +     {
  393. +     PyErr_NoMemory();
  394. +     *data = NULL;
  395. +     return;
  396. +     }
  397. +     mch_memmove(pathbuf, path, pathlen + 1);
  398. +     add_pathsep((char_u *) pathbuf);
  399. +     pathlen = STRLEN(pathbuf);
  400. +     mch_memmove(pathbuf + pathlen, PY_MAIN_DIR_STRING,
  401. +         PYTHONX_STRING_LENGTH + 1);
  402. +     if (!(pathObject1 = PyString_FromString(pathbuf)))
  403. +     {
  404. +     *data = NULL;
  405. +     PyMem_Free(pathbuf);
  406. +     return;
  407. +     }
  408. +     mch_memmove(pathbuf + pathlen, PY_ALTERNATE_DIR_STRING,
  409. +         PYTHONX_STRING_LENGTH + 1);
  410. +     if (!(pathObject2 = PyString_FromString(pathbuf)))
  411. +     {
  412. +     Py_DECREF(pathObject1);
  413. +     PyMem_Free(pathbuf);
  414. +     *data = NULL;
  415. +     return;
  416. +     }
  417. +     PyMem_Free(pathbuf);
  418. +     if (PyList_Append(list, pathObject1)
  419. +         || PyList_Append(list, pathObject2))
  420. +     *data = NULL;
  421. +     Py_DECREF(pathObject1);
  422. +     Py_DECREF(pathObject2);
  423. + }
  424. +     static PyObject *
  425. + Vim_GetPaths(PyObject *self UNUSED)
  426. + {
  427. +     PyObject    *r;
  428. +     if (!(r = PyList_New(0)))
  429. +     return NULL;
  430. +     do_in_runtimepath(NULL, FALSE, &map_finder_callback, r);
  431. +     if (PyErr_Occurred())
  432. +     {
  433. +     Py_DECREF(r);
  434. +     return NULL;
  435. +     }
  436. +     return r;
  437. + }
  438.   /*
  439.    * Vim module - Definitions
  440.    */
  441.   
  442.   static struct PyMethodDef VimMethods[] = {
  443. !     /* name,        function,            calling,            documentation */
  444. !     {"command",        VimCommand,            METH_VARARGS,            "Execute a Vim ex-mode command" },
  445. !     {"eval",        VimEval,            METH_VARARGS,            "Evaluate an expression using Vim evaluator" },
  446. !     {"bindeval",    VimEvalPy,            METH_VARARGS,            "Like eval(), but returns objects attached to vim ones"},
  447. !     {"strwidth",    VimStrwidth,        METH_VARARGS,            "Screen string width, counts <Tab> as having width 1"},
  448. !     {"chdir",        (PyCFunction)VimChdir,    METH_VARARGS|METH_KEYWORDS,    "Change directory"},
  449. !     {"fchdir",        (PyCFunction)VimFchdir,    METH_VARARGS|METH_KEYWORDS,    "Change directory"},
  450. !     {"foreach_rtp", VimForeachRTP,        METH_VARARGS,            "Call given callable for each path in &rtp"},
  451. ! #if PY_MAJOR_VERSION < 3
  452. !     {"find_module", FinderFindModule,        METH_VARARGS,            "Internal use only, returns loader object for any input it receives"},
  453. !     {"load_module", LoaderLoadModule,        METH_VARARGS,            "Internal use only, tries importing the given module from &rtp by temporary mocking sys.path (to an rtp-based one) and unsetting sys.meta_path and sys.path_hooks"},
  454. ! #endif
  455. !     {"path_hook",   VimPathHook,        METH_VARARGS,            "Hook function to install in sys.path_hooks"},
  456. !     {"_get_paths",  (PyCFunction)Vim_GetPaths,    METH_NOARGS,            "Get &rtp-based additions to sys.path"},
  457. !     { NULL,        NULL,            0,                NULL}
  458.   };
  459.   
  460.   /*
  461. ***************
  462. *** 5036,5041 ****
  463. --- 5189,5202 ----
  464.   } CurrentObject;
  465.   static PyTypeObject CurrentType;
  466.   
  467. + #if PY_MAJOR_VERSION >= 3
  468. + typedef struct
  469. + {
  470. +     PyObject_HEAD
  471. + } FinderObject;
  472. + static PyTypeObject FinderType;
  473. + #endif
  474.       static void
  475.   init_structs(void)
  476.   {
  477. ***************
  478. *** 5281,5286 ****
  479. --- 5442,5522 ----
  480.       PYTYPE_READY(FunctionType);
  481.       PYTYPE_READY(OptionsType);
  482.       PYTYPE_READY(OutputType);
  483. + #if PY_MAJOR_VERSION >= 3
  484. +     PYTYPE_READY(FinderType);
  485. + #endif
  486. +     return 0;
  487. + }
  488. +     static int
  489. + init_sys_path()
  490. + {
  491. +     PyObject    *path;
  492. +     PyObject    *path_hook;
  493. +     PyObject    *path_hooks;
  494. +     if (!(path_hook = PyObject_GetAttrString(vim_module, "path_hook")))
  495. +     return -1;
  496. +     if (!(path_hooks = PySys_GetObject("path_hooks")))
  497. +     {
  498. +     PyErr_Clear();
  499. +     path_hooks = PyList_New(1);
  500. +     PyList_SET_ITEM(path_hooks, 0, path_hook);
  501. +     if (PySys_SetObject("path_hooks", path_hooks))
  502. +     {
  503. +         Py_DECREF(path_hooks);
  504. +         return -1;
  505. +     }
  506. +     Py_DECREF(path_hooks);
  507. +     }
  508. +     else if (PyList_Check(path_hooks))
  509. +     {
  510. +     if (PyList_Append(path_hooks, path_hook))
  511. +     {
  512. +         Py_DECREF(path_hook);
  513. +         return -1;
  514. +     }
  515. +     Py_DECREF(path_hook);
  516. +     }
  517. +     else
  518. +     {
  519. +     VimTryStart();
  520. +     EMSG(_("Failed to set path hook: sys.path_hooks is not a list\n"
  521. +            "You should now do the following:\n"
  522. +            "- append vim.path_hook to sys.path_hooks\n"
  523. +            "- append vim.VIM_SPECIAL_PATH to sys.path\n"));
  524. +     VimTryEnd(); /* Discard the error */
  525. +     Py_DECREF(path_hook);
  526. +     return 0;
  527. +     }
  528. +     if (!(path = PySys_GetObject("path")))
  529. +     {
  530. +     PyErr_Clear();
  531. +     path = PyList_New(1);
  532. +     Py_INCREF(vim_special_path_object);
  533. +     PyList_SET_ITEM(path, 0, vim_special_path_object);
  534. +     if (PySys_SetObject("path", path))
  535. +     {
  536. +         Py_DECREF(path);
  537. +         return -1;
  538. +     }
  539. +     Py_DECREF(path);
  540. +     }
  541. +     else if (PyList_Check(path))
  542. +     {
  543. +     if (PyList_Append(path, vim_special_path_object))
  544. +         return -1;
  545. +     }
  546. +     else
  547. +     {
  548. +     VimTryStart();
  549. +     EMSG(_("Failed to set path: sys.path is not a list\n"
  550. +            "You should now append vim.VIM_SPECIAL_PATH to sys.path"));
  551. +     VimTryEnd(); /* Discard the error */
  552. +     }
  553.       return 0;
  554.   }
  555.   
  556. ***************
  557. *** 5332,5337 ****
  558. --- 5568,5576 ----
  559.       {"List",       (PyObject *)&ListType},
  560.       {"Function",   (PyObject *)&FunctionType},
  561.       {"Options",    (PyObject *)&OptionsType},
  562. + #if PY_MAJOR_VERSION >= 3
  563. +     {"Finder",     (PyObject *)&FinderType},
  564. + #endif
  565.   };
  566.   
  567.   typedef int (*object_adder)(PyObject *, const char *, PyObject *);
  568. ***************
  569. *** 5417,5421 ****
  570. --- 5656,5672 ----
  571.       else
  572.       PyErr_Clear();
  573.   
  574. +     if (!(vim_special_path_object = PyString_FromString(vim_special_path)))
  575. +     return -1;
  576. +     ADD_OBJECT(m, "VIM_SPECIAL_PATH", vim_special_path_object);
  577. + #if PY_MAJOR_VERSION >= 3
  578. +     ADD_OBJECT(m, "_PathFinder", path_finder);
  579. +     ADD_CHECKED_OBJECT(m, "_find_module",
  580. +         (py_find_module = PyObject_GetAttrString(path_finder,
  581. +                              "find_module")));
  582. + #endif
  583.       return 0;
  584.   }
  585. *** ../vim-7.3.1162/src/if_python.c    2013-06-10 20:47:33.000000000 +0200
  586. --- src/if_python.c    2013-06-10 20:55:04.000000000 +0200
  587. ***************
  588. *** 24,32 ****
  589.   /* uncomment this if used with the debug version of python.
  590.    * Checked on 2.7.4. */
  591.   /* #define Py_DEBUG */
  592. ! /* Note: most of time you can add -DPy_DEBUG to CFLAGS in place of uncommenting 
  593.    */
  594. ! /* uncomment this if used with the debug version of python, but without its 
  595.    * allocator */
  596.   /* #define Py_DEBUG_NO_PYMALLOC */
  597.   
  598. --- 24,32 ----
  599.   /* uncomment this if used with the debug version of python.
  600.    * Checked on 2.7.4. */
  601.   /* #define Py_DEBUG */
  602. ! /* Note: most of time you can add -DPy_DEBUG to CFLAGS in place of uncommenting
  603.    */
  604. ! /* uncomment this if used with the debug version of python, but without its
  605.    * allocator */
  606.   /* #define Py_DEBUG_NO_PYMALLOC */
  607.   
  608. ***************
  609. *** 168,173 ****
  610. --- 168,174 ----
  611.   # define PyErr_SetNone dll_PyErr_SetNone
  612.   # define PyErr_SetString dll_PyErr_SetString
  613.   # define PyErr_SetObject dll_PyErr_SetObject
  614. + # define PyErr_ExceptionMatches dll_PyErr_ExceptionMatches
  615.   # define PyEval_InitThreads dll_PyEval_InitThreads
  616.   # define PyEval_RestoreThread dll_PyEval_RestoreThread
  617.   # define PyEval_SaveThread dll_PyEval_SaveThread
  618. ***************
  619. *** 184,189 ****
  620. --- 185,191 ----
  621.   # define PyLong_Type (*dll_PyLong_Type)
  622.   # define PyList_GetItem dll_PyList_GetItem
  623.   # define PyList_Append dll_PyList_Append
  624. + # define PyList_Insert dll_PyList_Insert
  625.   # define PyList_New dll_PyList_New
  626.   # define PyList_SetItem dll_PyList_SetItem
  627.   # define PyList_Size dll_PyList_Size
  628. ***************
  629. *** 233,238 ****
  630. --- 235,241 ----
  631.   # define PyFloat_Type (*dll_PyFloat_Type)
  632.   # define PyImport_AddModule (*dll_PyImport_AddModule)
  633.   # define PySys_SetObject dll_PySys_SetObject
  634. + # define PySys_GetObject dll_PySys_GetObject
  635.   # define PySys_SetArgv dll_PySys_SetArgv
  636.   # define PyType_Type (*dll_PyType_Type)
  637.   # define PyType_Ready (*dll_PyType_Ready)
  638. ***************
  639. *** 305,310 ****
  640. --- 308,314 ----
  641.   static void(*dll_PyErr_SetNone)(PyObject *);
  642.   static void(*dll_PyErr_SetString)(PyObject *, const char *);
  643.   static void(*dll_PyErr_SetObject)(PyObject *, PyObject *);
  644. + static int(*dll_PyErr_ExceptionMatches)(PyObject *);
  645.   static void(*dll_PyEval_InitThreads)(void);
  646.   static void(*dll_PyEval_RestoreThread)(PyThreadState *);
  647.   static PyThreadState*(*dll_PyEval_SaveThread)(void);
  648. ***************
  649. *** 320,326 ****
  650.   static PyTypeObject* dll_PyInt_Type;
  651.   static PyTypeObject* dll_PyLong_Type;
  652.   static PyObject*(*dll_PyList_GetItem)(PyObject *, PyInt);
  653. ! static PyObject*(*dll_PyList_Append)(PyObject *, PyObject *);
  654.   static PyObject*(*dll_PyList_New)(PyInt size);
  655.   static int(*dll_PyList_SetItem)(PyObject *, PyInt, PyObject *);
  656.   static PyInt(*dll_PyList_Size)(PyObject *);
  657. --- 324,331 ----
  658.   static PyTypeObject* dll_PyInt_Type;
  659.   static PyTypeObject* dll_PyLong_Type;
  660.   static PyObject*(*dll_PyList_GetItem)(PyObject *, PyInt);
  661. ! static int(*dll_PyList_Append)(PyObject *, PyObject *);
  662. ! static int(*dll_PyList_Insert)(PyObject *, int, PyObject *);
  663.   static PyObject*(*dll_PyList_New)(PyInt size);
  664.   static int(*dll_PyList_SetItem)(PyObject *, PyInt, PyObject *);
  665.   static PyInt(*dll_PyList_Size)(PyObject *);
  666. ***************
  667. *** 366,371 ****
  668. --- 371,377 ----
  669.   static PyObject*(*dll_PyFloat_FromDouble)(double);
  670.   static PyTypeObject* dll_PyFloat_Type;
  671.   static int(*dll_PySys_SetObject)(char *, PyObject *);
  672. + static PyObject *(*dll_PySys_GetObject)(char *);
  673.   static int(*dll_PySys_SetArgv)(int, char **);
  674.   static PyTypeObject* dll_PyType_Type;
  675.   static int (*dll_PyType_Ready)(PyTypeObject *type);
  676. ***************
  677. *** 431,436 ****
  678. --- 437,443 ----
  679.   static PyObject *imp_PyExc_TypeError;
  680.   static PyObject *imp_PyExc_ValueError;
  681.   static PyObject *imp_PyExc_RuntimeError;
  682. + static PyObject *imp_PyExc_ImportError;
  683.   
  684.   # define PyExc_AttributeError imp_PyExc_AttributeError
  685.   # define PyExc_IndexError imp_PyExc_IndexError
  686. ***************
  687. *** 439,444 ****
  688. --- 446,452 ----
  689.   # define PyExc_TypeError imp_PyExc_TypeError
  690.   # define PyExc_ValueError imp_PyExc_ValueError
  691.   # define PyExc_RuntimeError imp_PyExc_RuntimeError
  692. + # define PyExc_ImportError imp_PyExc_ImportError
  693.   
  694.   /*
  695.    * Table of name to function pointer of python.
  696. ***************
  697. *** 471,476 ****
  698. --- 479,485 ----
  699.       {"PyErr_SetNone", (PYTHON_PROC*)&dll_PyErr_SetNone},
  700.       {"PyErr_SetString", (PYTHON_PROC*)&dll_PyErr_SetString},
  701.       {"PyErr_SetObject", (PYTHON_PROC*)&dll_PyErr_SetObject},
  702. +     {"PyErr_ExceptionMatches", (PYTHON_PROC*)&dll_PyErr_ExceptionMatches},
  703.       {"PyEval_InitThreads", (PYTHON_PROC*)&dll_PyEval_InitThreads},
  704.       {"PyEval_RestoreThread", (PYTHON_PROC*)&dll_PyEval_RestoreThread},
  705.       {"PyEval_SaveThread", (PYTHON_PROC*)&dll_PyEval_SaveThread},
  706. ***************
  707. *** 487,492 ****
  708. --- 496,502 ----
  709.       {"PyLong_Type", (PYTHON_PROC*)&dll_PyLong_Type},
  710.       {"PyList_GetItem", (PYTHON_PROC*)&dll_PyList_GetItem},
  711.       {"PyList_Append", (PYTHON_PROC*)&dll_PyList_Append},
  712. +     {"PyList_Insert", (PYTHON_PROC*)&dll_PyList_Insert},
  713.       {"PyList_New", (PYTHON_PROC*)&dll_PyList_New},
  714.       {"PyList_SetItem", (PYTHON_PROC*)&dll_PyList_SetItem},
  715.       {"PyList_Size", (PYTHON_PROC*)&dll_PyList_Size},
  716. ***************
  717. *** 532,537 ****
  718. --- 542,548 ----
  719.       {"PyFloat_FromDouble", (PYTHON_PROC*)&dll_PyFloat_FromDouble},
  720.       {"PyImport_AddModule", (PYTHON_PROC*)&dll_PyImport_AddModule},
  721.       {"PySys_SetObject", (PYTHON_PROC*)&dll_PySys_SetObject},
  722. +     {"PySys_GetObject", (PYTHON_PROC*)&dll_PySys_GetObject},
  723.       {"PySys_SetArgv", (PYTHON_PROC*)&dll_PySys_SetArgv},
  724.       {"PyType_Type", (PYTHON_PROC*)&dll_PyType_Type},
  725.       {"PyType_Ready", (PYTHON_PROC*)&dll_PyType_Ready},
  726. ***************
  727. *** 706,711 ****
  728. --- 717,723 ----
  729.       imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
  730.       imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
  731.       imp_PyExc_RuntimeError = PyDict_GetItemString(exdict, "RuntimeError");
  732. +     imp_PyExc_ImportError = PyDict_GetItemString(exdict, "ImportError");
  733.       Py_XINCREF(imp_PyExc_AttributeError);
  734.       Py_XINCREF(imp_PyExc_IndexError);
  735.       Py_XINCREF(imp_PyExc_KeyError);
  736. ***************
  737. *** 713,718 ****
  738. --- 725,731 ----
  739.       Py_XINCREF(imp_PyExc_TypeError);
  740.       Py_XINCREF(imp_PyExc_ValueError);
  741.       Py_XINCREF(imp_PyExc_RuntimeError);
  742. +     Py_XINCREF(imp_PyExc_ImportError);
  743.       Py_XDECREF(exmod);
  744.   }
  745.   #endif /* DYNAMIC_PYTHON */
  746. ***************
  747. *** 735,740 ****
  748. --- 748,757 ----
  749.   static PyObject *ListGetattr(PyObject *, char *);
  750.   static PyObject *FunctionGetattr(PyObject *, char *);
  751.   
  752. + static PyObject *LoaderLoadModule(PyObject *, PyObject *);
  753. + static PyObject *FinderFindModule(PyObject *, PyObject *);
  754. + static PyObject *VimPathHook(PyObject *, PyObject *);
  755.   #ifndef Py_VISIT
  756.   # define Py_VISIT(obj) visit(obj, arg)
  757.   #endif
  758. ***************
  759. *** 1359,1369 ****
  760.   }
  761.   #endif
  762.   
  763.       static int
  764.   PythonMod_Init(void)
  765.   {
  766. -     PyObject *mod;
  767.       /* The special value is removed from sys.path in Python_Init(). */
  768.       static char *(argv[2]) = {"/must>not&exist/foo", NULL};
  769.   
  770. --- 1376,1487 ----
  771.   }
  772.   #endif
  773.   
  774. +     static PyObject *
  775. + LoaderLoadModule(PyObject *self, PyObject *args)
  776. + {
  777. +     char    *fullname;
  778. +     PyObject    *path;
  779. +     PyObject    *meta_path;
  780. +     PyObject    *path_hooks;
  781. +     PyObject    *new_path;
  782. +     PyObject    *r;
  783. +     PyObject    *new_list;
  784. +     if (!PyArg_ParseTuple(args, "s", &fullname))
  785. +     return NULL;
  786. +     if (!(new_path = Vim_GetPaths(self)))
  787. +     return NULL;
  788. +     if (!(new_list = PyList_New(0)))
  789. +     return NULL;
  790. + #define GET_SYS_OBJECT(objstr, obj) \
  791. +     obj = PySys_GetObject(objstr); \
  792. +     PyErr_Clear(); \
  793. +     Py_XINCREF(obj);
  794. +     GET_SYS_OBJECT("meta_path", meta_path);
  795. +     if (PySys_SetObject("meta_path", new_list))
  796. +     {
  797. +     Py_XDECREF(meta_path);
  798. +     Py_DECREF(new_list);
  799. +     return NULL;
  800. +     }
  801. +     Py_DECREF(new_list); /* Now it becomes a reference borrowed from
  802. +                 sys.meta_path */
  803. + #define RESTORE_SYS_OBJECT(objstr, obj) \
  804. +     if (obj) \
  805. +     { \
  806. +     PySys_SetObject(objstr, obj); \
  807. +     Py_DECREF(obj); \
  808. +     }
  809. +     GET_SYS_OBJECT("path_hooks", path_hooks);
  810. +     if (PySys_SetObject("path_hooks", new_list))
  811. +     {
  812. +     RESTORE_SYS_OBJECT("meta_path", meta_path);
  813. +     Py_XDECREF(path_hooks);
  814. +     return NULL;
  815. +     }
  816. +     GET_SYS_OBJECT("path", path);
  817. +     if (PySys_SetObject("path", new_path))
  818. +     {
  819. +     RESTORE_SYS_OBJECT("meta_path", meta_path);
  820. +     RESTORE_SYS_OBJECT("path_hooks", path_hooks);
  821. +     Py_XDECREF(path);
  822. +     return NULL;
  823. +     }
  824. +     Py_DECREF(new_path);
  825. +     r = PyImport_ImportModule(fullname);
  826. +     RESTORE_SYS_OBJECT("meta_path", meta_path);
  827. +     RESTORE_SYS_OBJECT("path_hooks", path_hooks);
  828. +     RESTORE_SYS_OBJECT("path", path);
  829. +     if (PyErr_Occurred())
  830. +     {
  831. +     Py_XDECREF(r);
  832. +     return NULL;
  833. +     }
  834. +     return r;
  835. + }
  836. +     static PyObject *
  837. + FinderFindModule(PyObject *self UNUSED, PyObject *args UNUSED)
  838. + {
  839. +     /*
  840. +      * Don't bother actually finding the module, it is delegated to the "loader"
  841. +      * object (which is basically the same object: vim module).
  842. +      */
  843. +     Py_INCREF(vim_module);
  844. +     return vim_module;
  845. + }
  846. +     static PyObject *
  847. + VimPathHook(PyObject *self UNUSED, PyObject *args)
  848. + {
  849. +     char    *path;
  850. +     if (PyArg_ParseTuple(args, "s", &path)
  851. +         && STRCMP(path, vim_special_path) == 0)
  852. +     {
  853. +     Py_INCREF(vim_module);
  854. +     return vim_module;
  855. +     }
  856. +     PyErr_Clear();
  857. +     PyErr_SetNone(PyExc_ImportError);
  858. +     return NULL;
  859. + }
  860.       static int
  861.   PythonMod_Init(void)
  862.   {
  863.       /* The special value is removed from sys.path in Python_Init(). */
  864.       static char *(argv[2]) = {"/must>not&exist/foo", NULL};
  865.   
  866. ***************
  867. *** 1373,1382 ****
  868.       /* Set sys.argv[] to avoid a crash in warn(). */
  869.       PySys_SetArgv(1, argv);
  870.   
  871. !     mod = Py_InitModule4("vim", VimMethods, (char *)NULL, (PyObject *)NULL,
  872. !                 PYTHON_API_VERSION);
  873.   
  874. !     return populate_module(mod, PyModule_AddObject, PyObject_GetAttrString);
  875.   }
  876.   
  877.   /*************************************************************************
  878. --- 1491,1507 ----
  879.       /* Set sys.argv[] to avoid a crash in warn(). */
  880.       PySys_SetArgv(1, argv);
  881.   
  882. !     vim_module = Py_InitModule4("vim", VimMethods, (char *)NULL,
  883. !                 (PyObject *)NULL, PYTHON_API_VERSION);
  884. !     if (populate_module(vim_module, PyModule_AddObject,
  885. !                PyObject_GetAttrString))
  886. !     return -1;
  887. !     if (init_sys_path())
  888. !     return -1;
  889.   
  890. !     return 0;
  891.   }
  892.   
  893.   /*************************************************************************
  894. *** ../vim-7.3.1162/src/if_python3.c    2013-06-10 18:36:20.000000000 +0200
  895. --- src/if_python3.c    2013-06-10 20:55:44.000000000 +0200
  896. ***************
  897. *** 134,139 ****
  898. --- 134,140 ----
  899.   # define PyErr_SetNone py3_PyErr_SetNone
  900.   # define PyErr_SetString py3_PyErr_SetString
  901.   # define PyErr_SetObject py3_PyErr_SetObject
  902. + # define PyErr_ExceptionMatches py3_PyErr_ExceptionMatches
  903.   # define PyEval_InitThreads py3_PyEval_InitThreads
  904.   # define PyEval_RestoreThread py3_PyEval_RestoreThread
  905.   # define PyEval_SaveThread py3_PyEval_SaveThread
  906. ***************
  907. *** 143,148 ****
  908. --- 144,150 ----
  909.   # define PyLong_FromLong py3_PyLong_FromLong
  910.   # define PyList_GetItem py3_PyList_GetItem
  911.   # define PyList_Append py3_PyList_Append
  912. + # define PyList_Insert py3_PyList_Insert
  913.   # define PyList_New py3_PyList_New
  914.   # define PyList_SetItem py3_PyList_SetItem
  915.   # define PyList_Size py3_PyList_Size
  916. ***************
  917. *** 177,182 ****
  918. --- 179,185 ----
  919.   # define PyEval_GetLocals py3_PyEval_GetLocals
  920.   # define PyEval_GetGlobals py3_PyEval_GetGlobals
  921.   # define PySys_SetObject py3_PySys_SetObject
  922. + # define PySys_GetObject py3_PySys_GetObject
  923.   # define PySys_SetArgv py3_PySys_SetArgv
  924.   # define PyType_Ready py3_PyType_Ready
  925.   #undef Py_BuildValue
  926. ***************
  927. *** 268,274 ****
  928.   static PyGILState_STATE (*py3_PyGILState_Ensure)(void);
  929.   static void (*py3_PyGILState_Release)(PyGILState_STATE);
  930.   static int (*py3_PySys_SetObject)(char *, PyObject *);
  931. ! static PyObject* (*py3_PyList_Append)(PyObject *, PyObject *);
  932.   static Py_ssize_t (*py3_PyList_Size)(PyObject *);
  933.   static int (*py3_PySequence_Check)(PyObject *);
  934.   static Py_ssize_t (*py3_PySequence_Size)(PyObject *);
  935. --- 271,279 ----
  936.   static PyGILState_STATE (*py3_PyGILState_Ensure)(void);
  937.   static void (*py3_PyGILState_Release)(PyGILState_STATE);
  938.   static int (*py3_PySys_SetObject)(char *, PyObject *);
  939. ! static PyObject* (*py3_PySys_GetObject)(char *);
  940. ! static int (*py3_PyList_Append)(PyObject *, PyObject *);
  941. ! static int (*py3_PyList_Insert)(PyObject *, int, PyObject *);
  942.   static Py_ssize_t (*py3_PyList_Size)(PyObject *);
  943.   static int (*py3_PySequence_Check)(PyObject *);
  944.   static Py_ssize_t (*py3_PySequence_Size)(PyObject *);
  945. ***************
  946. *** 284,289 ****
  947. --- 289,295 ----
  948.   static void (*py3_Py_Finalize)(void);
  949.   static void (*py3_PyErr_SetString)(PyObject *, const char *);
  950.   static void (*py3_PyErr_SetObject)(PyObject *, PyObject *);
  951. + static int (*py3_PyErr_ExceptionMatches)(PyObject *);
  952.   static int (*py3_PyRun_SimpleString)(char *);
  953.   static PyObject* (*py3_PyRun_String)(char *, int, PyObject *, PyObject *);
  954.   static PyObject* (*py3_PyObject_GetAttrString)(PyObject *, const char *);
  955. ***************
  956. *** 393,398 ****
  957. --- 399,405 ----
  958.   static PyObject *p3imp_PyExc_TypeError;
  959.   static PyObject *p3imp_PyExc_ValueError;
  960.   static PyObject *p3imp_PyExc_RuntimeError;
  961. + static PyObject *p3imp_PyExc_ImportError;
  962.   
  963.   # define PyExc_AttributeError p3imp_PyExc_AttributeError
  964.   # define PyExc_IndexError p3imp_PyExc_IndexError
  965. ***************
  966. *** 401,406 ****
  967. --- 408,414 ----
  968.   # define PyExc_TypeError p3imp_PyExc_TypeError
  969.   # define PyExc_ValueError p3imp_PyExc_ValueError
  970.   # define PyExc_RuntimeError p3imp_PyExc_RuntimeError
  971. + # define PyExc_ImportError p3imp_PyExc_ImportError
  972.   
  973.   /*
  974.    * Table of name to function pointer of python.
  975. ***************
  976. *** 428,434 ****
  977. --- 436,444 ----
  978.       {"PyGILState_Ensure", (PYTHON_PROC*)&py3_PyGILState_Ensure},
  979.       {"PyGILState_Release", (PYTHON_PROC*)&py3_PyGILState_Release},
  980.       {"PySys_SetObject", (PYTHON_PROC*)&py3_PySys_SetObject},
  981. +     {"PySys_GetObject", (PYTHON_PROC*)&py3_PySys_GetObject},
  982.       {"PyList_Append", (PYTHON_PROC*)&py3_PyList_Append},
  983. +     {"PyList_Insert", (PYTHON_PROC*)&py3_PyList_Insert},
  984.       {"PyList_Size", (PYTHON_PROC*)&py3_PyList_Size},
  985.       {"PySequence_Check", (PYTHON_PROC*)&py3_PySequence_Check},
  986.       {"PySequence_Size", (PYTHON_PROC*)&py3_PySequence_Size},
  987. ***************
  988. *** 441,446 ****
  989. --- 451,457 ----
  990.       {"Py_Finalize", (PYTHON_PROC*)&py3_Py_Finalize},
  991.       {"PyErr_SetString", (PYTHON_PROC*)&py3_PyErr_SetString},
  992.       {"PyErr_SetObject", (PYTHON_PROC*)&py3_PyErr_SetObject},
  993. +     {"PyErr_ExceptionMatches", (PYTHON_PROC*)&py3_PyErr_ExceptionMatches},
  994.       {"PyRun_SimpleString", (PYTHON_PROC*)&py3_PyRun_SimpleString},
  995.       {"PyRun_String", (PYTHON_PROC*)&py3_PyRun_String},
  996.       {"PyObject_GetAttrString", (PYTHON_PROC*)&py3_PyObject_GetAttrString},
  997. ***************
  998. *** 664,669 ****
  999. --- 675,681 ----
  1000.       p3imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
  1001.       p3imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
  1002.       p3imp_PyExc_RuntimeError = PyDict_GetItemString(exdict, "RuntimeError");
  1003. +     p3imp_PyExc_ImportError = PyDict_GetItemString(exdict, "ImportError");
  1004.       Py_XINCREF(p3imp_PyExc_AttributeError);
  1005.       Py_XINCREF(p3imp_PyExc_IndexError);
  1006.       Py_XINCREF(p3imp_PyExc_KeyError);
  1007. ***************
  1008. *** 671,676 ****
  1009. --- 683,689 ----
  1010.       Py_XINCREF(p3imp_PyExc_TypeError);
  1011.       Py_XINCREF(p3imp_PyExc_ValueError);
  1012.       Py_XINCREF(p3imp_PyExc_RuntimeError);
  1013. +     Py_XINCREF(p3imp_PyExc_ImportError);
  1014.       Py_XDECREF(exmod);
  1015.   }
  1016.   #endif /* DYNAMIC_PYTHON3 */
  1017. ***************
  1018. *** 723,730 ****
  1019. --- 736,748 ----
  1020.   static int ListSetattro(PyObject *, PyObject *, PyObject *);
  1021.   static PyObject *FunctionGetattro(PyObject *, PyObject *);
  1022.   
  1023. + static PyObject *VimPathHook(PyObject *, PyObject *);
  1024.   static struct PyModuleDef vimmodule;
  1025.   
  1026. + static PyObject *path_finder;
  1027. + static PyObject *py_find_module = NULL;
  1028.   #define PY_CAN_RECURSE
  1029.   
  1030.   /*
  1031. ***************
  1032. *** 1585,1596 ****
  1033.   #endif
  1034.   
  1035.       static PyObject *
  1036. ! Py3Init_vim(void)
  1037.   {
  1038. !     PyObject *mod;
  1039.   
  1040.       /* The special value is removed from sys.path in Python3_Init(). */
  1041.       static wchar_t *(argv[2]) = {L"/must>not&exist/foo", NULL};
  1042.   
  1043.       if (init_types())
  1044.       return NULL;
  1045. --- 1603,1672 ----
  1046.   #endif
  1047.   
  1048.       static PyObject *
  1049. ! VimPathHook(PyObject *self UNUSED, PyObject *args)
  1050.   {
  1051. !     char    *path;
  1052. !     if (PyArg_ParseTuple(args, "s", &path)
  1053. !         && STRCMP(path, vim_special_path) == 0)
  1054. !     {
  1055. !     Py_INCREF(&FinderType);
  1056. !     return (PyObject *) &FinderType;
  1057. !     }
  1058. !     PyErr_Clear();
  1059. !     PyErr_SetNone(PyExc_ImportError);
  1060. !     return NULL;
  1061. ! }
  1062. !     static PyObject *
  1063. ! FinderFindModule(PyObject *cls UNUSED, PyObject *fullname)
  1064. ! {
  1065. !     PyObject    *new_path;
  1066. !     PyObject    *r;
  1067. !     if (!(new_path = Vim_GetPaths(NULL)))
  1068. !     return NULL;
  1069. !     /* call find_module of the super() class */
  1070. !     r = PyObject_CallFunctionObjArgs(py_find_module, fullname, new_path, NULL);
  1071. !     Py_DECREF(new_path);
  1072. !     return r;
  1073. ! }
  1074.   
  1075. + static struct PyMethodDef FinderMethods[] = {
  1076. +     {"find_module",    FinderFindModule,    METH_CLASS|METH_O,    ""},
  1077. +     {NULL,        NULL,            0,            NULL}
  1078. + };
  1079. +     static PyObject *
  1080. + Py3Init_vim(void)
  1081. + {
  1082.       /* The special value is removed from sys.path in Python3_Init(). */
  1083.       static wchar_t *(argv[2]) = {L"/must>not&exist/foo", NULL};
  1084. +     PyObject    *importlib_machinery;
  1085. +     if (!(importlib_machinery = PyImport_ImportModule("importlib.machinery")))
  1086. +     return NULL;
  1087. +     if (!(path_finder = PyObject_GetAttrString(importlib_machinery,
  1088. +                            "PathFinder")))
  1089. +     {
  1090. +     Py_DECREF(importlib_machinery);
  1091. +     return NULL;
  1092. +     }
  1093. +     Py_DECREF(importlib_machinery);
  1094. +     vim_memset(&FinderType, 0, sizeof(FinderObject));
  1095. +     FinderType.tp_name = "vim.Finder";
  1096. +     FinderType.tp_basicsize = sizeof(FinderObject);
  1097. +     FinderType.tp_base = (PyTypeObject *) path_finder;
  1098. +     FinderType.tp_flags = Py_TPFLAGS_DEFAULT;
  1099. +     FinderType.tp_doc = "Vim finder class, for use with path hook";
  1100. +     FinderType.tp_methods = FinderMethods;
  1101.   
  1102.       if (init_types())
  1103.       return NULL;
  1104. ***************
  1105. *** 1598,1611 ****
  1106.       /* Set sys.argv[] to avoid a crash in warn(). */
  1107.       PySys_SetArgv(1, argv);
  1108.   
  1109. !     mod = PyModule_Create(&vimmodule);
  1110. !     if (mod == NULL)
  1111.       return NULL;
  1112.   
  1113. !     if (populate_module(mod, PyModule_AddObject, PyObject_GetAttrString))
  1114.       return NULL;
  1115.   
  1116. !     return mod;
  1117.   }
  1118.   
  1119.   /*************************************************************************
  1120. --- 1674,1689 ----
  1121.       /* Set sys.argv[] to avoid a crash in warn(). */
  1122.       PySys_SetArgv(1, argv);
  1123.   
  1124. !     if ((vim_module = PyModule_Create(&vimmodule)) == NULL)
  1125. !     return NULL;
  1126. !     if (populate_module(vim_module, PyModule_AddObject, PyObject_GetAttrString))
  1127.       return NULL;
  1128.   
  1129. !     if (init_sys_path())
  1130.       return NULL;
  1131.   
  1132. !     return vim_module;
  1133.   }
  1134.   
  1135.   /*************************************************************************
  1136. *** ../vim-7.3.1162/src/testdir/test86.in    2013-06-02 18:54:16.000000000 +0200
  1137. --- src/testdir/test86.in    2013-06-10 21:05:44.000000000 +0200
  1138. ***************
  1139. *** 1069,1074 ****
  1140. --- 1069,1082 ----
  1141.   ee('vim.current.xxx = True')
  1142.   EOF
  1143.   :"
  1144. + :" Test import  TODO: BROKEN
  1145. + :"py << EOF
  1146. + :"vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
  1147. + :"from module import dir as d
  1148. + :"from modulex import ddir
  1149. + :"cb.append(d + ',' + ddir)
  1150. + :"EOF
  1151. + :"
  1152.   :" Test exceptions
  1153.   :fun Exe(e)
  1154.   :   execute a:e
  1155. *** ../vim-7.3.1162/src/testdir/test87.in    2013-06-02 18:54:16.000000000 +0200
  1156. --- src/testdir/test87.in    2013-06-10 21:06:37.000000000 +0200
  1157. ***************
  1158. *** 1036,1041 ****
  1159. --- 1036,1049 ----
  1160.   ee('vim.current.xxx = True')
  1161.   EOF
  1162.   :"
  1163. + :" Test import  TODO: BROKEN
  1164. + :"py3 << EOF
  1165. + :"vim.options['rtp'] = os.getcwd().replace(',', '\\,').replace('\\', '\\\\')
  1166. + :"from module import dir as d
  1167. + :"from modulex import ddir
  1168. + :"cb.append(d + ',' + ddir)
  1169. + :"EOF
  1170. + :"
  1171.   :" Test exceptions
  1172.   :fun Exe(e)
  1173.   :   execute a:e
  1174. *** ../vim-7.3.1162/src/auto/configure    2013-06-02 19:14:11.000000000 +0200
  1175. --- src/auto/configure    2013-06-10 21:22:52.000000000 +0200
  1176. ***************
  1177. *** 5289,5298 ****
  1178.   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $vi_cv_var_python_version" >&5
  1179.   $as_echo "$vi_cv_var_python_version" >&6; }
  1180.   
  1181. !         { $as_echo "$as_me:${as_lineno-$LINENO}: checking Python is 2.2 or better" >&5
  1182. ! $as_echo_n "checking Python is 2.2 or better... " >&6; }
  1183.       if ${vi_cv_path_python} -c \
  1184. !     "import sys; sys.exit(${vi_cv_var_python_version} < 2.2)"
  1185.       then
  1186.         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yep" >&5
  1187.   $as_echo "yep" >&6; }
  1188. --- 5289,5298 ----
  1189.   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $vi_cv_var_python_version" >&5
  1190.   $as_echo "$vi_cv_var_python_version" >&6; }
  1191.   
  1192. !         { $as_echo "$as_me:${as_lineno-$LINENO}: checking Python is 2.3 or better" >&5
  1193. ! $as_echo_n "checking Python is 2.3 or better... " >&6; }
  1194.       if ${vi_cv_path_python} -c \
  1195. !     "import sys; sys.exit(${vi_cv_var_python_version} < 2.3)"
  1196.       then
  1197.         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yep" >&5
  1198.   $as_echo "yep" >&6; }
  1199. *** ../vim-7.3.1162/src/version.c    2013-06-10 20:47:33.000000000 +0200
  1200. --- src/version.c    2013-06-10 20:53:23.000000000 +0200
  1201. ***************
  1202. *** 730,731 ****
  1203. --- 730,733 ----
  1204.   {   /* Add new patch number below this line */
  1205. + /**/
  1206. +     1163,
  1207.   /**/
  1208.  
  1209. -- 
  1210. The coffee just wasn't strong enough to defend itself -- Tom Waits
  1211.  
  1212.  /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
  1213. ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
  1214. \\\  an exciting new programming language -- http://www.Zimbu.org        ///
  1215.  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///
  1216.