--- Python-2.7.6/Lib/distutils/command/build_ext.py.~1~ 2013-11-09 23:36:40.000000000 -0800 +++ Python-2.7.6/Lib/distutils/command/build_ext.py 2014-05-14 12:47:04.342901439 -0700 @@ -634,6 +634,10 @@ filename = self.get_ext_filename(ext_name) filename = os.path.split(filename)[-1] + # on Solaris we put 64-bit python objects under .../64 + if sys.maxint != 2147483647L: + filename = os.path.join("64", filename) + if not self.inplace: # no further work needed # returning : @@ -674,7 +678,14 @@ so_ext = get_config_var('SO') if os.name == 'nt' and self.debug: return os.path.join(*ext_path) + '_d' + so_ext - return os.path.join(*ext_path) + so_ext + #return os.path.join(*ext_path) + so_ext + # .so extensions are word-size specific + path = apply(os.path.join, ext_path) + if sys.maxint == 2147483647L: + return path + so_ext + dirname = os.path.dirname(path); + basename = os.path.basename(path); + return os.path.join(dirname, "64", basename + so_ext) def get_export_symbols (self, ext): """Return the list of symbols that a shared extension has to --- Python-2.7.6/Python/import.c.~1~ 2013-11-09 23:36:41.000000000 -0800 +++ Python-2.7.6/Python/import.c 2014-05-14 12:53:34.233016586 -0700 @@ -1288,6 +1288,57 @@ static int find_init_module(char *); /* Forward */ static struct filedescr importhookdescr = {"", "", IMP_HOOK}; +#ifdef HAVE_STAT +static char * +insert_64dir(char *buf, size_t buflen) +{ + char *base; + char *cp; + size_t blen; + + if ((blen = strlen(buf)) == 0) + return (NULL); + + cp = &buf[blen - 1]; + while (cp != buf && *cp != SEP) + cp--; + + if (cp != buf) + cp++; + + if (blen + strlen("64/") + 1 >= buflen) + return NULL; + + base = strdup(cp); + sprintf(cp, "64%c%s", SEP, base); + free(base); + + return buf; +} + +/* + * If we're on a 64-bit platform, modify lookups for shared object files. + */ +static size_t modify_path(struct filedescr *fdp, char *buf, size_t buflen) +{ + struct stat statbuf; + + if (sizeof(void *) != 8) + return 0; + + if (stat(buf, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) + return 0; + + if (fdp->type != C_EXTENSION) + return 0; + + if (insert_64dir(buf, buflen) == NULL) + return 0; + + return strlen("64/"); +} +#endif + static struct filedescr * find_module(char *fullname, char *subname, PyObject *path, char *buf, size_t buflen, FILE **p_fp, PyObject **p_loader) @@ -1302,11 +1353,10 @@ static struct filedescr fd_builtin = {"", "", C_BUILTIN}; static struct filedescr fd_package = {"", "", PKG_DIRECTORY}; char *name; -#if defined(PYOS_OS2) size_t saved_len; size_t saved_namelen; char *saved_buf = NULL; -#endif + if (p_loader != NULL) *p_loader = NULL; @@ -1513,15 +1563,17 @@ } } } -#if defined(PYOS_OS2) /* take a snapshot of the module spec for restoration * after the 8 character DLL hackery */ saved_buf = strdup(buf); saved_len = len; saved_namelen = namelen; -#endif /* PYOS_OS2 */ + for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) { +#ifdef HAVE_STAT + len += modify_path(fdp, buf, buflen); +#endif #if defined(PYOS_OS2) && defined(HAVE_DYNAMIC_LOADING) /* OS/2 limits DLLs to 8 character names (w/o extension) @@ -1562,21 +1614,20 @@ fp = NULL; } } -#if defined(PYOS_OS2) + /* restore the saved snapshot */ strcpy(buf, saved_buf); len = saved_len; namelen = saved_namelen; -#endif } -#if defined(PYOS_OS2) + /* don't need/want the module name snapshot anymore */ if (saved_buf) { free(saved_buf); saved_buf = NULL; } -#endif + Py_XDECREF(copy); if (fp != NULL) break; --- Python-2.7.1/Python/importdl.h.orig Fri Jul 15 15:48:16 2011 +++ Python-2.7.1/Python/importdl.h Fri Jul 15 15:49:10 2011 @@ -31,8 +31,9 @@ extern PyObject *_PyImport_LoadDynamicModule(char *name, char *pathname, FILE *); -/* Max length of module suffix searched for -- accommodates "module.slb" */ -#define MAXSUFFIXSIZE 12 +/* Max length of module suffix searched for -- accommodates "module.slb" + and '64/' */ +#define MAXSUFFIXSIZE 15 #ifdef MS_WINDOWS #include --- Python-2.7.15/Lib/distutils/tests/test_build_ext.py.~1~ 2018-04-30 01:47:33.000000000 +0000 +++ Python-2.7.15/Lib/distutils/tests/test_build_ext.py 2018-08-27 17:45:37.658024420 +0000 @@ -298,7 +298,8 @@ self.assertEqual(os.path.splitext(so_file)[-1], sysconfig.get_config_var('SO')) so_dir = os.path.dirname(so_file) - self.assertEqual(so_dir, other_tmp_dir) + if sys.platform != 'sunos5': + self.assertEqual(so_dir, other_tmp_dir) cmd.compiler = None cmd.inplace = 0 cmd.run() @@ -307,7 +308,8 @@ self.assertEqual(os.path.splitext(so_file)[-1], sysconfig.get_config_var('SO')) so_dir = os.path.dirname(so_file) - self.assertEqual(so_dir, cmd.build_lib) + if sys.platform != 'sunos5': + self.assertEqual(so_dir, cmd.build_lib) # inplace = 0, cmd.package = 'bar' build_py = cmd.get_finalized_command('build_py') @@ -315,7 +317,8 @@ path = cmd.get_ext_fullpath('foo') # checking that the last directory is the build_dir path = os.path.split(path)[0] - self.assertEqual(path, cmd.build_lib) + if sys.platform != 'sunos5': + self.assertEqual(path, cmd.build_lib) # inplace = 1, cmd.package = 'bar' cmd.inplace = 1 @@ -329,7 +332,8 @@ # checking that the last directory is bar path = os.path.split(path)[0] lastdir = os.path.split(path)[-1] - self.assertEqual(lastdir, 'bar') + if sys.platform != 'sunos5': + self.assertEqual(lastdir, 'bar') def test_ext_fullpath(self): ext = sysconfig.get_config_vars()['SO'] @@ -341,14 +345,16 @@ curdir = os.getcwd() wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) path = cmd.get_ext_fullpath('lxml.etree') - self.assertEqual(wanted, path) + if sys.platform != 'sunos5': + self.assertEqual(wanted, path) # building lxml.etree not inplace cmd.inplace = 0 cmd.build_lib = os.path.join(curdir, 'tmpdir') wanted = os.path.join(curdir, 'tmpdir', 'lxml', 'etree' + ext) path = cmd.get_ext_fullpath('lxml.etree') - self.assertEqual(wanted, path) + if sys.platform != 'sunos5': + self.assertEqual(wanted, path) # building twisted.runner.portmap not inplace build_py = cmd.get_finalized_command('build_py') @@ -357,13 +363,15 @@ path = cmd.get_ext_fullpath('twisted.runner.portmap') wanted = os.path.join(curdir, 'tmpdir', 'twisted', 'runner', 'portmap' + ext) - self.assertEqual(wanted, path) + if sys.platform != 'sunos5': + self.assertEqual(wanted, path) # building twisted.runner.portmap inplace cmd.inplace = 1 path = cmd.get_ext_fullpath('twisted.runner.portmap') wanted = os.path.join(curdir, 'twisted', 'runner', 'portmap' + ext) - self.assertEqual(wanted, path) + if sys.platform != 'sunos5': + self.assertEqual(wanted, path) def test_build_ext_inplace(self): etree_c = os.path.join(self.tmp_dir, 'lxml.etree.c') @@ -378,7 +386,8 @@ ext = sysconfig.get_config_var("SO") wanted = os.path.join(curdir, 'src', 'lxml', 'etree' + ext) path = cmd.get_ext_fullpath('lxml.etree') - self.assertEqual(wanted, path) + if sys.platform != 'sunos5': + self.assertEqual(wanted, path) def test_setuptools_compat(self): import distutils.core, distutils.extension, distutils.command.build_ext @@ -418,7 +427,8 @@ ext_name = os.path.join('UpdateManager', 'fdsend') ext_path = cmd.get_ext_fullpath(ext_name) wanted = os.path.join(cmd.build_lib, 'UpdateManager', 'fdsend' + ext) - self.assertEqual(ext_path, wanted) + if sys.platform != 'sunos5': + self.assertEqual(ext_path, wanted) @unittest.skipUnless(sys.platform == 'win32', 'these tests require Windows') def test_build_ext_path_cross_platform(self):