From 1495313e53c26f6e0394e0c7f0411fc27f1054ce Mon Sep 17 00:00:00 2001 From: Mike Romberg Date: Thu, 2 Jun 2016 23:56:15 -0600 Subject: fix for new split module test cases. --- Source/Modules/python.cxx | 46 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 090c8461b..22703bb72 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -827,6 +827,14 @@ 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, 7, 0):\n", NULL); Printv(f_shadow, tab4, "def swig_import_helper():\n", NULL); @@ -834,7 +842,12 @@ public: 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, "return importlib.import_module(mname)\n", NULL); + 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 version_info >= (2, 6, 0):\n", NULL); @@ -859,21 +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 - * module. */ - Printv(f_shadow, "del version_info\n", NULL); - if (builtin) { /* - * Python3 removes relative imports. So 'from _foo import *' - * will only work for non-package modules. + * 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); - Printf(f_shadow, tab4 "from %s%s import *\n", (py3 ? "." : ""), - module); + Printv(f_shadow, tab4, "if 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 version_info symbol since we don't use it elsewhere in the + * module. */ + Printv(f_shadow, "del version_info\n", NULL); + 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); } -- cgit v1.2.1