summaryrefslogtreecommitdiff
path: root/Source/Modules/python.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Modules/python.cxx')
-rw-r--r--Source/Modules/python.cxx83
1 files changed, 65 insertions, 18 deletions
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index 82722304e..b42cf022f 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -517,6 +517,7 @@ public:
fputs(usage3, stdout);
} else if (strcmp(argv[i], "-py3") == 0) {
py3 = 1;
+ Preprocessor_define("SWIGPYTHON_PY3", 0);
Swig_mark_arg(i);
} else if (strcmp(argv[i], "-builtin") == 0) {
builtin = 1;
@@ -809,10 +810,10 @@ public:
mod_docstring = NULL;
}
- Printv(f_shadow, "\nfrom sys import version_info\n", NULL);
+ Printv(f_shadow, "\nfrom sys import version_info as _swig_python_version_info\n", NULL);
if (!builtin && fastproxy) {
- Printv(f_shadow, "if version_info >= (3, 0, 0):\n", NULL);
+ Printv(f_shadow, "if _swig_python_version_info >= (3, 0, 0):\n", NULL);
Printf(f_shadow, tab4 "new_instancemethod = lambda func, inst, cls: %s.SWIG_PyInstanceMethod_New(func)\n", module);
Printv(f_shadow, "else:\n", NULL);
Printv(f_shadow, tab4, "from new import instancemethod as new_instancemethod\n", NULL);
@@ -826,8 +827,30 @@ public:
* in 2.6, and fail in 2.7 onwards), but the relative import syntax
* isn't available in python 2.4 or earlier, so we have to write some
* code conditional on the python version.
+ *
+ * For python 2.7.0 and newer, first determine the shadow wrappers package
+ * based on the __name__ it was given by the importer that loaded it.
+ * Then construct a name for the module based on the package name and the
+ * module name (we know the module name). Use importlib to try and load
+ * it. If an attempt to load the module with importlib fails with an
+ * ImportError then fallback and try and load just the module name from
+ * the global namespace.
*/
- Printv(f_shadow, "if version_info >= (2, 6, 0):\n", NULL);
+ Printv(f_shadow, "if _swig_python_version_info >= (2, 7, 0):\n", NULL);
+ Printv(f_shadow, tab4, "def swig_import_helper():\n", NULL);
+ Printv(f_shadow, tab8, "import importlib\n", NULL);
+ Printv(f_shadow, tab8, "pkg = __name__.rpartition('.')[0]\n", NULL);
+ Printf(f_shadow, tab8 "mname = '.'.join((pkg, '%s')).lstrip('.')\n",
+ module);
+ Printv(f_shadow, tab8, "try:\n", NULL);
+ Printv(f_shadow, tab8, tab4, "return importlib.import_module(mname)\n",
+ NULL);
+ Printv(f_shadow, tab8, "except ImportError:\n", NULL);
+ Printf(f_shadow, tab8 tab4 "return importlib.import_module('%s')\n",
+ module);
+ Printf(f_shadow, tab4 "%s = swig_import_helper()\n", module);
+ Printv(f_shadow, tab4, "del swig_import_helper\n", NULL);
+ Printv(f_shadow, "elif _swig_python_version_info >= (2, 6, 0):\n", NULL);
Printv(f_shadow, tab4, "def swig_import_helper():\n", NULL);
Printv(f_shadow, tab8, "from os.path import dirname\n", NULL);
Printv(f_shadow, tab8, "import imp\n", NULL);
@@ -849,13 +872,36 @@ public:
Printv(f_shadow, "else:\n", NULL);
Printf(f_shadow, tab4 "import %s\n", module);
- /* Delete the version_info symbol since we don't use it elsewhere in the
+ if (builtin) {
+ /*
+ * Pull in all the attributes from the C module.
+ *
+ * An alternative approach to doing this if/else chain was
+ * proposed by Michael Thon. Someone braver than I may try it out.
+ * I fear some current swig user may depend on some side effect
+ * of from _foo import *
+ *
+ * for attr in _foo.__all__:
+ * globals()[attr] = getattr(_foo, attr)
+ *
+ */
+ Printf(f_shadow, "# pull in all the attributes from %s\n", module);
+ Printv(f_shadow, "if __name__.rpartition('.')[0] != '':\n", NULL);
+ Printv(f_shadow, tab4, "if _swig_python_version_info >= (2, 7, 0):\n", NULL);
+ Printv(f_shadow, tab8, "try:\n", NULL);
+ Printf(f_shadow, tab8 tab4 "from .%s import *\n", module);
+ Printv(f_shadow, tab8 "except ImportError:\n", NULL);
+ Printf(f_shadow, tab8 tab4 "from %s import *\n", module);
+ Printv(f_shadow, tab4, "else:\n", NULL);
+ Printf(f_shadow, tab8 "from %s import *\n", module);
+ Printv(f_shadow, "else:\n", NULL);
+ Printf(f_shadow, tab4 "from %s import *\n", module);
+ }
+
+ /* Delete the _swig_python_version_info symbol since we don't use it elsewhere in the
* module. */
- Printv(f_shadow, "del version_info\n", NULL);
+ Printv(f_shadow, "del _swig_python_version_info\n", NULL);
- if (builtin) {
- Printf(f_shadow, "from %s import *\n", module);
- }
if (modern || !classic) {
Printv(f_shadow, "try:\n", tab4, "_swig_property = property\n", "except NameError:\n", tab4, "pass # Python < 2.2 doesn't have 'property'.\n\n", NULL);
}
@@ -1205,13 +1251,14 @@ public:
Printf(out, "import %s%s%s%s\n", apkg, *Char(apkg) ? "." : "", pfx, mod);
Delete(apkg);
} else {
- if (py3) {
- if (py3_rlen1)
- Printf(out, "from . import %.*s\n", py3_rlen1, rpkg);
- Printf(out, "from .%s import %s%s\n", rpkg, pfx, mod);
- } else {
- Printf(out, "import %s%s%s%s\n", rpkg, *Char(rpkg) ? "." : "", pfx, mod);
- }
+ Printf(out, "from sys import version_info as _swig_python_version_info\n");
+ Printf(out, "if _swig_python_version_info >= (2, 7, 0):\n");
+ if (py3_rlen1)
+ Printf(out, tab4 "from . import %.*s\n", py3_rlen1, rpkg);
+ Printf(out, tab4 "from .%s import %s%s\n", rpkg, pfx, mod);
+ Printf(out, "else:\n");
+ Printf(out, tab4 "import %s%s%s%s\n", rpkg, *Char(rpkg) ? "." : "", pfx, mod);
+ Printf(out, "del _swig_python_version_info\n");
Delete(rpkg);
}
return out;
@@ -3463,7 +3510,7 @@ public:
* type but the return-type of function. */
if(!SwigType_isfunction(uqtype) && !SwigType_isfunctionpointer(uqtype)) {
SwigType *basetype = SwigType_base(uqtype);
- result = (bool)SwigType_isclass(basetype);
+ result = SwigType_isclass(basetype) != 0;
Delete(basetype);
}
@@ -4153,9 +4200,9 @@ public:
printSlot(f, getSlot(n, "feature:python:nb_inplace_xor"), "nb_inplace_xor", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_or"), "nb_inplace_or", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_floor_divide"), "nb_floor_divide", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_true_divide"), "nb_true_divide", "binaryfunc");
+ printSlot(f, getSlot(n, "feature:python:nb_divide"), "nb_true_divide", "binaryfunc");
printSlot(f, getSlot(n, "feature:python:nb_inplace_floor_divide"), "nb_inplace_floor_divide", "binaryfunc");
- printSlot(f, getSlot(n, "feature:python:nb_inplace_true_divide"), "nb_inplace_true_divide", "binaryfunc");
+ printSlot(f, getSlot(n, "feature:python:nb_inplace_divide"), "nb_inplace_true_divide", "binaryfunc");
Printv(f, "#if PY_VERSION_HEX >= 0x02050000\n", NIL);
printSlot(f, getSlot(n, "feature:python:nb_index"), "nb_index", "unaryfunc");
Printv(f, "#endif\n", NIL);