summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2013-06-12 14:41:04 +0200
committerBram Moolenaar <Bram@vim.org>2013-06-12 14:41:04 +0200
commit81c40c507c69ab0c3aede3ee14a2ba76c20c4595 (patch)
tree21bb9f8a713de4a223ab7b581c90207a79cfdb97
parent27610ed76c500cf680fdbac000d269e30dcba54c (diff)
updated for version 7.3.1174v7.3.1174
Problem: Python 2 and 3 use different ways to load modules. Solution: Use the same method. (ZyX)
-rw-r--r--runtime/doc/if_pyth.txt33
-rw-r--r--src/if_py_both.h238
-rw-r--r--src/if_python.c199
-rw-r--r--src/if_python3.c66
-rw-r--r--src/version.c2
5 files changed, 213 insertions, 325 deletions
diff --git a/runtime/doc/if_pyth.txt b/runtime/doc/if_pyth.txt
index b394b87021..53203311ce 100644
--- a/runtime/doc/if_pyth.txt
+++ b/runtime/doc/if_pyth.txt
@@ -315,7 +315,7 @@ 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 similar to the following, but written in C: >
+Implementation is similar to the following, but written in C: >
from imp import find_module, load_module
import vim
@@ -344,16 +344,16 @@ Implementation for python 2 is similar to the following, but written in C: >
# matter for python which object has find_module function attached to as
# an attribute.
class VimPathFinder(object):
+ @classmethod
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)
+ @classmethod
def load_module(cls, fullname, path=None):
return _find_module(fullname, fullname, path or vim._get_paths())
- load_module = classmethod(load_module)
def hook(path):
if path == vim.VIM_SPECIAL_PATH:
@@ -363,30 +363,6 @@ Implementation for python 2 is similar to the following, but written in C: >
sys.path_hooks.append(hook)
-Implementation for python 3 is cleaner: code is similar to the following, but,
-again, written in C: >
-
- from importlib.machinery import PathFinder
- import sys
-
- class Finder(PathFinder):
- @classmethod
- def find_module(cls, fullname):
- # see vim._get_paths below
- new_path = _get_paths()
-
- # super().find_module is also a class method
- # super() is not used because this variant is easier to implement
- # in C
- return PathFinder.find_module(fullname, new_path)
-
- def path_hook(path):
- if path == VIM_SPECIAL_PATH:
- return Finder
- raise ImportError
-
- sys.path_hooks.append(path_hook)
-
vim.VIM_SPECIAL_PATH *python-VIM_SPECIAL_PATH*
String constant used in conjunction with vim path hook. If path hook
installed by vim is requested to handle anything but path equal to
@@ -402,8 +378,7 @@ vim.path_hook(path) *python-path_hook*
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, find_module methods do not exists
- in python3.
+ versions.
vim._get_paths *python-_get_paths*
Methods returning a list of paths which will be searched for by path
diff --git a/src/if_py_both.h b/src/if_py_both.h
index bd1d70434f..e5d8d5e37d 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -60,6 +60,11 @@ static PyObject *py_getcwd;
static PyObject *vim_module;
static PyObject *vim_special_path_object;
+static PyObject *py_find_module;
+static PyObject *py_load_module;
+
+static PyObject *VimError;
+
/*
* obtain a lock on the Vim data structures
*/
@@ -393,8 +398,34 @@ PythonIO_Init_io(void)
return 0;
}
+typedef struct
+{
+ PyObject_HEAD
+ PyObject *module;
+} LoaderObject;
+static PyTypeObject LoaderType;
+
+ static void
+LoaderDestructor(LoaderObject *self)
+{
+ Py_DECREF(self->module);
+ DESTRUCTOR_FINISH(self);
+}
+
+ static PyObject *
+LoaderLoadModule(LoaderObject *self, PyObject *args UNUSED)
+{
+ PyObject *r = self->module;
-static PyObject *VimError;
+ Py_INCREF(r);
+ return r;
+}
+
+static struct PyMethodDef LoaderMethods[] = {
+ /* name, function, calling, doc */
+ {"load_module", (PyCFunction)LoaderLoadModule, METH_VARARGS, ""},
+ { NULL, NULL, 0, NULL}
+};
/* Check to see whether a Vim error has been reported, or a keyboard
* interrupt has been detected.
@@ -925,6 +956,150 @@ Vim_GetPaths(PyObject *self UNUSED)
return r;
}
+ static PyObject *
+call_load_module(char *name, int len, PyObject *find_module_result)
+{
+ PyObject *fd, *pathname, *description;
+
+ if (!PyTuple_Check(find_module_result)
+ || PyTuple_GET_SIZE(find_module_result) != 3)
+ {
+ PyErr_SetString(PyExc_TypeError,
+ _("expected 3-tuple as imp.find_module() result"));
+ return NULL;
+ }
+
+ if (!(fd = PyTuple_GET_ITEM(find_module_result, 0))
+ || !(pathname = PyTuple_GET_ITEM(find_module_result, 1))
+ || !(description = PyTuple_GET_ITEM(find_module_result, 2)))
+ {
+ PyErr_SetString(PyExc_RuntimeError,
+ _("internal error: imp.find_module returned tuple with NULL"));
+ return NULL;
+ }
+
+ return PyObject_CallFunction(py_load_module,
+ "s#OOO", name, len, fd, pathname, description);
+}
+
+ static PyObject *
+find_module(char *fullname, char *tail, PyObject *new_path)
+{
+ PyObject *find_module_result;
+ PyObject *module;
+ char *dot;
+
+ if ((dot = (char *) vim_strchr((char_u *) tail, '.')))
+ {
+ /*
+ * There is a dot in the name: call find_module recursively without the
+ * first component
+ */
+ PyObject *newest_path;
+ int partlen = (int) (dot - 1 - tail);
+
+ if (!(find_module_result = PyObject_CallFunction(py_find_module,
+ "s#O", tail, partlen, new_path)))
+ return NULL;
+
+ if (!(module = call_load_module(
+ fullname,
+ ((int) (tail - fullname)) + partlen,
+ find_module_result)))
+ {
+ Py_DECREF(find_module_result);
+ return NULL;
+ }
+
+ Py_DECREF(find_module_result);
+
+ if (!(newest_path = PyObject_GetAttrString(module, "__path__")))
+ {
+ Py_DECREF(module);
+ return NULL;
+ }
+
+ Py_DECREF(module);
+
+ module = find_module(fullname, dot + 1, newest_path);
+
+ Py_DECREF(newest_path);
+
+ return module;
+ }
+ else
+ {
+ if (!(find_module_result = PyObject_CallFunction(py_find_module,
+ "sO", tail, new_path)))
+ return NULL;
+
+ if (!(module = call_load_module(
+ fullname,
+ STRLEN(fullname),
+ find_module_result)))
+ {
+ Py_DECREF(find_module_result);
+ return NULL;
+ }
+
+ Py_DECREF(find_module_result);
+
+ return module;
+ }
+}
+
+ static PyObject *
+FinderFindModule(PyObject *self, PyObject *args)
+{
+ char *fullname;
+ PyObject *module;
+ PyObject *new_path;
+ LoaderObject *loader;
+
+ if (!PyArg_ParseTuple(args, "s", &fullname))
+ return NULL;
+
+ if (!(new_path = Vim_GetPaths(self)))
+ return NULL;
+
+ module = find_module(fullname, fullname, new_path);
+
+ Py_DECREF(new_path);
+
+ if (!module)
+ {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+
+ if (!(loader = PyObject_NEW(LoaderObject, &LoaderType)))
+ {
+ Py_DECREF(module);
+ return NULL;
+ }
+
+ loader->module = module;
+
+ return (PyObject *) loader;
+}
+
+ static PyObject *
+VimPathHook(PyObject *self UNUSED, PyObject *args)
+{
+ char *path;
+
+ if (PyArg_ParseTuple(args, "s", &path)
+ && STRCMP(path, vim_special_path) == 0)
+ {
+ Py_INCREF(vim_module);
+ return vim_module;
+ }
+
+ PyErr_Clear();
+ PyErr_SetNone(PyExc_ImportError);
+ return NULL;
+}
+
/*
* Vim module - Definitions
*/
@@ -938,9 +1113,7 @@ static struct PyMethodDef VimMethods[] = {
{"chdir", (PyCFunction)VimChdir, METH_VARARGS|METH_KEYWORDS, "Change directory"},
{"fchdir", (PyCFunction)VimFchdir, METH_VARARGS|METH_KEYWORDS, "Change directory"},
{"foreach_rtp", VimForeachRTP, METH_VARARGS, "Call given callable for each path in &rtp"},
-#if PY_MAJOR_VERSION < 3
{"find_module", FinderFindModule, METH_VARARGS, "Internal use only, returns loader object for any input it receives"},
-#endif
{"path_hook", VimPathHook, METH_VARARGS, "Hook function to install in sys.path_hooks"},
{"_get_paths", (PyCFunction)Vim_GetPaths, METH_NOARGS, "Get &rtp-based additions to sys.path"},
{ NULL, NULL, 0, NULL}
@@ -5188,21 +5361,6 @@ typedef struct
} CurrentObject;
static PyTypeObject CurrentType;
-#if PY_MAJOR_VERSION >= 3
-typedef struct
-{
- PyObject_HEAD
-} FinderObject;
-static PyTypeObject FinderType;
-#else
-typedef struct
-{
- PyObject_HEAD
- PyObject *module;
-} LoaderObject;
-static PyTypeObject LoaderType;
-#endif
-
static void
init_structs(void)
{
@@ -5418,6 +5576,14 @@ init_structs(void)
OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
OptionsType.tp_clear = (inquiry)OptionsClear;
+ vim_memset(&LoaderType, 0, sizeof(LoaderType));
+ LoaderType.tp_name = "vim.Loader";
+ LoaderType.tp_basicsize = sizeof(LoaderObject);
+ LoaderType.tp_flags = Py_TPFLAGS_DEFAULT;
+ LoaderType.tp_doc = "vim message object";
+ LoaderType.tp_methods = LoaderMethods;
+ LoaderType.tp_dealloc = (destructor)LoaderDestructor;
+
#if PY_MAJOR_VERSION >= 3
vim_memset(&vimmodule, 0, sizeof(vimmodule));
vimmodule.m_name = "vim";
@@ -5448,11 +5614,7 @@ init_types()
PYTYPE_READY(FunctionType);
PYTYPE_READY(OptionsType);
PYTYPE_READY(OutputType);
-#if PY_MAJOR_VERSION >= 3
- PYTYPE_READY(FinderType);
-#else
PYTYPE_READY(LoaderType);
-#endif
return 0;
}
@@ -5576,11 +5738,7 @@ static struct object_constant {
{"List", (PyObject *)&ListType},
{"Function", (PyObject *)&FunctionType},
{"Options", (PyObject *)&OptionsType},
-#if PY_MAJOR_VERSION >= 3
- {"Finder", (PyObject *)&FinderType},
-#else
- {"Loader", (PyObject *)&LoaderType},
-#endif
+ {"_Loader", (PyObject *)&LoaderType},
};
typedef int (*object_adder)(PyObject *, const char *, PyObject *);
@@ -5604,6 +5762,7 @@ populate_module(PyObject *m, object_adder add_object, attr_getter get_attr)
int i;
PyObject *other_module;
PyObject *attr;
+ PyObject *imp;
for (i = 0; i < (int)(sizeof(numeric_constants)
/ sizeof(struct numeric_constant));
@@ -5671,15 +5830,26 @@ populate_module(PyObject *m, object_adder add_object, attr_getter get_attr)
ADD_OBJECT(m, "VIM_SPECIAL_PATH", vim_special_path_object);
-#if PY_MAJOR_VERSION >= 3
- ADD_OBJECT(m, "_PathFinder", path_finder);
- ADD_CHECKED_OBJECT(m, "_find_module",
- (py_find_module = PyObject_GetAttrString(path_finder,
- "find_module")));
-#else
+ if (!(imp = PyImport_ImportModule("imp")))
+ return -1;
+
+ if (!(py_find_module = PyObject_GetAttrString(imp, "find_module")))
+ {
+ Py_DECREF(imp);
+ return -1;
+ }
+
+ if (!(py_load_module = PyObject_GetAttrString(imp, "load_module")))
+ {
+ Py_DECREF(py_find_module);
+ Py_DECREF(imp);
+ return -1;
+ }
+
+ Py_DECREF(imp);
+
ADD_OBJECT(m, "_find_module", py_find_module);
ADD_OBJECT(m, "_load_module", py_load_module);
-#endif
return 0;
}
diff --git a/src/if_python.c b/src/if_python.c
index d19ef3a39b..4a7c9d2589 100644
--- a/src/if_python.c
+++ b/src/if_python.c
@@ -752,12 +752,6 @@ static PyObject *DictionaryGetattr(PyObject *, char*);
static PyObject *ListGetattr(PyObject *, char *);
static PyObject *FunctionGetattr(PyObject *, char *);
-static PyObject *FinderFindModule(PyObject *, PyObject *);
-static PyObject *VimPathHook(PyObject *, PyObject *);
-
-static PyObject *py_find_module;
-static PyObject *py_load_module;
-
#ifndef Py_VISIT
# define Py_VISIT(obj) visit(obj, arg)
#endif
@@ -1382,204 +1376,11 @@ python_tabpage_free(tabpage_T *tab)
}
#endif
- static void
-LoaderDestructor(LoaderObject *self)
-{
- Py_DECREF(self->module);
- DESTRUCTOR_FINISH(self);
-}
-
- static PyObject *
-LoaderLoadModule(LoaderObject *self, PyObject *args UNUSED)
-{
- PyObject *r = self->module;
-
- Py_INCREF(r);
- return r;
-}
-
-static struct PyMethodDef LoaderMethods[] = {
- /* name, function, calling, doc */
- {"load_module", (PyCFunction)LoaderLoadModule, METH_VARARGS, ""},
- { NULL, NULL, 0, NULL}
-};
-
- static PyObject *
-call_load_module(char *name, int len, PyObject *find_module_result)
-{
- PyObject *fd, *pathname, *description;
-
- if (!PyTuple_Check(find_module_result)
- || PyTuple_GET_SIZE(find_module_result) != 3)
- {
- PyErr_SetString(PyExc_TypeError,
- _("expected 3-tuple as imp.find_module() result"));
- return NULL;
- }
-
- if (!(fd = PyTuple_GET_ITEM(find_module_result, 0))
- || !(pathname = PyTuple_GET_ITEM(find_module_result, 1))
- || !(description = PyTuple_GET_ITEM(find_module_result, 2)))
- {
- PyErr_SetString(PyExc_RuntimeError,
- _("internal error: imp.find_module returned tuple with NULL"));
- return NULL;
- }
-
- return PyObject_CallFunction(py_load_module,
- "s#OOO", name, len, fd, pathname, description);
-}
-
- static PyObject *
-find_module(char *fullname, char *tail, PyObject *new_path)
-{
- PyObject *find_module_result;
- PyObject *module;
- char *dot;
-
- if ((dot = (char *) vim_strchr((char_u *) tail, '.')))
- {
- /*
- * There is a dot in the name: call find_module recursively without the
- * first component
- */
- PyObject *newest_path;
- int partlen = (int) (dot - 1 - tail);
-
- if (!(find_module_result = PyObject_CallFunction(py_find_module,
- "s#O", tail, partlen, new_path)))
- return NULL;
-
- if (!(module = call_load_module(
- fullname,
- ((int) (tail - fullname)) + partlen,
- find_module_result)))
- {
- Py_DECREF(find_module_result);
- return NULL;
- }
-
- Py_DECREF(find_module_result);
-
- if (!(newest_path = PyObject_GetAttrString(module, "__path__")))
- {
- Py_DECREF(module);
- return NULL;
- }
-
- Py_DECREF(module);
-
- module = find_module(fullname, dot + 1, newest_path);
-
- Py_DECREF(newest_path);
-
- return module;
- }
- else
- {
- if (!(find_module_result = PyObject_CallFunction(py_find_module,
- "sO", tail, new_path)))
- return NULL;
-
- if (!(module = call_load_module(
- fullname,
- STRLEN(fullname),
- find_module_result)))
- {
- Py_DECREF(find_module_result);
- return NULL;
- }
-
- Py_DECREF(find_module_result);
-
- return module;
- }
-}
-
- static PyObject *
-FinderFindModule(PyObject *self, PyObject *args)
-{
- char *fullname;
- PyObject *module;
- PyObject *new_path;
- LoaderObject *loader;
-
- if (!PyArg_ParseTuple(args, "s", &fullname))
- return NULL;
-
- if (!(new_path = Vim_GetPaths(self)))
- return NULL;
-
- module = find_module(fullname, fullname, new_path);
-
- Py_DECREF(new_path);
-
- if (!module)
- {
- Py_INCREF(Py_None);
- return Py_None;
- }
-
- if (!(loader = PyObject_NEW(LoaderObject, &LoaderType)))
- {
- Py_DECREF(module);
- return NULL;
- }
-
- loader->module = module;
-
- return (PyObject *) loader;
-}
-
- static PyObject *
-VimPathHook(PyObject *self UNUSED, PyObject *args)
-{
- char *path;
-
- if (PyArg_ParseTuple(args, "s", &path)
- && STRCMP(path, vim_special_path) == 0)
- {
- Py_INCREF(vim_module);
- return vim_module;
- }
-
- PyErr_Clear();
- PyErr_SetNone(PyExc_ImportError);
- return NULL;
-}
-
static int
PythonMod_Init(void)
{
/* The special value is removed from sys.path in Python_Init(). */
static char *(argv[2]) = {"/must>not&exist/foo", NULL};
- PyObject *imp;
-
- if (!(imp = PyImport_ImportModule("imp")))
- return -1;
-
- if (!(py_find_module = PyObject_GetAttrString(imp, "find_module")))
- {
- Py_DECREF(imp);
- return -1;
- }
-
- if (!(py_load_module = PyObject_GetAttrString(imp, "load_module")))
- {
- Py_DECREF(py_find_module);
- Py_DECREF(imp);
- return -1;
- }
-
- Py_DECREF(imp);
-
- vim_memset(&LoaderType, 0, sizeof(LoaderType));
- LoaderType.tp_name = "vim.Loader";
- LoaderType.tp_basicsize = sizeof(LoaderObject);
- LoaderType.tp_flags = Py_TPFLAGS_DEFAULT;
- LoaderType.tp_doc = "vim message object";
- LoaderType.tp_methods = LoaderMethods;
- LoaderType.tp_dealloc = (destructor)LoaderDestructor;
if (init_types())
return -1;
diff --git a/src/if_python3.c b/src/if_python3.c
index 5c3c0b0d8a..a4f96407aa 100644
--- a/src/if_python3.c
+++ b/src/if_python3.c
@@ -175,6 +175,7 @@
# define PyObject_HasAttrString py3_PyObject_HasAttrString
# define PyObject_SetAttrString py3_PyObject_SetAttrString
# define PyObject_CallFunctionObjArgs py3_PyObject_CallFunctionObjArgs
+# define _PyObject_CallFunction_SizeT py3__PyObject_CallFunction_SizeT
# define PyObject_Call py3_PyObject_Call
# define PyEval_GetLocals py3_PyEval_GetLocals
# define PyEval_GetGlobals py3_PyEval_GetGlobals
@@ -296,6 +297,7 @@ static PyObject* (*py3_PyObject_GetAttrString)(PyObject *, const char *);
static int (*py3_PyObject_HasAttrString)(PyObject *, const char *);
static PyObject* (*py3_PyObject_SetAttrString)(PyObject *, const char *, PyObject *);
static PyObject* (*py3_PyObject_CallFunctionObjArgs)(PyObject *, ...);
+static PyObject* (*py3__PyObject_CallFunction_SizeT)(PyObject *, char *, ...);
static PyObject* (*py3_PyObject_Call)(PyObject *, PyObject *, PyObject *);
static PyObject* (*py3_PyEval_GetGlobals)();
static PyObject* (*py3_PyEval_GetLocals)();
@@ -458,6 +460,7 @@ static struct
{"PyObject_HasAttrString", (PYTHON_PROC*)&py3_PyObject_HasAttrString},
{"PyObject_SetAttrString", (PYTHON_PROC*)&py3_PyObject_SetAttrString},
{"PyObject_CallFunctionObjArgs", (PYTHON_PROC*)&py3_PyObject_CallFunctionObjArgs},
+ {"_PyObject_CallFunction_SizeT", (PYTHON_PROC*)&py3__PyObject_CallFunction_SizeT},
{"PyObject_Call", (PYTHON_PROC*)&py3_PyObject_Call},
{"PyEval_GetGlobals", (PYTHON_PROC*)&py3_PyEval_GetGlobals},
{"PyEval_GetLocals", (PYTHON_PROC*)&py3_PyEval_GetLocals},
@@ -740,9 +743,6 @@ static PyObject *VimPathHook(PyObject *, PyObject *);
static struct PyModuleDef vimmodule;
-static PyObject *path_finder;
-static PyObject *py_find_module = NULL;
-
#define PY_CAN_RECURSE
/*
@@ -1603,70 +1603,10 @@ python3_tabpage_free(tabpage_T *tab)
#endif
static PyObject *
-VimPathHook(PyObject *self UNUSED, PyObject *args)
-{
- char *path;
-
- if (PyArg_ParseTuple(args, "s", &path)
- && STRCMP(path, vim_special_path) == 0)
- {
- Py_INCREF(&FinderType);
- return (PyObject *) &FinderType;
- }
-
- PyErr_Clear();
- PyErr_SetNone(PyExc_ImportError);
- return NULL;
-}
-
- static PyObject *
-FinderFindModule(PyObject *cls UNUSED, PyObject *fullname)
-{
- PyObject *new_path;
- PyObject *r;
-
- if (!(new_path = Vim_GetPaths(NULL)))
- return NULL;
-
- /* call find_module of the super() class */
- r = PyObject_CallFunctionObjArgs(py_find_module, fullname, new_path, NULL);
-
- Py_DECREF(new_path);
-
- return r;
-}
-
-static struct PyMethodDef FinderMethods[] = {
- {"find_module", FinderFindModule, METH_CLASS|METH_O, ""},
- {NULL, NULL, 0, NULL}
-};
-
- static PyObject *
Py3Init_vim(void)
{
/* The special value is removed from sys.path in Python3_Init(). */
static wchar_t *(argv[2]) = {L"/must>not&exist/foo", NULL};
- PyObject *importlib_machinery;
-
- if (!(importlib_machinery = PyImport_ImportModule("importlib.machinery")))
- return NULL;
-
- if (!(path_finder = PyObject_GetAttrString(importlib_machinery,
- "PathFinder")))
- {
- Py_DECREF(importlib_machinery);
- return NULL;
- }
-
- Py_DECREF(importlib_machinery);
-
- vim_memset(&FinderType, 0, sizeof(FinderObject));
- FinderType.tp_name = "vim.Finder";
- FinderType.tp_basicsize = sizeof(FinderObject);
- FinderType.tp_base = (PyTypeObject *) path_finder;
- FinderType.tp_flags = Py_TPFLAGS_DEFAULT;
- FinderType.tp_doc = "Vim finder class, for use with path hook";
- FinderType.tp_methods = FinderMethods;
if (init_types())
return NULL;
diff --git a/src/version.c b/src/version.c
index 58e059a703..e30bffe5d1 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1174,
+/**/
1173,
/**/
1172,