You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(15) |
Oct
(31) |
Nov
(38) |
Dec
(21) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(46) |
Feb
(2) |
Mar
(10) |
Apr
(13) |
May
(2) |
Jun
(14) |
Jul
(28) |
Aug
(3) |
Sep
(7) |
Oct
(8) |
Nov
(8) |
Dec
(11) |
2005 |
Jan
|
Feb
|
Mar
|
Apr
(42) |
May
(1) |
Jun
(8) |
Jul
(4) |
Aug
(18) |
Sep
(38) |
Oct
(10) |
Nov
|
Dec
(7) |
2006 |
Jan
|
Feb
(8) |
Mar
(9) |
Apr
|
May
|
Jun
(6) |
Jul
(6) |
Aug
|
Sep
|
Oct
|
Nov
(12) |
Dec
(8) |
2007 |
Jan
(3) |
Feb
|
Mar
(9) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(5) |
Oct
|
Nov
|
Dec
|
2008 |
Jan
|
Feb
(4) |
Mar
(2) |
Apr
(17) |
May
(16) |
Jun
(2) |
Jul
|
Aug
(3) |
Sep
(1) |
Oct
|
Nov
(11) |
Dec
(1) |
2009 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
2010 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
2012 |
Jan
(1) |
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(2) |
2013 |
Jan
(14) |
Feb
(14) |
Mar
|
Apr
|
May
(3) |
Jun
(10) |
Jul
(2) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
2014 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(10) |
Jun
|
Jul
|
Aug
|
Sep
(9) |
Oct
(8) |
Nov
|
Dec
|
2017 |
Jan
(3) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(4) |
Sep
|
Oct
|
Nov
|
Dec
|
From: <th...@us...> - 2017-08-04 12:41:41
|
Revision: 772 http://sourceforge.net/p/py2exe/svn/772 Author: theller Date: 2017-08-04 12:41:39 +0000 (Fri, 04 Aug 2017) Log Message: ----------- Use the ANSI version functions; now the source can be compiled even when UNICODE is defined. Modified Paths: -------------- trunk/py2exe/source/actctx.c Modified: trunk/py2exe/source/actctx.c =================================================================== --- trunk/py2exe/source/actctx.c 2017-08-04 12:29:28 UTC (rev 771) +++ trunk/py2exe/source/actctx.c 2017-08-04 12:41:39 UTC (rev 772) @@ -26,7 +26,7 @@ ULONG_PTR ret = 0; if (PyWin_DLLhActivationContext && pfnActivateActCtx) if (!(*pfnActivateActCtx)(PyWin_DLLhActivationContext, &ret)) { - OutputDebugString("py2exe failed to activate the activation context before loading a DLL\n"); + OutputDebugStringA("py2exe failed to activate the activation context before loading a DLL\n"); ret = 0; // no promise the failing function didn't change it! } return ret; @@ -36,5 +36,5 @@ { if (cookie && pfnDeactivateActCtx) if (!(*pfnDeactivateActCtx)(0, cookie)) - OutputDebugString("py2exe failed to de-activate the activation context\n"); + OutputDebugStringA("py2exe failed to de-activate the activation context\n"); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2017-08-04 12:29:31
|
Revision: 771 http://sourceforge.net/p/py2exe/svn/771 Author: theller Date: 2017-08-04 12:29:28 +0000 (Fri, 04 Aug 2017) Log Message: ----------- Use the ANSI version functions; now the source can be compiled even when UNICODE is defined. Modified Paths: -------------- trunk/py2exe-3/source/MyLoadLibrary.c trunk/py2exe-3/source/actctx.c trunk/py2exe-3/source/run.c trunk/py2exe-3/source/run_ctypes_dll.c trunk/py2exe-3/source/run_w.c trunk/py2exe-3/source/start.c Modified: trunk/py2exe-3/source/MyLoadLibrary.c =================================================================== --- trunk/py2exe-3/source/MyLoadLibrary.c 2017-08-01 13:59:44 UTC (rev 770) +++ trunk/py2exe-3/source/MyLoadLibrary.c 2017-08-04 12:29:28 UTC (rev 771) @@ -219,7 +219,7 @@ return lib->module; } } - return LoadLibrary(name); + return LoadLibraryA(name); } BOOL MyFreeLibrary(HMODULE module) Modified: trunk/py2exe-3/source/actctx.c =================================================================== --- trunk/py2exe-3/source/actctx.c 2017-08-01 13:59:44 UTC (rev 770) +++ trunk/py2exe-3/source/actctx.c 2017-08-04 12:29:28 UTC (rev 771) @@ -26,7 +26,7 @@ ULONG_PTR ret = 0; if (PyWin_DLLhActivationContext && pfnActivateActCtx) if (!(*pfnActivateActCtx)(PyWin_DLLhActivationContext, &ret)) { - OutputDebugString("py2exe failed to activate the activation context before loading a DLL\n"); + OutputDebugStringA("py2exe failed to activate the activation context before loading a DLL\n"); ret = 0; // no promise the failing function didn't change it! } return ret; @@ -36,5 +36,5 @@ { if (cookie && pfnDeactivateActCtx) if (!(*pfnDeactivateActCtx)(0, cookie)) - OutputDebugString("py2exe failed to de-activate the activation context\n"); + OutputDebugStringA("py2exe failed to de-activate the activation context\n"); } Modified: trunk/py2exe-3/source/run.c =================================================================== --- trunk/py2exe-3/source/run.c 2017-08-01 13:59:44 UTC (rev 770) +++ trunk/py2exe-3/source/run.c 2017-08-04 12:29:28 UTC (rev 771) @@ -32,7 +32,7 @@ fprintf(stderr, msg); if (error) { LPVOID lpMsgBuf; - FormatMessage( + FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, Modified: trunk/py2exe-3/source/run_ctypes_dll.c =================================================================== --- trunk/py2exe-3/source/run_ctypes_dll.c 2017-08-01 13:59:44 UTC (rev 770) +++ trunk/py2exe-3/source/run_ctypes_dll.c 2017-08-04 12:29:28 UTC (rev 771) @@ -55,7 +55,7 @@ if (error) { LPVOID lpMsgBuf; - FormatMessage( + FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, @@ -69,9 +69,9 @@ LocalFree(lpMsgBuf); } else Buffer[0] = '\0'; - n = lstrlen(Buffer); + n = lstrlenA(Buffer); _snprintf(Buffer+n, sizeof(Buffer)-n, msg); - MessageBox(GetFocus(), Buffer, NULL, MB_OK | MB_ICONSTOP); + MessageBoxA(GetFocus(), Buffer, NULL, MB_OK | MB_ICONSTOP); } BOOL have_init = FALSE; @@ -136,7 +136,7 @@ ); } if (g_ctypes == NULL) { - OutputDebugString("GetModuleHandle _ctypes.pyd failed"); + OutputDebugStringA("GetModuleHandle _ctypes.pyd failed"); // give up in disgust return -1; } @@ -213,7 +213,7 @@ // ***************************************************************** BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { - OutputDebugString("DllMain"); + OutputDebugStringA("DllMain"); if ( dwReason == DLL_PROCESS_ATTACH) { gInstance = hInstance; InitializeCriticalSection(&csInit); @@ -221,7 +221,7 @@ if (pfnGetCurrentActCtx && pfnAddRefActCtx) if ((*pfnGetCurrentActCtx)(&PyWin_DLLhActivationContext)) if (!(*pfnAddRefActCtx)(PyWin_DLLhActivationContext)) - OutputDebugString("Python failed to load the default activation context\n"); + OutputDebugStringA("Python failed to load the default activation context\n"); } else if ( dwReason == DLL_PROCESS_DETACH ) { gInstance = 0; @@ -277,7 +277,7 @@ wchar_t buf[300]; ULONG_PTR cookie = 0; - OutputDebugString("DllRegisterServer"); + OutputDebugStringA("DllRegisterServer"); /* MessageBox(NULL, "Debug\n", @@ -288,10 +288,10 @@ check_init(); _My_DeactivateActCtx(cookie); - OutputDebugString("check_init ok"); + OutputDebugStringA("check_init ok"); state = PyGILState_Ensure(); - OutputDebugString("PyGILState_Ensure done"); + OutputDebugStringA("PyGILState_Ensure done"); swprintf(buf,300,L"DllRegisterServer: libfilename=%s\n",&libfilename); OutputDebugStringW(buf); Modified: trunk/py2exe-3/source/run_w.c =================================================================== --- trunk/py2exe-3/source/run_w.c 2017-08-01 13:59:44 UTC (rev 770) +++ trunk/py2exe-3/source/run_w.c 2017-08-04 12:29:28 UTC (rev 771) @@ -31,7 +31,7 @@ if (error) { LPVOID lpMsgBuf; - FormatMessage( + FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, @@ -45,9 +45,9 @@ LocalFree(lpMsgBuf); } else Buffer[0] = '\0'; - n = lstrlen(Buffer); + n = lstrlenA(Buffer); _snprintf(Buffer+n, sizeof(Buffer)-n, msg); - MessageBox(GetFocus(), Buffer, NULL, MB_OK | MB_ICONSTOP); + MessageBoxA(GetFocus(), Buffer, NULL, MB_OK | MB_ICONSTOP); } extern int init(char *); Modified: trunk/py2exe-3/source/start.c =================================================================== --- trunk/py2exe-3/source/start.c 2017-08-01 13:59:44 UTC (rev 770) +++ trunk/py2exe-3/source/start.c 2017-08-04 12:29:28 UTC (rev 771) @@ -115,7 +115,7 @@ */ BOOL locate_script(HMODULE hmod) { - HRSRC hrsrc = FindResource(hmod, MAKEINTRESOURCE(1), "PYTHONSCRIPT"); + HRSRC hrsrc = FindResourceA(hmod, MAKEINTRESOURCEA(1), "PYTHONSCRIPT"); HGLOBAL hgbl; // load the script resource @@ -281,7 +281,7 @@ HMODULE hmod = LoadLibraryExW(libfilename, NULL, LOAD_LIBRARY_AS_DATAFILE); // Try to locate pythonxy.dll as resource in the exe - hrsrc = FindResource(hmod, MAKEINTRESOURCE(1), PYTHONDLL); + hrsrc = FindResourceA(hmod, MAKEINTRESOURCEA(1), PYTHONDLL); if (hrsrc) { HGLOBAL hgbl; DWORD size; @@ -296,7 +296,7 @@ LOAD_WITH_ALTERED_SEARCH_PATH so that really our own one is used. */ - hmod_pydll = LoadLibrary(PYTHONDLL); + hmod_pydll = LoadLibraryA(PYTHONDLL); FreeLibrary(hmod); return hmod_pydll; } @@ -384,7 +384,7 @@ if (!PyArg_ParseTuple(args, "is|zi", &hwnd, &message, &title, &flags)) return NULL; - return PyLong_FromLong(MessageBox(hwnd, message, title, flags)); + return PyLong_FromLong(MessageBoxA(hwnd, message, title, flags)); } static PyObject *Py_SHGetSpecialFolderPath(PyObject *self, PyObject *args) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2017-08-01 13:59:46
|
Revision: 770 http://sourceforge.net/p/py2exe/svn/770 Author: theller Date: 2017-08-01 13:59:44 +0000 (Tue, 01 Aug 2017) Log Message: ----------- Update Modified Paths: -------------- trunk/py2exe-3/ChangeLog Modified: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog 2017-08-01 13:55:48 UTC (rev 769) +++ trunk/py2exe-3/ChangeLog 2017-08-01 13:59:44 UTC (rev 770) @@ -1,3 +1,7 @@ +2017-08-01 <th...@ct...> + + * Add more MKL files to numpy_core hook, bump version to 0.9.2.7. + 2017-01-04 <th...@ct...> * Updates from upstream version, adds compatibility with Python This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2017-08-01 13:55:51
|
Revision: 769 http://sourceforge.net/p/py2exe/svn/769 Author: theller Date: 2017-08-01 13:55:48 +0000 (Tue, 01 Aug 2017) Log Message: ----------- Add more MKL files to numpy_core hook, bump py2exe version. Modified Paths: -------------- trunk/py2exe-3/py2exe/__init__.py trunk/py2exe-3/py2exe/boot_ctypes_com_server.py trunk/py2exe-3/py2exe/hooks.py Modified: trunk/py2exe-3/py2exe/__init__.py =================================================================== --- trunk/py2exe-3/py2exe/__init__.py 2017-01-04 16:13:11 UTC (rev 768) +++ trunk/py2exe-3/py2exe/__init__.py 2017-08-01 13:55:48 UTC (rev 769) @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """py2exe package """ -__version__ = "0.9.2.5" +__version__ = "0.9.2.7" from .patch_distutils import patch_distutils Modified: trunk/py2exe-3/py2exe/boot_ctypes_com_server.py =================================================================== --- trunk/py2exe-3/py2exe/boot_ctypes_com_server.py 2017-01-04 16:13:11 UTC (rev 768) +++ trunk/py2exe-3/py2exe/boot_ctypes_com_server.py 2017-08-01 13:55:48 UTC (rev 769) @@ -53,7 +53,7 @@ def get_classes(module): return [ob for ob in module.__dict__.values() - if hasattr(ob, "_reg_progid_") + if hasattr(ob, "_reg_progid_") and ob._reg_progid_ is not None ] def build_class_map(): Modified: trunk/py2exe-3/py2exe/hooks.py =================================================================== --- trunk/py2exe-3/py2exe/hooks.py 2017-01-04 16:13:11 UTC (rev 768) +++ trunk/py2exe-3/py2exe/hooks.py 2017-08-01 13:55:48 UTC (rev 769) @@ -485,7 +485,9 @@ numpy_core_path = os.path.dirname(module.__loader__.path) #add mkl dlls from numpy.core, if present from os import listdir - dlls = [os.path.join(numpy_core_path,mkl) for mkl in listdir(numpy_core_path) if mkl.startswith('mkl_')] + dlls = [os.path.join(numpy_core_path,mkl) + for mkl in listdir(numpy_core_path) + if mkl.startswith('mkl_') or mkl in ['libmmd.dll', 'libifcoremd.dll', 'libiomp5md.dll']] for dll in dlls: finder.add_dll(dll) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2017-01-04 16:13:14
|
Revision: 768 http://sourceforge.net/p/py2exe/svn/768 Author: theller Date: 2017-01-04 16:13:11 +0000 (Wed, 04 Jan 2017) Log Message: ----------- Fix compiler warning in 64-bit build. Modified Paths: -------------- trunk/py2exe-3/source/run_ctypes_dll.c Modified: trunk/py2exe-3/source/run_ctypes_dll.c =================================================================== --- trunk/py2exe-3/source/run_ctypes_dll.c 2017-01-04 15:35:37 UTC (rev 767) +++ trunk/py2exe-3/source/run_ctypes_dll.c 2017-01-04 16:13:11 UTC (rev 768) @@ -93,7 +93,7 @@ char dll_path[_MAX_PATH+_MAX_FNAME+1]; wchar_t ctypes_path[_MAX_PATH+_MAX_FNAME+1]; wchar_t * temp=NULL; - int length=0; + size_t length=0; // shouldn't do this twice assert(g_ctypes == NULL); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2017-01-04 15:35:40
|
Revision: 767 http://sourceforge.net/p/py2exe/svn/767 Author: theller Date: 2017-01-04 15:35:37 +0000 (Wed, 04 Jan 2017) Log Message: ----------- Updates from upstream version. Modified Paths: -------------- trunk/py2exe-3/ChangeLog Modified: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog 2017-01-04 15:34:08 UTC (rev 766) +++ trunk/py2exe-3/ChangeLog 2017-01-04 15:35:37 UTC (rev 767) @@ -1,3 +1,9 @@ +2017-01-04 <th...@ct...> + + * Updates from upstream version, adds compatibility with Python + 3.5 and 3.6. + Version number 0.9.2.5. + 2014-10-21 <th...@ct...> * Released py2exe 0.9.2.2. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2017-01-04 15:34:10
|
Revision: 766 http://sourceforge.net/p/py2exe/svn/766 Author: theller Date: 2017-01-04 15:34:08 +0000 (Wed, 04 Jan 2017) Log Message: ----------- Updates from upstream version. Modified Paths: -------------- trunk/py2exe-3/py2exe/__init__.py trunk/py2exe-3/py2exe/boot_ctypes_com_server.py trunk/py2exe-3/py2exe/distutils_buildexe.py trunk/py2exe-3/py2exe/dllfinder.py trunk/py2exe-3/py2exe/hooks.py trunk/py2exe-3/py2exe/mf3.py trunk/py2exe-3/py2exe/mf34.py trunk/py2exe-3/py2exe/py2exe_distutils.py trunk/py2exe-3/py2exe/runtime.py trunk/py2exe-3/setup.py trunk/py2exe-3/source/MyLoadLibrary.c trunk/py2exe-3/source/Python-dynload.h trunk/py2exe-3/source/_memimporter.c trunk/py2exe-3/source/python-dynload.c trunk/py2exe-3/source/run_ctypes_dll.c trunk/py2exe-3/zipextimporter.py Modified: trunk/py2exe-3/py2exe/__init__.py =================================================================== --- trunk/py2exe-3/py2exe/__init__.py 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/py2exe/__init__.py 2017-01-04 15:34:08 UTC (rev 766) @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """py2exe package """ -__version__ = "0.9.2.2" +__version__ = "0.9.2.5" from .patch_distutils import patch_distutils Modified: trunk/py2exe-3/py2exe/boot_ctypes_com_server.py =================================================================== --- trunk/py2exe-3/py2exe/boot_ctypes_com_server.py 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/py2exe/boot_ctypes_com_server.py 2017-01-04 15:34:08 UTC (rev 766) @@ -66,6 +66,7 @@ # dump each class for cls in get_classes(mod): classmap[cls._reg_clsid_] = cls + #print("build_class_map: ",classmap) import comtypes.server.inprocserver comtypes.server.inprocserver._clsid_to_class = classmap build_class_map() Modified: trunk/py2exe-3/py2exe/distutils_buildexe.py =================================================================== --- trunk/py2exe-3/py2exe/distutils_buildexe.py 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/py2exe/distutils_buildexe.py 2017-01-04 15:34:08 UTC (rev 766) @@ -130,9 +130,12 @@ ('custom-boot-script=', None, "Python file that will be run when setting up the runtime environment"), + + ('use-assembly', None, + "use windows assembly to isolate python dll in ctypes-com-server."), ] - boolean_options = ["compressed", "xref", "ascii", "skip-archive"] + boolean_options = ["compressed", "xref", "ascii", "skip-archive","use-assembly"] def initialize_options (self): self.xref =0 @@ -150,6 +153,7 @@ self.skip_archive = 0 self.ascii = 0 self.custom_boot_script = None + self.use_assembly = False def finalize_options (self): self.optimize = int(self.optimize) @@ -258,11 +262,12 @@ data_files = self.distribution.data_files, compress = self.compressed, + use_assembly = self.use_assembly, ) ## level = logging.INFO if options.verbose else logging.WARNING ## logging.basicConfig(level=level) - + #import pdb;pdb.set_trace() builder = runtime.Runtime(options) builder.analyze() builder.build() Modified: trunk/py2exe-3/py2exe/dllfinder.py =================================================================== --- trunk/py2exe-3/py2exe/dllfinder.py 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/py2exe/dllfinder.py 2017-01-04 15:34:08 UTC (rev 766) @@ -84,9 +84,18 @@ """Call BindImageEx and collect all dlls that are bound. """ # XXX Should cache results! + import platform + if platform.architecture()[0]=="32bit": + pth = ";".join([p for p in os.environ["PATH"].split(';') if not "intel64_win" in p]) + elif platform.architecture()[0]=="64bit": + pth = ";".join([p for p in os.environ["PATH"].split(';') if not "ia32_win" in p]) + else: + pth = os.environ["PATH"] + + #import pdb;pdb.set_trace() path = ";".join([os.path.dirname(imagename), os.path.dirname(sys.executable), - os.environ["PATH"]]) + pth]) result = set() @_wapi.PIMAGEHLP_STATUS_ROUTINE @@ -278,4 +287,4 @@ scanner = Scanner() scanner.import_package("numpy") - scanner.report_dlls() + print(scanner.all_dlls()) Modified: trunk/py2exe-3/py2exe/hooks.py =================================================================== --- trunk/py2exe-3/py2exe/hooks.py 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/py2exe/hooks.py 2017-01-04 15:34:08 UTC (rev 766) @@ -326,6 +326,7 @@ finder.ignore("nose") finder.ignore("scipy") + def hook_nose(finder, module): finder.ignore("IronPython") finder.ignore("cStringIO") @@ -481,3 +482,45 @@ def hook_numpy_core(finder, module): finder.ignore("numpy.core._dotblas") + numpy_core_path = os.path.dirname(module.__loader__.path) + #add mkl dlls from numpy.core, if present + from os import listdir + dlls = [os.path.join(numpy_core_path,mkl) for mkl in listdir(numpy_core_path) if mkl.startswith('mkl_')] + for dll in dlls: + finder.add_dll(dll) + + +def hook_scipy_special(finder, module): + #import pdb;pdb.set_trace() + depth = getattr(finder,"recursion_depth_special",0) + if depth==0: + finder.recursion_depth_special = depth + 1 + finder.import_hook("scipy.special._ufuncs_cxx") + finder.import_hook("scipy.special.orthogonal") + finder.import_hook("scipy", fromlist=("linalg",)) + finder.recursion_depth_special = depth + +def hook_scipy_linalg(finder, module): + depth = getattr(finder,"recursion_depth_linalg",0) + if depth==0: + finder.recursion_depth_linalg = depth + 1 + finder.import_hook("scipy.linalg.cython_blas") + finder.import_hook("scipy.linalg.cython_lapack") + finder.import_hook("scipy.integrate") + finder.recursion_depth_linalg = depth + + +def hook_scipy_sparse_csgraph(finder, module): + depth = getattr(finder,"recursion_depth_sparse",0) + if depth==0: + finder.recursion_depth_sparse = depth + 1 + finder.import_hook("scipy.sparse.csgraph._validation") + finder.recursion_depth_sparse = depth + +def hook_scipy_optimize(finder, module): + #import pdb;pdb.set_trace() + depth = getattr(finder,"recursion_depth_optimize",0) + if depth==0: + finder.recursion_depth_optimize = depth + 1 + finder.import_hook("scipy.optimize.minpack2") + finder.recursion_depth_optimize = depth Modified: trunk/py2exe-3/py2exe/mf3.py =================================================================== --- trunk/py2exe-3/py2exe/mf3.py 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/py2exe/mf3.py 2017-01-04 15:34:08 UTC (rev 766) @@ -17,12 +17,12 @@ import warnings # XXX Clean up once str8's cstor matches bytes. -LOAD_CONST = bytes([dis.opname.index('LOAD_CONST')]) -IMPORT_NAME = bytes([dis.opname.index('IMPORT_NAME')]) -STORE_NAME = bytes([dis.opname.index('STORE_NAME')]) -STORE_GLOBAL = bytes([dis.opname.index('STORE_GLOBAL')]) +LOAD_CONST = dis.opname.index('LOAD_CONST') +IMPORT_NAME = dis.opname.index('IMPORT_NAME') +STORE_NAME = dis.opname.index('STORE_NAME') +STORE_GLOBAL = dis.opname.index('STORE_GLOBAL') STORE_OPS = [STORE_NAME, STORE_GLOBAL] -HAVE_ARGUMENT = bytes([dis.HAVE_ARGUMENT]) +HAVE_ARGUMENT = dis.HAVE_ARGUMENT # Monkeypatch some missing methods in Python 3.3's NamespaceLoader def __patch_py33(): @@ -317,11 +317,43 @@ try: loader = importlib.find_loader(name, path) except ValueError as details: + # XXX XXX XXX + # namespace modules only have these attributes (in Python 3.4, when + # a xxx.pth file is present in Lib/site-packages: + # + # __doc__: None + # __loader__: None + # __name__: <the module name> + # __package__: None + # __path__: [<the directory name>] + # __spec__: None + # + # + # When the xxx.pth file is NOT present: + # + # __doc__: None + # __loader__: <_frozen_importlib._NamespaceLoader object at ...> + # __name__: <the module name> + # __package__: <the module name> + # __path__: <_NamespacePath([<the directory name>]> + # __spec__: ModuleSpec(name=<module_name>, origin='namespace', + # submodule_search_locations=_NamespacePath([<dir name>])) + # Python 3.4 raises this error for namespace packages if str(details) == "{}.__loader__ is None".format(name): - msg = "Error: Namespace packages not yet supported: Skipping package {!r}" - print(msg.format(name)) - loader = None + ## msg = "Error: Namespace packages not yet supported: Skipping package {!r}" + from importlib._bootstrap import _NamespaceLoader + ## print(msg.format(name)) + ## loader = None + loader = _NamespaceLoader(name, path, None) + self._load_module(loader, name) + mod = self.modules[name] + real_mod = __import__(name) + print("PATH", path) + print("__path__", dir(real_mod)) + mod.__path__ = real_mod.__path__ + for n in dir(mod): + print(n, getattr(mod, n)) else: raise except AttributeError as details: @@ -406,26 +438,43 @@ Scan the code object, and yield 'interesting' opcode combinations """ - code = co.co_code - names = co.co_names - consts = co.co_consts - LOAD_LOAD_AND_IMPORT = LOAD_CONST + LOAD_CONST + IMPORT_NAME - while code: - c = bytes([code[0]]) - if c in STORE_OPS: - oparg, = unpack('<H', code[1:3]) - yield "store", (names[oparg],) - code = code[3:] - continue - if code[:9:3] == LOAD_LOAD_AND_IMPORT: - oparg_1, oparg_2, oparg_3 = unpack('<xHxHxH', code[:9]) - yield "import", (consts[oparg_1], consts[oparg_2], names[oparg_3]) - code = code[9:] - continue - if c >= HAVE_ARGUMENT: - code = code[3:] - else: - code = code[1:] + if hasattr(dis, "get_instructions"): + # dis.get_instructions() is only available in python 3.4 + # and higher + instructions = [] + for inst in dis.get_instructions(co): + instructions.append(inst) + c = inst.opcode + if c == IMPORT_NAME: + assert instructions[-3].opcode == LOAD_CONST + level = instructions[-3].argval + assert instructions[-2].opcode == LOAD_CONST + fromlist = instructions[-2].argval + name = inst.argval + yield "import", (level, fromlist, name) + elif c in STORE_OPS: + yield "store", (inst.argval,) + else: + code = co.co_code + names = co.co_names + consts = co.co_consts + LOAD_LOAD_AND_IMPORT = LOAD_CONST + LOAD_CONST + IMPORT_NAME + while code: + c = code[0] + if c in STORE_OPS: + oparg, = unpack('<H', code[1:3]) + yield "store", (names[oparg],) + code = code[3:] + continue + if code[:9:3] == LOAD_LOAD_AND_IMPORT: + oparg_1, oparg_2, oparg_3 = unpack('<xHxHxH', code[:9]) + yield "import", (consts[oparg_1], consts[oparg_2], names[oparg_3]) + code = code[9:] + continue + if c >= HAVE_ARGUMENT: + code = code[3:] + else: + code = code[1:] def ignore(self, name): """If the module or package with the given name is not found, @@ -621,7 +670,11 @@ if self.__optimize__ == sys.flags.optimize: self.__code_object__ = self.__loader__.get_code(self.__name__) else: - source = self.__source__ + try: + source = self.__source__ + except Exception: + import traceback; traceback.print_exc() + raise RuntimeError("loading %r" % self) from None if source is not None: # XXX??? for py3exe: __file__ = self.__file__ \ Modified: trunk/py2exe-3/py2exe/mf34.py =================================================================== --- trunk/py2exe-3/py2exe/mf34.py 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/py2exe/mf34.py 2017-01-04 15:34:08 UTC (rev 766) @@ -1,4 +1,4 @@ -#!/usr/bin/python3.3 +#!/usr/bin/python3.4 # -*- coding: utf-8 -*- """ModuleFinder based on importlib """ @@ -14,6 +14,7 @@ import struct import sys import textwrap +import warnings # XXX Clean up once str8's cstor matches bytes. LOAD_CONST = bytes([dis.opname.index('LOAD_CONST')]) @@ -23,31 +24,7 @@ STORE_OPS = [STORE_NAME, STORE_GLOBAL] HAVE_ARGUMENT = bytes([dis.HAVE_ARGUMENT]) -# Monkeypatch some missing methods in Python 3.3's NamespaceLoader -def __patch_py33(): - if sys.version_info < (3, 4): - def is_package(self, fullname): - return True - def get_source(self, fullname): - return '' - - def get_code(self, fullname): - return compile('', '<string>', 'exec', dont_inherit=True) - - def init_module_attrs(self, module): - module.__loader__ = self - module.__package__ = module.__name__ - from importlib._bootstrap import NamespaceLoader - NamespaceLoader.is_package = is_package - NamespaceLoader.get_source = get_source - NamespaceLoader.get_code = get_code - NamespaceLoader.init_module_attrs = init_module_attrs - -__patch_py33() -del __patch_py33 - - class ModuleFinder: def __init__(self, path=None, verbose=0, excludes=None, optimize=0, ignores=None): @@ -79,7 +56,11 @@ """ assert "__SCRIPT__" not in sys.modules ldr = importlib.machinery.SourceFileLoader("__SCRIPT__", path) - mod = Module(ldr, "__SCRIPT__", self._optimize) + if sys.version_info >= (3, 4): + spec = importlib.machinery.ModuleSpec("__SCRIPT__", ldr) + mod = Module(spec, "__SCRIPT__", self._optimize) + else: + mod = Module(ldr, "__SCRIPT__", self._optimize) # Do NOT add it... # self._add_module("__SCRIPT__", mod) self._scan_code(mod.__code__, mod) @@ -95,6 +76,8 @@ raise TypeError("{0} is not a package".format(name)) for finder, modname, ispkg in pkgutil.iter_modules(package.__path__): self.safe_import_hook("%s.%s" % (name, modname)) + if ispkg: + self.import_package("%s.%s" % (name, modname)) def import_hook(self, name, caller=None, fromlist=(), level=0): @@ -298,14 +281,27 @@ msg = ('No module named {!r}; {} is not a package').format(name, parent) self._add_badmodule(name) raise ImportError(msg, name=name) - loader = importlib.find_loader(name, path) - if loader is None: + try: + spec = importlib.util.find_spec(name, path) + except ValueError as details: + # workaround for the .pth file for namespace packages that + # setuptools installs. The pth file inserts a 'damaged' + # module into sys.modules: it has no __spec__. Reloading + # the module helps (at least in Python3.4). + if details.args[0] == '{}.__spec__ is None'.format(name): + import imp + _ = __import__(name, path) + imp.reload(_) + spec = importlib.util.find_spec(name, path) + else: + raise + if spec is None: self._add_badmodule(name) raise ImportError(name) elif name not in self.modules: # The parent import may have already imported this module. try: - self._load_module(loader, name) + self._load_module(spec, name) except ImportError: self._add_badmodule(name) raise @@ -335,8 +331,8 @@ self.modules[name] = mod - def _load_module(self, loader, name): - mod = Module(loader, name, self._optimize) + def _load_module(self, spec, name): + mod = Module(spec, name, self._optimize) self._add_module(name, mod) if name in self._package_paths: mod.__path__.extend(self._package_paths[name]) @@ -481,8 +477,10 @@ print("P", end=" ") else: print("m", end=" ") - print("%-35s" % name, getattr(m, "__file__", - "(built-in, frozen, or namespace)")) + if m.__spec__.has_location and hasattr(m, "__file__"): + print("%-35s" % name, getattr(m, "__file__")) + else: + print("%-35s" % name, "(%s)" % m.__spec__.origin) deps = sorted(self._depgraph[name]) text = "\n".join(textwrap.wrap(", ".join(deps))) print(" imported from:\n%s" % textwrap.indent(text, " ")) @@ -549,14 +547,16 @@ extension modules) """ - def __init__(self, loader, name, optimize): + def __init__(self, spec, name, optimize): self.__optimize__ = optimize self.__globalnames__ = set() self.__name__ = name - self.__loader__ = loader + self.__spec__ = spec self.__code_object__ = None + loader = self.__loader__ = spec.loader + if hasattr(loader, "get_filename"): # python modules fnm = loader.get_filename(name) @@ -569,6 +569,9 @@ self.__file__ = fnm if loader.is_package(name): self.__path__ = [os.path.dirname(fnm)] + elif spec.origin == "namespace": + # namespace modules have no loader + self.__path__ = spec.submodule_search_locations else: # frozen or builtin modules if loader.is_package(name): @@ -585,13 +588,12 @@ @property def __code__(self): - if self.__code_object__ is None: + if self.__code_object__ is None and self.__loader__ is not None: if self.__optimize__ == sys.flags.optimize: self.__code_object__ = self.__loader__.get_code(self.__name__) else: source = self.__source__ if source is not None: - # XXX??? for py3exe: __file__ = self.__file__ \ if hasattr(self, "__file__") else "<string>" try: Modified: trunk/py2exe-3/py2exe/py2exe_distutils.py =================================================================== --- trunk/py2exe-3/py2exe/py2exe_distutils.py 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/py2exe/py2exe_distutils.py 2017-01-04 15:34:08 UTC (rev 766) @@ -6,10 +6,12 @@ from distutils.command import build_ext, build from distutils.sysconfig import customize_compiler from distutils.dep_util import newer_group -from distutils.errors import DistutilsError, DistutilsSetupError +from distutils.errors import DistutilsError, DistutilsSetupError, DistutilsPlatformError +from distutils.errors import CCompilerError, CompileError from distutils.util import get_platform +from distutils import log -# We don't need a manifest in the executable, so monkeypath the code away: +# We don't need a manifest in the executable, so monkeypatch the code away: from distutils.msvc9compiler import MSVCCompiler MSVCCompiler.manifest_setup_ldargs = lambda *args: None @@ -40,134 +42,30 @@ description = "build special python interpreter stubs" def finalize_options(self): - build_ext.build_ext.finalize_options(self) + super().finalize_options() self.interpreters = self.distribution.interpreters - def run (self): + def run(self): + # Copied from build_ext.run() except that we use + # self.interpreters instead of self.extensions and + # self.build_interpreters() instead of self.build_extensions() + from distutils.ccompiler import new_compiler + if not self.interpreters: return - self.setup_compiler() - - # Now actually compile and link everything. - for inter in self.interpreters: - sources = inter.sources - if sources is None or type(sources) not in (type([]), type(())): - raise DistutilsSetupError(("in 'interpreters' option ('%s'), " + - "'sources' must be present and must be " + - "a list of source filenames") % inter.name) - sources = list(sources) - - fullname = self.get_exe_fullname(inter.name) - if self.inplace: - # ignore build-lib -- put the compiled extension into - # the source tree along with pure Python modules - modpath = fullname.split('.') - package = '.'.join(modpath[0:-1]) - base = modpath[-1] - - build_py = self.get_finalized_command('build_py') - package_dir = build_py.get_package_dir(package) - exe_filename = os.path.join(package_dir, - self.get_exe_filename(base)) - else: - exe_filename = os.path.join(self.build_lib, - self.get_exe_filename(fullname)) - if inter.target_desc == "executable": - exe_filename += ".exe" - else: - exe_filename += ".dll" - - if not (self.force or \ - newer_group(sources + inter.depends, exe_filename, 'newer')): - self.announce("skipping '%s' interpreter (up-to-date)" % - inter.name) - continue # 'for' loop over all interpreters - else: - self.announce("building '%s' interpreter" % inter.name) - - extra_args = inter.extra_compile_args or [] - - macros = inter.define_macros[:] - for undef in inter.undef_macros: - macros.append((undef,)) - - objects = self.compiler.compile(sources, - output_dir=self.build_temp, - macros=macros, - include_dirs=inter.include_dirs, - debug=self.debug, - extra_postargs=extra_args, - depends=inter.depends) - - if inter.extra_objects: - objects.extend(inter.extra_objects) - extra_args = inter.extra_link_args or [] - - if inter.export_symbols: - # The mingw32 compiler writes a .def file containing - # the export_symbols. Since py2exe uses symbols in - # the extended form 'DllCanUnloadNow,PRIVATE' (to - # avoid MS linker warnings), we have to replace the - # comma(s) with blanks, so that the .def file can be - # properly parsed. - # XXX MingW32CCompiler, or CygwinCCompiler ? - from distutils.cygwinccompiler import Mingw32CCompiler - if isinstance(self.compiler, Mingw32CCompiler): - inter.export_symbols = [s.replace(",", " ") for s in inter.export_symbols] - inter.export_symbols = [s.replace("=", "\t") for s in inter.export_symbols] - - # XXX - is msvccompiler.link broken? From what I can see, the - # following should work, instead of us checking the param: - self.compiler.link(inter.target_desc, - objects, exe_filename, - libraries=self.get_libraries(inter), - library_dirs=inter.library_dirs, - runtime_library_dirs=inter.runtime_library_dirs, - export_symbols=inter.export_symbols, - extra_postargs=extra_args, - debug=self.debug) - # build_extensions () - - def get_exe_fullname (self, inter_name): - if self.package is None: - return inter_name - else: - return self.package + '.' + inter_name - - def get_exe_filename (self, inter_name): - ext_path = inter_name.split('.') - if self.debug: - fnm = os.path.join(*ext_path) + '_d' - else: - fnm = os.path.join(*ext_path) - if ext_path[-1] == "resources": - return fnm - return '%s-py%s.%s-%s' % (fnm, sys.version_info[0], sys.version_info[1], get_platform()) - - def setup_compiler(self): - # This method *should* be available separately in build_ext! - from distutils.ccompiler import new_compiler - - # If we were asked to build any C/C++ libraries, make sure that the - # directory where we put them is in the library search path for - # linking interpreters. - if self.distribution.has_c_libraries(): - build_clib = self.get_finalized_command('build_clib') - self.libraries.extend(build_clib.get_library_names() or []) - self.library_dirs.append(build_clib.build_clib) - # Setup the CCompiler object that we'll use to do all the # compiling and linking self.compiler = new_compiler(compiler=self.compiler, verbose=self.verbose, dry_run=self.dry_run, force=self.force) - try: - self.compiler.initialize() - except AttributeError: - pass # initialize doesn't exist before 2.5 customize_compiler(self.compiler) + # If we are cross-compiling, init the compiler now (if we are not + # cross-compiling, init would not hurt, but people may rely on + # late initialization of compiler even if they shouldn't...) + if os.name == 'nt' and self.plat_name != get_platform(): + self.compiler.initialize(self.plat_name) # And make sure that any compile/link-related options (which might # come from the command-line or from the setup script) are set in @@ -176,8 +74,8 @@ if self.include_dirs is not None: self.compiler.set_include_dirs(self.include_dirs) if self.define is not None: - # 'define' option is a list of (name, value) tuples - for (name,value) in self.define: + # 'define' option is a list of (name,value) tuples + for (name, value) in self.define: self.compiler.define_macro(name, value) if self.undef is not None: for macro in self.undef: @@ -191,10 +89,125 @@ if self.link_objects is not None: self.compiler.set_link_objects(self.link_objects) - # setup_compiler() + # Now actually compile and link everything. + self.build_interpreters() -# class BuildInterpreters + def build_interpreters(self): + for interp in self.interpreters: + self.build_interp(interp) + + def build_interp(self, ext): + sources = ext.sources + if sources is None or not isinstance(sources, (list, tuple)): + raise DistutilsSetupError( + "in 'interpreters' option (extension '%s'), " + "'sources' must be present and must be " + "a list of source filenames" % ext.name) + sources = list(sources) + + ext_path = self.get_ext_fullpath(ext.name) + + if ext.target_desc == "executable": + ext_path += ".exe" + else: + ext_path += ".dll" + + depends = sources + ext.depends + if not (self.force or newer_group(depends, ext_path, 'newer')): + log.debug("skipping '%s' extension (up-to-date)", ext.name) + return + else: + log.info("building '%s' extension", ext.name) + + # First, compile the source code to object files. + + # XXX not honouring 'define_macros' or 'undef_macros' -- the + # CCompiler API needs to change to accommodate this, and I + # want to do one thing at a time! + + # Two possible sources for extra compiler arguments: + # - 'extra_compile_args' in Extension object + # - CFLAGS environment variable (not particularly + # elegant, but people seem to expect it and I + # guess it's useful) + # The environment variable should take precedence, and + # any sensible compiler will give precedence to later + # command line args. Hence we combine them in order: + extra_args = ext.extra_compile_args or [] + + macros = ext.define_macros[:] + for undef in ext.undef_macros: + macros.append((undef,)) + + objects = self.compiler.compile(sources, + output_dir=self.build_temp, + macros=macros, + include_dirs=ext.include_dirs, + debug=self.debug, + extra_postargs=extra_args, + depends=ext.depends) + + # XXX -- this is a Vile HACK! + # + # The setup.py script for Python on Unix needs to be able to + # get this list so it can perform all the clean up needed to + # avoid keeping object files around when cleaning out a failed + # build of an extension module. Since Distutils does not + # track dependencies, we have to get rid of intermediates to + # ensure all the intermediates will be properly re-built. + # + self._built_objects = objects[:] + + # Now link the object files together into a "shared object" -- + # of course, first we have to figure out all the other things + # that go into the mix. + if ext.extra_objects: + objects.extend(ext.extra_objects) + extra_args = ext.extra_link_args or [] + + # Detect target language, if not provided +## language = ext.language or self.compiler.detect_language(sources) + + ## self.compiler.link_shared_object( + ## objects, ext_path, + ## libraries=self.get_libraries(ext), + ## library_dirs=ext.library_dirs, + ## runtime_library_dirs=ext.runtime_library_dirs, + ## extra_postargs=extra_args, + ## export_symbols=self.get_export_symbols(ext), + ## debug=self.debug, + ## build_temp=self.build_temp, + ## target_lang=language) + + # Hm, for Python 3.5 to link a shared library (instead of exe + # or pyd) we need to add /DLL to the linker arguments. + # Currently this is done in the setup script; should we do it + # here? + + self.compiler.link(ext.target_desc, + objects, ext_path, + libraries=self.get_libraries(ext), + library_dirs=ext.library_dirs, + runtime_library_dirs=ext.runtime_library_dirs, + export_symbols=ext.export_symbols, + extra_postargs=extra_args, + debug=self.debug) + + + # -- Name generators ----------------------------------------------- + + def get_ext_filename (self, inter_name): + ext_path = inter_name.split('.') + if self.debug: + fnm = os.path.join(*ext_path) + '_d' + else: + fnm = os.path.join(*ext_path) + if ext_path[-1] == "resources": + return fnm + return '%s-py%s.%s-%s' % (fnm, sys.version_info[0], sys.version_info[1], get_platform()) + + def InstallSubCommands(): """Adds our own sub-commands to build and install""" has_interpreters = lambda self: self.distribution.has_interpreters() Modified: trunk/py2exe-3/py2exe/runtime.py =================================================================== --- trunk/py2exe-3/py2exe/runtime.py 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/py2exe/runtime.py 2017-01-04 15:34:08 UTC (rev 766) @@ -423,7 +423,7 @@ arc.writestr(path, stream.getvalue()) elif hasattr(mod, "__file__"): - assert mod.__file__.endswith(EXTENSION_SUFFIXES[0]) + assert mod.__file__.endswith(tuple(EXTENSION_SUFFIXES)) if self.options.bundle_files <= 2: # put .pyds into the archive arcfnm = mod.__name__.replace(".", "\\") + EXTENSION_SUFFIXES[0] @@ -495,7 +495,7 @@ # nothing to do for python modules. continue if hasattr(mod, "__file__"): - assert mod.__file__.endswith(EXTENSION_SUFFIXES[0]) + assert mod.__file__.endswith(tuple(EXTENSION_SUFFIXES)) pydfile = mod.__name__ + EXTENSION_SUFFIXES[0] dst = os.path.join(libdir, pydfile) Modified: trunk/py2exe-3/setup.py =================================================================== --- trunk/py2exe-3/setup.py 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/setup.py 2017-01-04 15:34:08 UTC (rev 766) @@ -40,11 +40,12 @@ extra_link_args = [] if 0: - # enable this to debug a release build + # XXX enable this to debug a release build, otherwise let disabled + # because the .PDB files are huge. extra_compile_args.append("/Od") extra_compile_args.append("/Z7") extra_link_args.append("/DEBUG") - macros.append(("VERBOSE", "1")) + #macros.append(("VERBOSE", "1")) run_ctypes_dll = Interpreter("py2exe.run_ctypes_dll", ["source/run_ctypes_dll.c", @@ -67,7 +68,7 @@ target_desc = "shared_library", define_macros=macros, extra_compile_args=extra_compile_args, - extra_link_args=extra_link_args, + extra_link_args=extra_link_args + ["/DLL"], ) run = Interpreter("py2exe.run", @@ -119,7 +120,7 @@ ["source/dll.c", "source/icon.rc"], target_desc = "shared_library", - extra_link_args=["/NOENTRY"], + extra_link_args=["/DLL", "/NOENTRY"], ) interpreters = [run, run_w, resource_dll, @@ -132,12 +133,12 @@ else: class my_bdist_wheel(bdist_wheel.bdist_wheel): """We change the bdist_wheel command so that it creates a - wheel-file compatible with Python 3.3 and Python 3.4 only by - setting the impl_tag to py33.py34. + wheel-file compatible with CPython, 3.4, 3.5, and 3.6 only + by setting the impl_tag to 'cp33.cp34.cp35.cp36' """ def get_tag(self): impl_tag, abi_tag, plat_tag = super().get_tag() - return "py33.py34", abi_tag, plat_tag + return "cp33.cp34.cp35.cp36", abi_tag, plat_tag if __name__ == "__main__": Modified: trunk/py2exe-3/source/MyLoadLibrary.c =================================================================== --- trunk/py2exe-3/source/MyLoadLibrary.c 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/source/MyLoadLibrary.c 2017-01-04 15:34:08 UTC (rev 766) @@ -198,7 +198,8 @@ if (lib) return lib->module; SetLastError(0); - return GetModuleHandle(name); + return NULL; + //return GetModuleHandle(name); } HMODULE MyLoadLibrary(LPCSTR name, void *bytes, void *userdata) Modified: trunk/py2exe-3/source/Python-dynload.h =================================================================== --- trunk/py2exe-3/source/Python-dynload.h 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/source/Python-dynload.h 2017-01-04 15:34:08 UTC (rev 766) @@ -1,9 +1,11 @@ #define Py_OptimizeFlag *(_Py_OptimizeFlag_PTR()) #define Py_NoSiteFlag *(_Py_NoSiteFlag_PTR()) #define Py_VerboseFlag *(_Py_VerboseFlag_PTR()) +#define _Py_PackageContext *(__Py_PackageContext_PTR()) extern int *_Py_OptimizeFlag_PTR(); extern int *_Py_NoSiteFlag_PTR(); extern int *_Py_VerboseFlag_PTR(); +extern char **__Py_PackageContext_PTR(); extern int PythonLoaded(HMODULE hmod); Modified: trunk/py2exe-3/source/_memimporter.c =================================================================== --- trunk/py2exe-3/source/_memimporter.c 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/source/_memimporter.c 2017-01-04 15:34:08 UTC (rev 766) @@ -52,7 +52,7 @@ PyObject* (*p)(void); PyObject *m = NULL; struct PyModuleDef *def; -// char *oldcontext; + char *oldcontext; PyObject *name = PyUnicode_FromString(modname); if (name == NULL) @@ -75,16 +75,16 @@ Py_DECREF(name); return -1; } -/* + oldcontext = _Py_PackageContext; _Py_PackageContext = modname; -*/ + p = (PyObject*(*)(void))init_func; m = (*p)(); -/* + _Py_PackageContext = oldcontext; -*/ + if (PyErr_Occurred()) { Py_DECREF(name); return -1; Modified: trunk/py2exe-3/source/python-dynload.c =================================================================== --- trunk/py2exe-3/source/python-dynload.c 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/source/python-dynload.c 2017-01-04 15:34:08 UTC (rev 766) @@ -55,6 +55,11 @@ DATA(int *, Py_VerboseFlag); } +char **__Py_PackageContext_PTR() +{ + DATA(char **, _Py_PackageContext); +} + //////////////////////////////////////////////////////////////// int Py_IsInitialized(void) Modified: trunk/py2exe-3/source/run_ctypes_dll.c =================================================================== --- trunk/py2exe-3/source/run_ctypes_dll.c 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/source/run_ctypes_dll.c 2017-01-04 15:34:08 UTC (rev 766) @@ -81,6 +81,7 @@ extern int init_with_instance(HMODULE, char *); extern void fini(); extern int run_script(void); +extern wchar_t libfilename[_MAX_PATH + _MAX_FNAME + _MAX_EXT]; #include "MyLoadLibrary.h" @@ -90,7 +91,9 @@ int load_ctypes(void) { char dll_path[_MAX_PATH+_MAX_FNAME+1]; - + wchar_t ctypes_path[_MAX_PATH+_MAX_FNAME+1]; + wchar_t * temp=NULL; + int length=0; // shouldn't do this twice assert(g_ctypes == NULL); @@ -104,7 +107,14 @@ if (g_ctypes == NULL) { // not already loaded - try and load from the current dir // char *temp; - GetModuleFileNameA(gInstance, dll_path, sizeof(dll_path)); + //wrong, this is myself, makes an endless loop... + //GetModuleFileNameA(gInstance, dll_path, sizeof(dll_path)); + temp=wcsrchr(libfilename,L'\\'); + length=temp-(wchar_t*)libfilename+1; + wcscpy(ctypes_path,libfilename); + ctypes_path[length]=L'\0'; + wcscat(ctypes_path,L"_ctypes.pyd"); + /* ??? temp = dll_path + strlen(dll_path); while (temp>dll_path && *temp != '\\') @@ -113,13 +123,14 @@ // temp points to '\\filename.ext'! */ /* ??? + #ifdef _DEBUG g_ctypes = MyGetModuleHandle("_ctypes_d.pyd"); #else g_ctypes = MyGetModuleHandle("_ctypes.pyd"); #endif */ - g_ctypes = LoadLibraryEx(dll_path, // points to name of executable module + g_ctypes = LoadLibraryExW(ctypes_path, // points to name of executable module NULL, // HANDLE hFile, // reserved, must be NULL LOAD_WITH_ALTERED_SEARCH_PATH // DWORD dwFlags // entry-point execution flag ); @@ -202,7 +213,8 @@ // ***************************************************************** BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { - if ( dwReason == DLL_PROCESS_ATTACH) { + OutputDebugString("DllMain"); + if ( dwReason == DLL_PROCESS_ATTACH) { gInstance = hInstance; InitializeCriticalSection(&csInit); _MyLoadActCtxPointers(); @@ -224,7 +236,10 @@ HRESULT __stdcall DllCanUnloadNow(void) { HRESULT rc; + ULONG_PTR cookie = 0; + cookie = _My_ActivateActCtx(); // some windows manifest magic... check_init(); + _My_DeactivateActCtx(cookie); assert(Pyc_DllCanUnloadNow); if (!Pyc_DllCanUnloadNow) return E_UNEXPECTED; rc = Pyc_DllCanUnloadNow(); @@ -235,10 +250,22 @@ HRESULT __stdcall DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) { HRESULT rc; + ULONG_PTR cookie = 0; + /* + OutputDebugString("DllGetClassObject"); + + MessageBox(NULL,"Debug\n", + "DllGetClassObject", + MB_OK | MB_ICONINFORMATION); + */ + cookie = _My_ActivateActCtx(); // some windows manifest magic... check_init(); + assert(Pyc_DllGetClassObject); if (!Pyc_DllGetClassObject) return E_UNEXPECTED; rc = Pyc_DllGetClassObject(rclsid, riid, ppv); + _My_DeactivateActCtx(cookie); + return rc; } @@ -247,8 +274,28 @@ { int rc=0; PyGILState_STATE state; + wchar_t buf[300]; + ULONG_PTR cookie = 0; + + OutputDebugString("DllRegisterServer"); + /* + MessageBox(NULL, + "Debug\n", + "DllregisterServer", + MB_OK | MB_ICONINFORMATION); + */ + cookie = _My_ActivateActCtx(); // some windows manifest magic... check_init(); + _My_DeactivateActCtx(cookie); + + OutputDebugString("check_init ok"); + state = PyGILState_Ensure(); + OutputDebugString("PyGILState_Ensure done"); + + swprintf(buf,300,L"DllRegisterServer: libfilename=%s\n",&libfilename); + OutputDebugStringW(buf); + rc = PyRun_SimpleString("DllRegisterServer()\n"); if (rc != 0) PyErr_Print(); @@ -260,7 +307,11 @@ { int rc=0; PyGILState_STATE state; + ULONG_PTR cookie = 0; + cookie = _My_ActivateActCtx(); // some windows manifest magic... check_init(); + _My_DeactivateActCtx(cookie); + state = PyGILState_Ensure(); rc = PyRun_SimpleString("DllUnregisterServer()\n"); if (rc != 0) Modified: trunk/py2exe-3/zipextimporter.py =================================================================== --- trunk/py2exe-3/zipextimporter.py 2014-10-21 15:22:50 UTC (rev 765) +++ trunk/py2exe-3/zipextimporter.py 2017-01-04 15:34:08 UTC (rev 766) @@ -75,6 +75,7 @@ def load_module(self, fullname): verbose = _memimporter.get_verbose_flag() + if fullname in sys.modules: mod = sys.modules[fullname] if verbose: @@ -84,37 +85,39 @@ return mod try: return zipimport.zipimporter.load_module(self, fullname) - except ImportError: - pass - if sys.version_info >= (3, 0): - # name of initfunction - initname = "PyInit_" + fullname.split(".")[-1] - else: - # name of initfunction - initname = "init" + fullname.split(".")[-1] - filename = fullname.replace(".", "\\") - if filename in ("pywintypes", "pythoncom"): - filename = filename + "%d%d" % sys.version_info[:2] - suffixes = ('.dll',) - else: - suffixes = self._suffixes - for s in suffixes: - path = filename + s - if path in self._files: - if verbose > 1: - sys.stderr.write("# found %s in zipfile %s\n" - % (path, self.archive)) - mod = _memimporter.import_module(fullname, path, - initname, - self.get_data) - mod.__file__ = "%s\\%s" % (self.archive, path) - mod.__loader__ = self - if verbose: - sys.stderr.write("import %s # loaded from zipfile %s\n" - % (fullname, mod.__file__)) - return mod - raise zipimport.ZipImportError("can't find module %s" % fullname) + except ImportError as err: + if verbose: + sys.stderr.write("error loading %s: %s\n"% (fullname, err)) + if sys.version_info >= (3, 0): + # name of initfunction + initname = "PyInit_" + fullname.split(".")[-1] + else: + # name of initfunction + initname = "init" + fullname.split(".")[-1] + filename = fullname.replace(".", "\\") + if filename in ("pywintypes", "pythoncom"): + filename = filename + "%d%d" % sys.version_info[:2] + suffixes = ('.dll',) + else: + suffixes = self._suffixes + for s in suffixes: + path = filename + s + if path in self._files: + if verbose > 1: + sys.stderr.write("# found %s in zipfile %s\n" + % (path, self.archive)) + mod = _memimporter.import_module(fullname, path, + initname, + self.get_data) + mod.__file__ = "%s\\%s" % (self.archive, path) + mod.__loader__ = self + if verbose: + sys.stderr.write("import %s # loaded from zipfile %s\n" + % (fullname, mod.__file__)) + return mod + raise zipimport.ZipImportError("can't find module %s" % fullname) from err + def __repr__(self): return "<%s object %r>" % (self.__class__.__name__, self.archive) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-10-21 15:22:54
|
Revision: 765 http://sourceforge.net/p/py2exe/svn/765 Author: theller Date: 2014-10-21 15:22:50 +0000 (Tue, 21 Oct 2014) Log Message: ----------- Final version 0.9.2.2. Modified Paths: -------------- trunk/py2exe-3/ChangeLog trunk/py2exe-3/README.rst trunk/py2exe-3/py2exe/__init__.py Modified: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog 2014-10-17 12:52:49 UTC (rev 764) +++ trunk/py2exe-3/ChangeLog 2014-10-21 15:22:50 UTC (rev 765) @@ -1,3 +1,7 @@ +2014-10-21 <th...@ct...> + + * Released py2exe 0.9.2.2. + 2014-10-17 <th...@ct...> * py2exe/hooks.py: Add hook for the six compatibility Modified: trunk/py2exe-3/README.rst =================================================================== --- trunk/py2exe-3/README.rst 2014-10-17 12:52:49 UTC (rev 764) +++ trunk/py2exe-3/README.rst 2014-10-21 15:22:50 UTC (rev 765) @@ -11,7 +11,15 @@ .. contents:: +Changes +------- +Version 0.9.2.2: Added support for six, cffi, pycparser, openssl. +Support cmdline_style ("py2exe", "pywin32", "custom") again for +windows services. +Several bugfixes, better error messages. + + News ---- Modified: trunk/py2exe-3/py2exe/__init__.py =================================================================== --- trunk/py2exe-3/py2exe/__init__.py 2014-10-17 12:52:49 UTC (rev 764) +++ trunk/py2exe-3/py2exe/__init__.py 2014-10-21 15:22:50 UTC (rev 765) @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """py2exe package """ -__version__ = "0.9.2.1" +__version__ = "0.9.2.2" from .patch_distutils import patch_distutils This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-10-17 12:52:53
|
Revision: 764 http://sourceforge.net/p/py2exe/svn/764 Author: theller Date: 2014-10-17 12:52:49 +0000 (Fri, 17 Oct 2014) Log Message: ----------- py2exe/hooks.py: Add hook for the six compatibility library. py2exe does now understand the renaming of modules/packages the six.py does. Modified Paths: -------------- trunk/py2exe-3/ChangeLog trunk/py2exe-3/py2exe/hooks.py trunk/py2exe-3/py2exe/mf3.py trunk/py2exe-3/py2exe/runtime.py Modified: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog 2014-10-17 09:30:39 UTC (rev 763) +++ trunk/py2exe-3/ChangeLog 2014-10-17 12:52:49 UTC (rev 764) @@ -1,5 +1,11 @@ 2014-10-17 <th...@ct...> + * py2exe/hooks.py: Add hook for the six compatibility + library. py2exe does now understand the renaming of + modules/packages the six.py does. + +2014-10-17 <th...@ct...> + * py2exe/hooks.py: Add hooks for pycparser, OpenSSL, cffi. cffi needs some hacks so that it works from within zipfiles. Modified: trunk/py2exe-3/py2exe/hooks.py =================================================================== --- trunk/py2exe-3/py2exe/hooks.py 2014-10-17 09:30:39 UTC (rev 763) +++ trunk/py2exe-3/py2exe/hooks.py 2014-10-17 12:52:49 UTC (rev 764) @@ -262,11 +262,46 @@ finder.set_min_bundle("tkinter", 2) def hook_six(finder, module): - """six.py is a python2/python3 compatibility library. Exclude the - python2 modules. + """six.py has an object 'moves'. This allows to import + modules/packages via attribute access under new names. + + We install a fake module named 'six.moves' which simulates this + behaviour. """ - finder.ignore("StringIO") + class SixImporter(type(module)): + """Simulate six.moves. + + Import renamed modules when retrived as attributes. + """ + + __code__ = None + + def __init__(self, mf, *args, **kw): + import six + self.__moved_modules = {item.name: item.mod + for item in six._moved_attributes + if isinstance(item, six.MovedModule)} + super().__init__(*args, **kw) + self.__finder = mf + + def __getattr__(self, name): + if name in self.__moved_modules: + renamed = self.__moved_modules[name] + self.__finder.safe_import_hook(renamed, caller=self) + mod = self.__finder.modules[renamed] + # add the module again with the renamed name: + self.__finder._add_module("six.moves." + name, mod) + return mod + else: + raise AttributeError(name) + + m = SixImporter(finder, + None, "six.moves", finder._optimize) + finder._add_module("six.moves", m) + + + def hook_matplotlib(finder, module): """matplotlib requires data files in a 'mpl-data' subdirectory in the same directory as the executable. Modified: trunk/py2exe-3/py2exe/mf3.py =================================================================== --- trunk/py2exe-3/py2exe/mf3.py 2014-10-17 09:30:39 UTC (rev 763) +++ trunk/py2exe-3/py2exe/mf3.py 2014-10-17 12:52:49 UTC (rev 764) @@ -291,13 +291,26 @@ return self.modules[name] # Backwards-compatibility; be nicer to skip the dict lookup. parent_module = self.modules[parent] + try: + # try lazy imports via attribute access (six.moves + # does this)... + getattr(parent_module, name.rpartition('.')[2]) + module = self.modules[name] + except (AttributeError, KeyError): + pass + else: + if hasattr(module, "__code__"): + self._scan_code(module.__code__, module) + return module + + try: path = parent_module.__path__ except AttributeError: - # this fixes 'import os.path'. Does it create other problems? - child = name.rpartition('.')[2] - if child in parent_module.__globalnames__: - return parent_module + ## # this fixes 'import os.path'. Does it create other problems? + ## child = name.rpartition('.')[2] + ## if child in parent_module.__globalnames__: + ## return parent_module msg = ('No module named {!r}; {} is not a package').format(name, parent) self._add_badmodule(name) raise ImportError(msg, name=name) @@ -588,7 +601,7 @@ self.__file__ = fnm if loader.is_package(name): self.__path__ = [os.path.dirname(fnm)] - else: + elif hasattr(loader, "is_package"): # frozen or builtin modules if loader.is_package(name): self.__path__ = [name] @@ -697,6 +710,11 @@ --summary Print a single line listing how many modules were found and how many modules are missing + + -m + --missing + Print detailed report about missing modules + """ text = textwrap.dedent(helptext.format(os.path.basename(script))) @@ -706,7 +724,7 @@ import getopt try: opts, args = getopt.gnu_getopt(sys.argv[1:], - "x:f:hi:Op:rsv", + "x:f:hi:Op:rsvm", ["exclude=", "from=", "help", @@ -716,6 +734,7 @@ "report", "summary", "verbose", + "missing", ]) except getopt.GetoptError as err: print("Error: %s." % err) @@ -729,6 +748,7 @@ optimize = 0 summary = 0 packages = [] + missing = 0 for o, a in opts: if o in ("-h", "--help"): usage(sys.argv[0]) @@ -749,6 +769,8 @@ summary = 1 elif o in ("-p", "--package"): packages.append(a) + elif o in ("-m", "--missing"): + missing = 1 mf = ModuleFinder( excludes=excludes, @@ -767,6 +789,8 @@ mf.run_script(path) if report: mf.report() + if missing: + mf.report_missing() if summary: mf.report_summary() for modname in show_from: Modified: trunk/py2exe-3/py2exe/runtime.py =================================================================== --- trunk/py2exe-3/py2exe/runtime.py 2014-10-17 09:30:39 UTC (rev 763) +++ trunk/py2exe-3/py2exe/runtime.py 2014-10-17 12:52:49 UTC (rev 764) @@ -407,7 +407,9 @@ arc = zipfile.ZipFile(libpath, "a", compression=compression) - for mod in self.mf.modules.values(): + # The same modules may be in self.ms.modules under different + # keys; we only need one of them in the archive. + for mod in set(self.mf.modules.values()): if mod.__code__: if hasattr(mod, "__path__"): path = mod.__name__.replace(".", "\\") + "\\__init__" + bytecode_suffix This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-10-17 09:30:47
|
Revision: 763 http://sourceforge.net/p/py2exe/svn/763 Author: theller Date: 2014-10-17 09:30:39 +0000 (Fri, 17 Oct 2014) Log Message: ----------- Add hooks for pycparser, OpenSSL, cffi. cffi needs some hacks so that it works from within zipfiles. Modified Paths: -------------- trunk/py2exe-3/ChangeLog trunk/py2exe-3/py2exe/hooks.py Modified: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog 2014-10-17 07:27:39 UTC (rev 762) +++ trunk/py2exe-3/ChangeLog 2014-10-17 09:30:39 UTC (rev 763) @@ -1,5 +1,10 @@ 2014-10-17 <th...@ct...> + * py2exe/hooks.py: Add hooks for pycparser, OpenSSL, cffi. cffi + needs some hacks so that it works from within zipfiles. + +2014-10-17 <th...@ct...> + * py2exe/hooks.py: Remove hook_pyside. 2014-10-16 <th...@ct...> Modified: trunk/py2exe-3/py2exe/hooks.py =================================================================== --- trunk/py2exe-3/py2exe/hooks.py 2014-10-17 07:27:39 UTC (rev 762) +++ trunk/py2exe-3/py2exe/hooks.py 2014-10-17 09:30:39 UTC (rev 763) @@ -56,14 +56,111 @@ finder.ignore("commands") finder.ignore("compiler") finder.ignore("copy_reg") + finder.ignore("dummy_thread") finder.ignore("future_builtins") finder.ignore("htmlentitydefs") finder.ignore("httplib") finder.ignore("md5") finder.ignore("new") + finder.ignore("thread") finder.ignore("unittest2") finder.ignore("urllib2") finder.ignore("urlparse") + +def hook_pycparser(finder, module): + """pycparser needs lextab.py and yacctab.py which are not picked + up automatically. Make sure the complete package is included; + otherwise the exe-files may create yacctab.py and lextab.py when + they are run. + """ + finder.import_package_later("pycparser") + +def hook_pycparser__build_tables(finder, module): + finder.ignore("lextab") + finder.ignore("yacctab") + finder.ignore("_ast_gen") + finder.ignore("c_ast") + +def hook_pycparser_ply(finder, module): + finder.ignore("lex") + finder.ignore("ply") + +def hook_OpenSSL(finder, module): + """OpenSSL needs the cryptography package.""" + finder.import_package_later("cryptography") + +def hook_cffi_cparser(finder, module): + finder.ignore("cffi._pycparser") + +def hook_cffi(finder, module): + # We need to patch two methods in the + # cffi.vengine_cpy.VCPythonEngine class so that cffi libraries + # work from within zip-files. + finder.add_bootcode(""" +def patch_cffi(): + def find_module(self, module_name, path, so_suffixes): + import sys + name = "%s.%s" % (self.verifier.ext_package, module_name) + try: + __import__(name) + except ImportError: + return None + self.__module = mod = sys.modules[name] + return mod.__file__ + + def load_library(self): + from cffi import ffiplatform + import sys + # XXX review all usages of 'self' here! + # import it as a new extension module + module = self.__module + # + # call loading_cpy_struct() to get the struct layout inferred by + # the C compiler + self._load(module, 'loading') + # + # the C code will need the <ctype> objects. Collect them in + # order in a list. + revmapping = dict([(value, key) + for (key, value) in self._typesdict.items()]) + lst = [revmapping[i] for i in range(len(revmapping))] + lst = list(map(self.ffi._get_cached_btype, lst)) + # + # build the FFILibrary class and instance and call _cffi_setup(). + # this will set up some fields like '_cffi_types', and only then + # it will invoke the chained list of functions that will really + # build (notably) the constant objects, as <cdata> if they are + # pointers, and store them as attributes on the 'library' object. + class FFILibrary(object): + _cffi_python_module = module + _cffi_ffi = self.ffi + _cffi_dir = [] + def __dir__(self): + return FFILibrary._cffi_dir + list(self.__dict__) + library = FFILibrary() + if module._cffi_setup(lst, ffiplatform.VerificationError, library): + import warnings + warnings.warn("reimporting %r might overwrite older definitions" + % (self.verifier.get_module_name())) + # + # finally, call the loaded_cpy_xxx() functions. This will perform + # the final adjustments, like copying the Python->C wrapper + # functions from the module to the 'library' object, and setting + # up the FFILibrary class with properties for the global C variables. + self._load(module, 'loaded', library=library) + module._cffi_original_ffi = self.ffi + module._cffi_types_of_builtin_funcs = self._types_of_builtin_functions + return library + + + from cffi.vengine_cpy import VCPythonEngine + + VCPythonEngine.find_module = find_module + VCPythonEngine.load_library = load_library + +patch_cffi() +del patch_cffi +""") def hook_multiprocessing(finder, module): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-10-17 07:27:47
|
Revision: 762 http://sourceforge.net/p/py2exe/svn/762 Author: theller Date: 2014-10-17 07:27:39 +0000 (Fri, 17 Oct 2014) Log Message: ----------- Remove the PySide hook function. Modified Paths: -------------- trunk/py2exe-3/ChangeLog trunk/py2exe-3/py2exe/hooks.py Modified: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog 2014-10-16 17:50:16 UTC (rev 761) +++ trunk/py2exe-3/ChangeLog 2014-10-17 07:27:39 UTC (rev 762) @@ -1,5 +1,14 @@ +2014-10-17 <th...@ct...> + + * py2exe/hooks.py: Remove hook_pyside. + 2014-10-16 <th...@ct...> + * zipextimporter.py (ZipExtensionImporter.load_module): Only catch + ImportError not Exception. + +2014-10-16 <th...@ct...> + * py2exe/boot_service.py: Fix bug in error handling code. cmdline_style = "pywin32" should now work for services. Modified: trunk/py2exe-3/py2exe/hooks.py =================================================================== --- trunk/py2exe-3/py2exe/hooks.py 2014-10-16 17:50:16 UTC (rev 761) +++ trunk/py2exe-3/py2exe/hooks.py 2014-10-17 07:27:39 UTC (rev 762) @@ -164,9 +164,6 @@ finder.add_datadirectory("tcl", tcl_dir, recursive=True) finder.set_min_bundle("tkinter", 2) -def hook_PySide(finder, module): - finder.set_min_bundle("PySide", 3) - def hook_six(finder, module): """six.py is a python2/python3 compatibility library. Exclude the python2 modules. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-10-16 17:50:19
|
Revision: 761 http://sourceforge.net/p/py2exe/svn/761 Author: theller Date: 2014-10-16 17:50:16 +0000 (Thu, 16 Oct 2014) Log Message: ----------- Only catch ImportError; this avoids hiding other exceptions. Modified Paths: -------------- trunk/py2exe-3/zipextimporter.py Modified: trunk/py2exe-3/zipextimporter.py =================================================================== --- trunk/py2exe-3/zipextimporter.py 2014-10-16 17:46:15 UTC (rev 760) +++ trunk/py2exe-3/zipextimporter.py 2014-10-16 17:50:16 UTC (rev 761) @@ -84,7 +84,7 @@ return mod try: return zipimport.zipimporter.load_module(self, fullname) - except Exception: + except ImportError: pass if sys.version_info >= (3, 0): # name of initfunction This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-10-16 17:46:17
|
Revision: 760 http://sourceforge.net/p/py2exe/svn/760 Author: theller Date: 2014-10-16 17:46:15 +0000 (Thu, 16 Oct 2014) Log Message: ----------- Use the cmdline_style attribute of service targets. Modified Paths: -------------- trunk/py2exe-3/py2exe/runtime.py Modified: trunk/py2exe-3/py2exe/runtime.py =================================================================== --- trunk/py2exe-3/py2exe/runtime.py 2014-10-16 17:38:22 UTC (rev 759) +++ trunk/py2exe-3/py2exe/runtime.py 2014-10-16 17:46:15 UTC (rev 760) @@ -569,13 +569,18 @@ optimize=self.options.optimize)) if target.exe_type == "service": + + cmdline_style = getattr(target, "cmdline_style", "py2exe") + if cmdline_style not in ["py2exe", "pywin32", "custom"]: + raise RuntimeError("cmdline_handler invalid") + # code for services # cmdline_style is one of: # py2exe # pywin32 # custom code_objects.append( - compile("cmdline_style = 'py2exe'; service_module_names = %r" % (target.modules,), + compile("cmdline_style = %r; service_module_names = %r" % (cmdline_style, target.modules,), "<service_info>", "exec", optimize=self.options.optimize)) @@ -618,7 +623,7 @@ LOAD_FROM_DIR = r"""\ def __load(): import imp, os - dllpath = os.path.join(os.path.dirname(__loader__.archive), '{0}') + dllpath = os.path.join(os.path.dirname(__loader__.archive), r'{0}') try: mod = imp.load_dynamic(__name__, dllpath) except ImportError as details: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-10-16 17:38:26
|
Revision: 759 http://sourceforge.net/p/py2exe/svn/759 Author: theller Date: 2014-10-16 17:38:22 +0000 (Thu, 16 Oct 2014) Log Message: ----------- Fix bug in the error handling of py2exe.boot_service. Modified Paths: -------------- trunk/py2exe-3/ChangeLog trunk/py2exe-3/py2exe/boot_service.py Modified: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog 2014-10-15 17:41:56 UTC (rev 758) +++ trunk/py2exe-3/ChangeLog 2014-10-16 17:38:22 UTC (rev 759) @@ -1,3 +1,8 @@ +2014-10-16 <th...@ct...> + + * py2exe/boot_service.py: Fix bug in error handling code. + cmdline_style = "pywin32" should now work for services. + 2014-09-24 <th...@ct...> * py2exe/dllfinder.py: Add Scanner.add_bootcode(code) method. The Modified: trunk/py2exe-3/py2exe/boot_service.py =================================================================== --- trunk/py2exe-3/py2exe/boot_service.py 2014-10-15 17:41:56 UTC (rev 758) +++ trunk/py2exe-3/py2exe/boot_service.py 2014-10-16 17:38:22 UTC (rev 759) @@ -179,7 +179,7 @@ try: servicemanager.StartServiceCtrlDispatcher() except win32service.error as details: - if details[0] == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: + if details.winerror == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: win32serviceutil.usage() else: win32serviceutil.HandleCommandLine(k) @@ -192,7 +192,7 @@ try: servicemanager.StartServiceCtrlDispatcher() except win32service.error as details: - if details[0] == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: + if details.winerror == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT: win32serviceutil.usage() else: # assume/insist that the module provides a HandleCommandLine function. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-10-15 17:42:04
|
Revision: 758 http://sourceforge.net/p/py2exe/svn/758 Author: theller Date: 2014-10-15 17:41:56 +0000 (Wed, 15 Oct 2014) Log Message: ----------- set svn:eol-style to native. Modified Paths: -------------- trunk/py2exe-3/zipextimporter.py Property Changed: ---------------- trunk/py2exe-3/zipextimporter.py Modified: trunk/py2exe-3/zipextimporter.py =================================================================== --- trunk/py2exe-3/zipextimporter.py 2014-09-24 17:47:51 UTC (rev 757) +++ trunk/py2exe-3/zipextimporter.py 2014-10-15 17:41:56 UTC (rev 758) @@ -1,128 +1,128 @@ -r"""zipextimporter - an importer which can import extension modules -from zipfiles without unpacking them to the file system. - -This file and _memimporter.pyd is part of the py2exe package. - -Overview -======== - -zipextimporter.py contains the ZipExtImporter class which allows to -load Python binary extension modules contained in a zip.archive, -without unpacking them to the file system. - -Call the zipextimporter.install() function to install the import hook, -add a zip-file containing .pyd or .dll extension modules to sys.path, -and import them. - -It uses the _memimporter extension which uses code from Joachim -Bauch's MemoryModule library. This library emulates the win32 api -function LoadLibrary. - -Sample usage -============ - -You have to prepare a zip-archive 'lib.zip' containing -your Python's _socket.pyd for this example to work. - ->>> import zipextimporter ->>> zipextimporter.install() ->>> import sys ->>> sys.path.insert(0, "lib.zip") ->>> import _socket ->>> print(_socket) -<module '_socket' from 'lib.zip\_socket.pyd'> ->>> _socket.__file__ -'lib.zip\\_socket.pyd' ->>> _socket.__loader__ -<ZipExtensionImporter object 'lib.zip'> ->>> # Reloading also works correctly: ->>> _socket is reload(_socket) -True ->>> - -""" -import imp -import sys -import zipimport - -# _memimporter is a module built into the py2exe runstubs. -import _memimporter - -class ZipExtensionImporter(zipimport.zipimporter): - _suffixes = [s[0] for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION] - - def find_loader(self, fullname): - """We need to override this method for Python 3.x. - """ - loader, portions = super().find_loader(fullname) - if loader is None: - pathname = fullname.replace(".", "\\") - for s in self._suffixes: - if (pathname + s) in self._files: - return self, [] - return None, [] - return loader, portions - - def find_module(self, fullname, path=None): - result = zipimport.zipimporter.find_module(self, fullname, path) - if result: - return result - fullname = fullname.replace(".", "\\") - for s in self._suffixes: - if (fullname + s) in self._files: - return self - return None - - def load_module(self, fullname): - verbose = _memimporter.get_verbose_flag() - if fullname in sys.modules: - mod = sys.modules[fullname] - if verbose: - sys.stderr.write( - "import %s # previously loaded from zipfile %s\n" - % (fullname, self.archive)) - return mod - try: - return zipimport.zipimporter.load_module(self, fullname) - except Exception: - pass - if sys.version_info >= (3, 0): - # name of initfunction - initname = "PyInit_" + fullname.split(".")[-1] - else: - # name of initfunction - initname = "init" + fullname.split(".")[-1] - filename = fullname.replace(".", "\\") - if filename in ("pywintypes", "pythoncom"): - filename = filename + "%d%d" % sys.version_info[:2] - suffixes = ('.dll',) - else: - suffixes = self._suffixes - for s in suffixes: - path = filename + s - if path in self._files: - if verbose > 1: - sys.stderr.write("# found %s in zipfile %s\n" - % (path, self.archive)) - mod = _memimporter.import_module(fullname, path, - initname, - self.get_data) - mod.__file__ = "%s\\%s" % (self.archive, path) - mod.__loader__ = self - if verbose: - sys.stderr.write("import %s # loaded from zipfile %s\n" - % (fullname, mod.__file__)) - return mod - raise zipimport.ZipImportError("can't find module %s" % fullname) - - def __repr__(self): - return "<%s object %r>" % (self.__class__.__name__, self.archive) - -def install(): - "Install the zipextimporter" - sys.path_hooks.insert(0, ZipExtensionImporter) - # Not sure if this is needed... - sys.path_importer_cache.clear() - ## # Not sure if this is needed... - ## import importlib - ## importlib.invalidate_caches() +r"""zipextimporter - an importer which can import extension modules +from zipfiles without unpacking them to the file system. + +This file and _memimporter.pyd is part of the py2exe package. + +Overview +======== + +zipextimporter.py contains the ZipExtImporter class which allows to +load Python binary extension modules contained in a zip.archive, +without unpacking them to the file system. + +Call the zipextimporter.install() function to install the import hook, +add a zip-file containing .pyd or .dll extension modules to sys.path, +and import them. + +It uses the _memimporter extension which uses code from Joachim +Bauch's MemoryModule library. This library emulates the win32 api +function LoadLibrary. + +Sample usage +============ + +You have to prepare a zip-archive 'lib.zip' containing +your Python's _socket.pyd for this example to work. + +>>> import zipextimporter +>>> zipextimporter.install() +>>> import sys +>>> sys.path.insert(0, "lib.zip") +>>> import _socket +>>> print(_socket) +<module '_socket' from 'lib.zip\_socket.pyd'> +>>> _socket.__file__ +'lib.zip\\_socket.pyd' +>>> _socket.__loader__ +<ZipExtensionImporter object 'lib.zip'> +>>> # Reloading also works correctly: +>>> _socket is reload(_socket) +True +>>> + +""" +import imp +import sys +import zipimport + +# _memimporter is a module built into the py2exe runstubs. +import _memimporter + +class ZipExtensionImporter(zipimport.zipimporter): + _suffixes = [s[0] for s in imp.get_suffixes() if s[2] == imp.C_EXTENSION] + + def find_loader(self, fullname): + """We need to override this method for Python 3.x. + """ + loader, portions = super().find_loader(fullname) + if loader is None: + pathname = fullname.replace(".", "\\") + for s in self._suffixes: + if (pathname + s) in self._files: + return self, [] + return None, [] + return loader, portions + + def find_module(self, fullname, path=None): + result = zipimport.zipimporter.find_module(self, fullname, path) + if result: + return result + fullname = fullname.replace(".", "\\") + for s in self._suffixes: + if (fullname + s) in self._files: + return self + return None + + def load_module(self, fullname): + verbose = _memimporter.get_verbose_flag() + if fullname in sys.modules: + mod = sys.modules[fullname] + if verbose: + sys.stderr.write( + "import %s # previously loaded from zipfile %s\n" + % (fullname, self.archive)) + return mod + try: + return zipimport.zipimporter.load_module(self, fullname) + except Exception: + pass + if sys.version_info >= (3, 0): + # name of initfunction + initname = "PyInit_" + fullname.split(".")[-1] + else: + # name of initfunction + initname = "init" + fullname.split(".")[-1] + filename = fullname.replace(".", "\\") + if filename in ("pywintypes", "pythoncom"): + filename = filename + "%d%d" % sys.version_info[:2] + suffixes = ('.dll',) + else: + suffixes = self._suffixes + for s in suffixes: + path = filename + s + if path in self._files: + if verbose > 1: + sys.stderr.write("# found %s in zipfile %s\n" + % (path, self.archive)) + mod = _memimporter.import_module(fullname, path, + initname, + self.get_data) + mod.__file__ = "%s\\%s" % (self.archive, path) + mod.__loader__ = self + if verbose: + sys.stderr.write("import %s # loaded from zipfile %s\n" + % (fullname, mod.__file__)) + return mod + raise zipimport.ZipImportError("can't find module %s" % fullname) + + def __repr__(self): + return "<%s object %r>" % (self.__class__.__name__, self.archive) + +def install(): + "Install the zipextimporter" + sys.path_hooks.insert(0, ZipExtensionImporter) + # Not sure if this is needed... + sys.path_importer_cache.clear() + ## # Not sure if this is needed... + ## import importlib + ## importlib.invalidate_caches() Property changes on: trunk/py2exe-3/zipextimporter.py ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-09-24 17:47:59
|
Revision: 757 http://sourceforge.net/p/py2exe/svn/757 Author: theller Date: 2014-09-24 17:47:51 +0000 (Wed, 24 Sep 2014) Log Message: ----------- py2exe/dllfinder.py: Add Scanner.add_bootcode(code) method. The runtime compiles the code and adds it to the bootstrap code sequences. Modified Paths: -------------- trunk/py2exe-3/ChangeLog trunk/py2exe-3/py2exe/dllfinder.py trunk/py2exe-3/py2exe/mf3.py trunk/py2exe-3/py2exe/runtime.py Modified: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog 2014-09-24 17:33:35 UTC (rev 756) +++ trunk/py2exe-3/ChangeLog 2014-09-24 17:47:51 UTC (rev 757) @@ -1,5 +1,11 @@ 2014-09-24 <th...@ct...> + * py2exe/dllfinder.py: Add Scanner.add_bootcode(code) method. The + runtime compiles the code and adds it to the bootstrap code + sequences. This enables the hooks to do more fancy stuff. + +2014-09-24 <th...@ct...> + * Fix the 'ValueError: __loader__ is None' exception when a PEP 420 implicit namespace package is encountered. Modified: trunk/py2exe-3/py2exe/dllfinder.py =================================================================== --- trunk/py2exe-3/py2exe/dllfinder.py 2014-09-24 17:33:35 UTC (rev 756) +++ trunk/py2exe-3/py2exe/dllfinder.py 2014-09-24 17:47:51 UTC (rev 757) @@ -186,8 +186,13 @@ self._min_bundle = {} self._import_package_later = [] self._safe_import_hook_later = [] + self._boot_code = [] hooks.init_finder(self) + def add_bootcode(self, code): + """Add some code that the exe will execute when bootstrapping.""" + self._boot_code.append(code) + def set_min_bundle(self, name, value): self._min_bundle[name] = value Modified: trunk/py2exe-3/py2exe/mf3.py =================================================================== --- trunk/py2exe-3/py2exe/mf3.py 2014-09-24 17:33:35 UTC (rev 756) +++ trunk/py2exe-3/py2exe/mf3.py 2014-09-24 17:47:51 UTC (rev 757) @@ -306,7 +306,7 @@ except ValueError as details: # Python 3.4 raises this error for namespace packages if str(details) == "{}.__loader__ is None".format(name): - msg = "Error: Namespace packages are not yet supported: Skipping package {!r}" + msg = "Error: Namespace packages not yet supported: Skipping package {!r}" print(msg.format(name)) loader = None else: @@ -314,7 +314,7 @@ except AttributeError as details: # Python 3.3 raises this error for namespace packages if details.args == ("'module' object has no attribute '__loader__'",): - msg = "Error: Namespace packages are not yet supported: Skipping package {!r}" + msg = "Error: Namespace packages not yet supported: Skipping package {!r}" print(msg.format(name)) loader = None else: @@ -345,7 +345,6 @@ return module - def _add_badmodule(self, name): if name not in self.ignores: self.badmodules.add(name) Modified: trunk/py2exe-3/py2exe/runtime.py =================================================================== --- trunk/py2exe-3/py2exe/runtime.py 2014-09-24 17:33:35 UTC (rev 756) +++ trunk/py2exe-3/py2exe/runtime.py 2014-09-24 17:47:51 UTC (rev 757) @@ -562,6 +562,12 @@ optimize=self.options.optimize) code_objects.append(obj) + for text in self.mf._boot_code: + code_objects.append( + compile(text, + "<boot hacks>", "exec", + optimize=self.options.optimize)) + if target.exe_type == "service": # code for services # cmdline_style is one of: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-09-24 17:33:49
|
Revision: 756 http://sourceforge.net/p/py2exe/svn/756 Author: theller Date: 2014-09-24 17:33:35 +0000 (Wed, 24 Sep 2014) Log Message: ----------- Fix the 'ValueError: __loader__ is None' exception when a PEP 420 implicit namespace package is encountered; instead print an error message about unsupported namespace packages. Fixed: When running in a virtual environment, py2exe did not copy the tcl/tk files when 'import tkinter' is detected. Ignore 'numpy.core._dotblas' when numpy.core is imported. Modified Paths: -------------- trunk/py2exe-3/ChangeLog trunk/py2exe-3/TODO.txt trunk/py2exe-3/py2exe/hooks.py trunk/py2exe-3/py2exe/mf3.py trunk/py2exe-3/py2exe/runtime.py Modified: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog 2014-09-23 12:58:15 UTC (rev 755) +++ trunk/py2exe-3/ChangeLog 2014-09-24 17:33:35 UTC (rev 756) @@ -1,3 +1,13 @@ +2014-09-24 <th...@ct...> + + * Fix the 'ValueError: __loader__ is None' exception when a PEP + 420 implicit namespace package is encountered. + + * Fixed: When running in a virtual environment, py2exe did + not copy the tcl/tk files when 'import tkinter' is detected. + + * Ignore 'numpy.core._dotblas' when numpy.core is imported. + 2014-09-18 <th...@ct...> * py2exe/mf3.py (ModuleFinder.import_package): enumerate and Modified: trunk/py2exe-3/TODO.txt =================================================================== --- trunk/py2exe-3/TODO.txt 2014-09-23 12:58:15 UTC (rev 755) +++ trunk/py2exe-3/TODO.txt 2014-09-24 17:33:35 UTC (rev 756) @@ -5,8 +5,9 @@ These occur when ModuleFinder encounters an implicit namespace package. - First step: Catch this case and display a message (which includes - the package name) that namespace packages are not yet supported. + Fixed in rev. 755: + First step: Catch this case and display a message (which includes + the package name) that namespace packages are not yet supported. Second step: Make namespace packages work. Actually they occur in two separate cases - the first one is matplotlib.mpl_toolkit which @@ -32,13 +33,6 @@ - py2exe does not detect imports from six.moves. -- tkinter programs will not build in virtual environments. - - The problem is that the tcl directory in the system installation is - used; there is only a init.tcl file present in the virtual - environment. How can we detect this case and find the correct files - to copy? - - Implement a separate modulefinder for Python 3.4 and above which uses the PEP451 ModuleSpec type and avoids calling deprecated apis. @@ -47,13 +41,17 @@ ================================================================ -Fixed in rev. 751: Enumerate subpackages and import all modules from -the recursively: - - ModuleFinder.import_package() should either work recursively - (have to check what py2exe for Python2 does) or get a receursive - parameter. +Fixed in rev. 755: When running in a virtual environment, py2exe did + not copy the tcl/tk files when 'import tkinter' is detected. +Fixed in rev. 755: When ModuleFinder encounters a PEP 420 implicit + namespace package 'ValueError: __loader__ is None' exception is + no longer raised; instead an error message is printed. + +Fixed in rev. 751: ModuleFinder.import_package enumerates subpackages + and imports modules from them recursively. + ================================================================ Have to check which of the following is still needed: Modified: trunk/py2exe-3/py2exe/hooks.py =================================================================== --- trunk/py2exe-3/py2exe/hooks.py 2014-09-23 12:58:15 UTC (rev 755) +++ trunk/py2exe-3/py2exe/hooks.py 2014-09-24 17:33:35 UTC (rev 756) @@ -158,7 +158,9 @@ """ # It probably doesn't make sense to exclude tix from the tcl distribution, # and only copy it when tkinter.tix is imported... - tcl_dir = os.path.join(sys.prefix, "tcl") + import tkinter._fix as fix + tcl_dir = os.path.normpath(os.path.join(fix.tcldir, "..")) + assert os.path.isdir(tcl_dir) finder.add_datadirectory("tcl", tcl_dir, recursive=True) finder.set_min_bundle("tkinter", 2) @@ -166,7 +168,7 @@ finder.set_min_bundle("PySide", 3) def hook_six(finder, module): - """six.py is a python2/python3 compaibility library. Exclude the + """six.py is a python2/python3 compatibility library. Exclude the python2 modules. """ finder.ignore("StringIO") @@ -180,6 +182,8 @@ "mpl-data") finder.add_datadirectory("mpl-data", mpl_data_path, recursive=True) finder.excludes.append("wx") + # XXX matplotlib requires tkinter which modulefinder does not + # detect because of the six bug. def hook_numpy(finder, module): """numpy for Python 3 still tries to import some Python 2 modules; @@ -345,3 +349,6 @@ module.__globalnames__.add("int32") module.__globalnames__.add("number") module.__globalnames__.add("single") + +def hook_numpy_core(finder, module): + finder.ignore("numpy.core._dotblas") Modified: trunk/py2exe-3/py2exe/mf3.py =================================================================== --- trunk/py2exe-3/py2exe/mf3.py 2014-09-23 12:58:15 UTC (rev 755) +++ trunk/py2exe-3/py2exe/mf3.py 2014-09-24 17:33:35 UTC (rev 756) @@ -301,7 +301,24 @@ msg = ('No module named {!r}; {} is not a package').format(name, parent) self._add_badmodule(name) raise ImportError(msg, name=name) - loader = importlib.find_loader(name, path) + try: + loader = importlib.find_loader(name, path) + except ValueError as details: + # Python 3.4 raises this error for namespace packages + if str(details) == "{}.__loader__ is None".format(name): + msg = "Error: Namespace packages are not yet supported: Skipping package {!r}" + print(msg.format(name)) + loader = None + else: + raise + except AttributeError as details: + # Python 3.3 raises this error for namespace packages + if details.args == ("'module' object has no attribute '__loader__'",): + msg = "Error: Namespace packages are not yet supported: Skipping package {!r}" + print(msg.format(name)) + loader = None + else: + raise if loader is None: self._add_badmodule(name) raise ImportError(name) Modified: trunk/py2exe-3/py2exe/runtime.py =================================================================== --- trunk/py2exe-3/py2exe/runtime.py 2014-09-23 12:58:15 UTC (rev 755) +++ trunk/py2exe-3/py2exe/runtime.py 2014-09-24 17:33:35 UTC (rev 756) @@ -200,8 +200,8 @@ if errors: print("The following modules require a minimum bundle_files option,") - print("otherwise they will not work.") - print("Currently bundle_files is set to %d:\n" % self.options.bundle_files) + print("otherwise they will not work (currently bundle_files is set to %d):" + % self.options.bundle_files) for name, value in errors: print(" %s: %s" % (name, value)) print("\nPlease change the bundle_files option and run the build again.") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-09-23 12:58:27
|
Revision: 755 http://sourceforge.net/p/py2exe/svn/755 Author: theller Date: 2014-09-23 12:58:15 +0000 (Tue, 23 Sep 2014) Log Message: ----------- Add another to-do item, and mark one as done. Modified Paths: -------------- trunk/py2exe-3/TODO.txt Modified: trunk/py2exe-3/TODO.txt =================================================================== --- trunk/py2exe-3/TODO.txt 2014-09-19 19:32:48 UTC (rev 754) +++ trunk/py2exe-3/TODO.txt 2014-09-23 12:58:15 UTC (rev 755) @@ -30,6 +30,8 @@ pyInstaller has a hook that seems to work. Can it be adapted for py2exe, or do we need to patch cffi at runtime? +- py2exe does not detect imports from six.moves. + - tkinter programs will not build in virtual environments. The problem is that the tcl directory in the system installation is @@ -40,14 +42,18 @@ - Implement a separate modulefinder for Python 3.4 and above which uses the PEP451 ModuleSpec type and avoids calling deprecated apis. -- ModuleFinder.import_package() should either work recursively (have - to check what py2exe for Python2 does) or get a receursive - parameter. - - Does probably not work with extensions built against the limited API (python3.dll)??? ================================================================ + +Fixed in rev. 751: Enumerate subpackages and import all modules from +the recursively: + + - ModuleFinder.import_package() should either work recursively + (have to check what py2exe for Python2 does) or get a receursive + parameter. + ================================================================ Have to check which of the following is still needed: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-09-19 19:32:51
|
Revision: 754 http://sourceforge.net/p/py2exe/svn/754 Author: theller Date: 2014-09-19 19:32:48 +0000 (Fri, 19 Sep 2014) Log Message: ----------- Lots added to the TODO-list. Modified Paths: -------------- trunk/py2exe-3/TODO.txt Modified: trunk/py2exe-3/TODO.txt =================================================================== --- trunk/py2exe-3/TODO.txt 2014-09-18 18:18:44 UTC (rev 753) +++ trunk/py2exe-3/TODO.txt 2014-09-19 19:32:48 UTC (rev 754) @@ -1,3 +1,56 @@ +Important Bugs: + +- Fix these 'ValueError: __loader__ is None' errors. + + These occur when ModuleFinder encounters an implicit namespace + package. + + First step: Catch this case and display a message (which includes + the package name) that namespace packages are not yet supported. + + Second step: Make namespace packages work. Actually they occur in + two separate cases - the first one is matplotlib.mpl_toolkit which + is a real namespace package becuase it has no __init__.py file. The + second case is zope.interface or wheezy.template, these packages + have an __init__.py file in the sources, but setuptools installs a + xxx-nspkg.pth file which puts an strange module into sys.modules + even if nothing is imported. + + See also messages to the py2exe mailing list, and + https://www.mail-archive.com/dis...@py.../msg20307.html + as well as + http://sourceforge.net/p/py2exe/bugs/136/ + +- Packages that use cffi do not work. + + Example: cryptography (which is use by OpenSSL). The reason is that + cffi uses imp.find_module() and later imp.load_dynamic() (in + cffi.vengine_ypi.VCPythonEngine). These do only work for files + and not for zipimport. + pyInstaller has a hook that seems to work. Can it be adapted for py2exe, + or do we need to patch cffi at runtime? + +- tkinter programs will not build in virtual environments. + + The problem is that the tcl directory in the system installation is + used; there is only a init.tcl file present in the virtual + environment. How can we detect this case and find the correct files + to copy? + +- Implement a separate modulefinder for Python 3.4 and above which + uses the PEP451 ModuleSpec type and avoids calling deprecated apis. + +- ModuleFinder.import_package() should either work recursively (have + to check what py2exe for Python2 does) or get a receursive + parameter. + +- Does probably not work with extensions built against the limited API + (python3.dll)??? + +================================================================ +================================================================ +Have to check which of the following is still needed: + Bugs: - debug the 'verbose' argument to py2exe. It defaults to 1, using @@ -13,9 +66,6 @@ - distutils_buildexe needs to import DistutilsOptionError (or so) -- Does probably not work with extensions built against the limited API - (python3.dll)??? - - py2exe for Python2 used an 'uac_info' string (exec_level) or tuple (exec_level, ui_access) attribute on the Target to include or patch a default manifest. @@ -32,13 +82,19 @@ - dump_manifest.py - dump_versioninfo.py - or even a general resource dumper? +- or even a py2exe dumper? TODO: - services cmdline_style not yet implemented +================================================================ + Fixed bugs: + (The version numbers up tp 380 are probably from the former repository at + https://ctypes-stuff.googlecode.com/svn/trunk/mf) + rev 380: - ctypes DLL COM servers can now load dlls (like sqlite3.dll) correctly. rev 343: - DLL com servers are now implemented rev 336: - py2exe\dll.dll is not installed. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-09-18 18:18:52
|
Revision: 753 http://sourceforge.net/p/py2exe/svn/753 Author: theller Date: 2014-09-18 18:18:44 +0000 (Thu, 18 Sep 2014) Log Message: ----------- Revert accidential commit Modified Paths: -------------- trunk/py2exe-3/py2exe/dllfinder.py trunk/py2exe-3/py2exe/mf34.py Modified: trunk/py2exe-3/py2exe/dllfinder.py =================================================================== --- trunk/py2exe-3/py2exe/dllfinder.py 2014-09-18 18:14:22 UTC (rev 752) +++ trunk/py2exe-3/py2exe/dllfinder.py 2014-09-18 18:18:44 UTC (rev 753) @@ -8,10 +8,7 @@ import os import sys -if sys.version_info >= (3, 4): - from . mf34 import ModuleFinder -else: - from . mf3 import ModuleFinder +from . mf3 import ModuleFinder from . import hooks ################################ Modified: trunk/py2exe-3/py2exe/mf34.py =================================================================== --- trunk/py2exe-3/py2exe/mf34.py 2014-09-18 18:14:22 UTC (rev 752) +++ trunk/py2exe-3/py2exe/mf34.py 2014-09-18 18:18:44 UTC (rev 753) @@ -1,4 +1,4 @@ -#!/usr/bin/python3.4 +#!/usr/bin/python3.3 # -*- coding: utf-8 -*- """ModuleFinder based on importlib """ @@ -14,7 +14,6 @@ import struct import sys import textwrap -import warnings # XXX Clean up once str8's cstor matches bytes. LOAD_CONST = bytes([dis.opname.index('LOAD_CONST')]) @@ -24,7 +23,31 @@ STORE_OPS = [STORE_NAME, STORE_GLOBAL] HAVE_ARGUMENT = bytes([dis.HAVE_ARGUMENT]) +# Monkeypatch some missing methods in Python 3.3's NamespaceLoader +def __patch_py33(): + if sys.version_info < (3, 4): + def is_package(self, fullname): + return True + def get_source(self, fullname): + return '' + + def get_code(self, fullname): + return compile('', '<string>', 'exec', dont_inherit=True) + + def init_module_attrs(self, module): + module.__loader__ = self + module.__package__ = module.__name__ + from importlib._bootstrap import NamespaceLoader + NamespaceLoader.is_package = is_package + NamespaceLoader.get_source = get_source + NamespaceLoader.get_code = get_code + NamespaceLoader.init_module_attrs = init_module_attrs + +__patch_py33() +del __patch_py33 + + class ModuleFinder: def __init__(self, path=None, verbose=0, excludes=None, optimize=0, ignores=None): @@ -56,11 +79,7 @@ """ assert "__SCRIPT__" not in sys.modules ldr = importlib.machinery.SourceFileLoader("__SCRIPT__", path) - if sys.version_info >= (3, 4): - spec = importlib.machinery.ModuleSpec("__SCRIPT__", ldr) - mod = Module(spec, "__SCRIPT__", self._optimize) - else: - mod = Module(ldr, "__SCRIPT__", self._optimize) + mod = Module(ldr, "__SCRIPT__", self._optimize) # Do NOT add it... # self._add_module("__SCRIPT__", mod) self._scan_code(mod.__code__, mod) @@ -76,8 +95,6 @@ raise TypeError("{0} is not a package".format(name)) for finder, modname, ispkg in pkgutil.iter_modules(package.__path__): self.safe_import_hook("%s.%s" % (name, modname)) - if ispkg: - self.import_package("%s.%s" % (name, modname)) def import_hook(self, name, caller=None, fromlist=(), level=0): @@ -281,27 +298,14 @@ msg = ('No module named {!r}; {} is not a package').format(name, parent) self._add_badmodule(name) raise ImportError(msg, name=name) - try: - spec = importlib.util.find_spec(name, path) - except ValueError as details: - # workaround for the .pth file for namespace packages that - # setuptools installs. The pth file inserts a 'damaged' - # module into sys.modules: it has no __spec__. Reloading - # the module helps (at least in Python3.4). - if details.args[0] == '{}.__spec__ is None'.format(name): - import imp - _ = __import__(name, path) - imp.reload(_) - spec = importlib.util.find_spec(name, path) - else: - raise - if spec is None: + loader = importlib.find_loader(name, path) + if loader is None: self._add_badmodule(name) raise ImportError(name) elif name not in self.modules: # The parent import may have already imported this module. try: - self._load_module(spec, name) + self._load_module(loader, name) except ImportError: self._add_badmodule(name) raise @@ -331,8 +335,8 @@ self.modules[name] = mod - def _load_module(self, spec, name): - mod = Module(spec, name, self._optimize) + def _load_module(self, loader, name): + mod = Module(loader, name, self._optimize) self._add_module(name, mod) if name in self._package_paths: mod.__path__.extend(self._package_paths[name]) @@ -477,10 +481,8 @@ print("P", end=" ") else: print("m", end=" ") - if m.__spec__.has_location and hasattr(m, "__file__"): - print("%-35s" % name, getattr(m, "__file__")) - else: - print("%-35s" % name, "(%s)" % m.__spec__.origin) + print("%-35s" % name, getattr(m, "__file__", + "(built-in, frozen, or namespace)")) deps = sorted(self._depgraph[name]) text = "\n".join(textwrap.wrap(", ".join(deps))) print(" imported from:\n%s" % textwrap.indent(text, " ")) @@ -547,16 +549,14 @@ extension modules) """ - def __init__(self, spec, name, optimize): + def __init__(self, loader, name, optimize): self.__optimize__ = optimize self.__globalnames__ = set() self.__name__ = name - self.__spec__ = spec + self.__loader__ = loader self.__code_object__ = None - loader = self.__loader__ = spec.loader - if hasattr(loader, "get_filename"): # python modules fnm = loader.get_filename(name) @@ -569,9 +569,6 @@ self.__file__ = fnm if loader.is_package(name): self.__path__ = [os.path.dirname(fnm)] - elif spec.origin == "namespace": - # namespace modules have no loader - self.__path__ = spec.submodule_search_locations else: # frozen or builtin modules if loader.is_package(name): @@ -588,12 +585,13 @@ @property def __code__(self): - if self.__code_object__ is None and self.__loader__ is not None: + if self.__code_object__ is None: if self.__optimize__ == sys.flags.optimize: self.__code_object__ = self.__loader__.get_code(self.__name__) else: source = self.__source__ if source is not None: + # XXX??? for py3exe: __file__ = self.__file__ \ if hasattr(self, "__file__") else "<string>" try: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-09-18 18:14:25
|
Revision: 752 http://sourceforge.net/p/py2exe/svn/752 Author: theller Date: 2014-09-18 18:14:22 +0000 (Thu, 18 Sep 2014) Log Message: ----------- ## Lines starting with '## ' will be removed from the log message. ## File(s) to commit: ## ChangeLog ## py2exe/mf3.py Enumerate subpackages and import all modules from the recursively. Modified Paths: -------------- trunk/py2exe-3/py2exe/dllfinder.py trunk/py2exe-3/py2exe/mf34.py Modified: trunk/py2exe-3/py2exe/dllfinder.py =================================================================== --- trunk/py2exe-3/py2exe/dllfinder.py 2014-09-18 18:13:48 UTC (rev 751) +++ trunk/py2exe-3/py2exe/dllfinder.py 2014-09-18 18:14:22 UTC (rev 752) @@ -8,7 +8,10 @@ import os import sys -from . mf3 import ModuleFinder +if sys.version_info >= (3, 4): + from . mf34 import ModuleFinder +else: + from . mf3 import ModuleFinder from . import hooks ################################ Modified: trunk/py2exe-3/py2exe/mf34.py =================================================================== --- trunk/py2exe-3/py2exe/mf34.py 2014-09-18 18:13:48 UTC (rev 751) +++ trunk/py2exe-3/py2exe/mf34.py 2014-09-18 18:14:22 UTC (rev 752) @@ -1,4 +1,4 @@ -#!/usr/bin/python3.3 +#!/usr/bin/python3.4 # -*- coding: utf-8 -*- """ModuleFinder based on importlib """ @@ -14,6 +14,7 @@ import struct import sys import textwrap +import warnings # XXX Clean up once str8's cstor matches bytes. LOAD_CONST = bytes([dis.opname.index('LOAD_CONST')]) @@ -23,31 +24,7 @@ STORE_OPS = [STORE_NAME, STORE_GLOBAL] HAVE_ARGUMENT = bytes([dis.HAVE_ARGUMENT]) -# Monkeypatch some missing methods in Python 3.3's NamespaceLoader -def __patch_py33(): - if sys.version_info < (3, 4): - def is_package(self, fullname): - return True - def get_source(self, fullname): - return '' - - def get_code(self, fullname): - return compile('', '<string>', 'exec', dont_inherit=True) - - def init_module_attrs(self, module): - module.__loader__ = self - module.__package__ = module.__name__ - from importlib._bootstrap import NamespaceLoader - NamespaceLoader.is_package = is_package - NamespaceLoader.get_source = get_source - NamespaceLoader.get_code = get_code - NamespaceLoader.init_module_attrs = init_module_attrs - -__patch_py33() -del __patch_py33 - - class ModuleFinder: def __init__(self, path=None, verbose=0, excludes=None, optimize=0, ignores=None): @@ -79,7 +56,11 @@ """ assert "__SCRIPT__" not in sys.modules ldr = importlib.machinery.SourceFileLoader("__SCRIPT__", path) - mod = Module(ldr, "__SCRIPT__", self._optimize) + if sys.version_info >= (3, 4): + spec = importlib.machinery.ModuleSpec("__SCRIPT__", ldr) + mod = Module(spec, "__SCRIPT__", self._optimize) + else: + mod = Module(ldr, "__SCRIPT__", self._optimize) # Do NOT add it... # self._add_module("__SCRIPT__", mod) self._scan_code(mod.__code__, mod) @@ -95,6 +76,8 @@ raise TypeError("{0} is not a package".format(name)) for finder, modname, ispkg in pkgutil.iter_modules(package.__path__): self.safe_import_hook("%s.%s" % (name, modname)) + if ispkg: + self.import_package("%s.%s" % (name, modname)) def import_hook(self, name, caller=None, fromlist=(), level=0): @@ -298,14 +281,27 @@ msg = ('No module named {!r}; {} is not a package').format(name, parent) self._add_badmodule(name) raise ImportError(msg, name=name) - loader = importlib.find_loader(name, path) - if loader is None: + try: + spec = importlib.util.find_spec(name, path) + except ValueError as details: + # workaround for the .pth file for namespace packages that + # setuptools installs. The pth file inserts a 'damaged' + # module into sys.modules: it has no __spec__. Reloading + # the module helps (at least in Python3.4). + if details.args[0] == '{}.__spec__ is None'.format(name): + import imp + _ = __import__(name, path) + imp.reload(_) + spec = importlib.util.find_spec(name, path) + else: + raise + if spec is None: self._add_badmodule(name) raise ImportError(name) elif name not in self.modules: # The parent import may have already imported this module. try: - self._load_module(loader, name) + self._load_module(spec, name) except ImportError: self._add_badmodule(name) raise @@ -335,8 +331,8 @@ self.modules[name] = mod - def _load_module(self, loader, name): - mod = Module(loader, name, self._optimize) + def _load_module(self, spec, name): + mod = Module(spec, name, self._optimize) self._add_module(name, mod) if name in self._package_paths: mod.__path__.extend(self._package_paths[name]) @@ -481,8 +477,10 @@ print("P", end=" ") else: print("m", end=" ") - print("%-35s" % name, getattr(m, "__file__", - "(built-in, frozen, or namespace)")) + if m.__spec__.has_location and hasattr(m, "__file__"): + print("%-35s" % name, getattr(m, "__file__")) + else: + print("%-35s" % name, "(%s)" % m.__spec__.origin) deps = sorted(self._depgraph[name]) text = "\n".join(textwrap.wrap(", ".join(deps))) print(" imported from:\n%s" % textwrap.indent(text, " ")) @@ -549,14 +547,16 @@ extension modules) """ - def __init__(self, loader, name, optimize): + def __init__(self, spec, name, optimize): self.__optimize__ = optimize self.__globalnames__ = set() self.__name__ = name - self.__loader__ = loader + self.__spec__ = spec self.__code_object__ = None + loader = self.__loader__ = spec.loader + if hasattr(loader, "get_filename"): # python modules fnm = loader.get_filename(name) @@ -569,6 +569,9 @@ self.__file__ = fnm if loader.is_package(name): self.__path__ = [os.path.dirname(fnm)] + elif spec.origin == "namespace": + # namespace modules have no loader + self.__path__ = spec.submodule_search_locations else: # frozen or builtin modules if loader.is_package(name): @@ -585,13 +588,12 @@ @property def __code__(self): - if self.__code_object__ is None: + if self.__code_object__ is None and self.__loader__ is not None: if self.__optimize__ == sys.flags.optimize: self.__code_object__ = self.__loader__.get_code(self.__name__) else: source = self.__source__ if source is not None: - # XXX??? for py3exe: __file__ = self.__file__ \ if hasattr(self, "__file__") else "<string>" try: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-09-18 18:13:57
|
Revision: 751 http://sourceforge.net/p/py2exe/svn/751 Author: theller Date: 2014-09-18 18:13:48 +0000 (Thu, 18 Sep 2014) Log Message: ----------- Enumerate subpackages and import all modules from the recursively. Modified Paths: -------------- trunk/py2exe-3/ChangeLog trunk/py2exe-3/py2exe/mf3.py Modified: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog 2014-09-12 17:28:30 UTC (rev 750) +++ trunk/py2exe-3/ChangeLog 2014-09-18 18:13:48 UTC (rev 751) @@ -1,18 +1,23 @@ -2014-09-11 <th...@ct...> - - * py2exe/runtime.py Print a meaningful error message when the - build fails because bundle_files is too low for certain packages. - -2014-05-26 <th...@ct...> - - * py2exe/runtime.py (Runtime.bootstrap_modules): Add ctypes to the - modules needed for bootstrap; it is used by boot_common. - -2014-05-12 <th...@ct...> - - * Add missing DeactivateActCtx() call. Change version number to - 0.9.2.1. - -2014-05-09 <th...@ct...> - - * Releasing py2exe for Python 3, version 0.9.2.0. +2014-09-18 <th...@ct...> + + * py2exe/mf3.py (ModuleFinder.import_package): enumerate and + import modules from all subpackages. + +2014-09-11 <th...@ct...> + + * py2exe/runtime.py Print a meaningful error message when the + build fails because bundle_files is too low for certain packages. + +2014-05-26 <th...@ct...> + + * py2exe/runtime.py (Runtime.bootstrap_modules): Add ctypes to the + modules needed for bootstrap; it is used by boot_common. + +2014-05-12 <th...@ct...> + + * Add missing DeactivateActCtx() call. Change version number to + 0.9.2.1. + +2014-05-09 <th...@ct...> + + * Releasing py2exe for Python 3, version 0.9.2.0. Modified: trunk/py2exe-3/py2exe/mf3.py =================================================================== --- trunk/py2exe-3/py2exe/mf3.py 2014-09-12 17:28:30 UTC (rev 750) +++ trunk/py2exe-3/py2exe/mf3.py 2014-09-18 18:13:48 UTC (rev 751) @@ -14,6 +14,7 @@ import struct import sys import textwrap +import warnings # XXX Clean up once str8's cstor matches bytes. LOAD_CONST = bytes([dis.opname.index('LOAD_CONST')]) @@ -95,6 +96,8 @@ raise TypeError("{0} is not a package".format(name)) for finder, modname, ispkg in pkgutil.iter_modules(package.__path__): self.safe_import_hook("%s.%s" % (name, modname)) + if ispkg: + self.import_package("%s.%s" % (name, modname)) def import_hook(self, name, caller=None, fromlist=(), level=0): @@ -597,7 +600,7 @@ try: self.__code_object__ = compile(source, __file__, "exec", optimize=self.__optimize__) - except Exception as details: + except Exception: import traceback; traceback.print_exc() raise RuntimeError("compiling %r" % self) from None elif hasattr(self, "__file__") and not self.__file__.endswith(".pyd"): This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-09-12 17:28:32
|
Revision: 750 http://sourceforge.net/p/py2exe/svn/750 Author: theller Date: 2014-09-12 17:28:30 +0000 (Fri, 12 Sep 2014) Log Message: ----------- Copy mf3.py to mf34.py - will become a modulefinder for Python 3.4 and up, using changes for PEP451: "A ModuleSpec Type for the Import System". Hopefully it will be able then to use namespace packages. Added Paths: ----------- trunk/py2exe-3/py2exe/mf34.py Copied: trunk/py2exe-3/py2exe/mf34.py (from rev 746, trunk/py2exe-3/py2exe/mf3.py) =================================================================== --- trunk/py2exe-3/py2exe/mf34.py (rev 0) +++ trunk/py2exe-3/py2exe/mf34.py 2014-09-12 17:28:30 UTC (rev 750) @@ -0,0 +1,760 @@ +#!/usr/bin/python3.3 +# -*- coding: utf-8 -*- +"""ModuleFinder based on importlib +""" + +# XXX XXX XXX Does not yet support PEP 452 namespace packages! + +from collections import defaultdict +import dis +import importlib +import importlib.machinery +import os +import pkgutil +import struct +import sys +import textwrap + +# XXX Clean up once str8's cstor matches bytes. +LOAD_CONST = bytes([dis.opname.index('LOAD_CONST')]) +IMPORT_NAME = bytes([dis.opname.index('IMPORT_NAME')]) +STORE_NAME = bytes([dis.opname.index('STORE_NAME')]) +STORE_GLOBAL = bytes([dis.opname.index('STORE_GLOBAL')]) +STORE_OPS = [STORE_NAME, STORE_GLOBAL] +HAVE_ARGUMENT = bytes([dis.HAVE_ARGUMENT]) + +# Monkeypatch some missing methods in Python 3.3's NamespaceLoader +def __patch_py33(): + if sys.version_info < (3, 4): + def is_package(self, fullname): + return True + + def get_source(self, fullname): + return '' + + def get_code(self, fullname): + return compile('', '<string>', 'exec', dont_inherit=True) + + def init_module_attrs(self, module): + module.__loader__ = self + module.__package__ = module.__name__ + from importlib._bootstrap import NamespaceLoader + NamespaceLoader.is_package = is_package + NamespaceLoader.get_source = get_source + NamespaceLoader.get_code = get_code + NamespaceLoader.init_module_attrs = init_module_attrs + +__patch_py33() +del __patch_py33 + + +class ModuleFinder: + def __init__(self, path=None, verbose=0, excludes=None, optimize=0, + ignores=None): + self.excludes = list(excludes) if excludes is not None else [] + self.ignores = ignores if ignores is not None else [] + self.path = path + self._optimize = optimize + self._verbose = verbose + self.modules = {} + self.badmodules = set() + self.__last_caller = None + self._depgraph = defaultdict(set) + self._indent = "" + self._package_paths = defaultdict(list) + + + def add_packagepath(self, packagename, path): + """ModuleFinder can not handle __path__ modifications packages + make at runtime. + + This method registers extra paths for a package. + """ + self._package_paths[packagename].append(path) + + + def run_script(self, path): + """Run a script: scan it for dependencies, but do NOT + add it the self.modules. + """ + assert "__SCRIPT__" not in sys.modules + ldr = importlib.machinery.SourceFileLoader("__SCRIPT__", path) + mod = Module(ldr, "__SCRIPT__", self._optimize) + # Do NOT add it... + # self._add_module("__SCRIPT__", mod) + self._scan_code(mod.__code__, mod) + + def import_package(self, name): + """Import a complete package. + + """ + self.import_hook(name) + package = self.modules[name] + if not hasattr(package, "__path__"): + # Hm, should we raise ImportError instead? + raise TypeError("{0} is not a package".format(name)) + for finder, modname, ispkg in pkgutil.iter_modules(package.__path__): + self.safe_import_hook("%s.%s" % (name, modname)) + + + def import_hook(self, name, caller=None, fromlist=(), level=0): + """Import a module. + + The 'caller' argument is used to infer where the import is + occuring from to handle relative imports. The 'fromlist' + argument specifies what should exist as attributes on the + module being imported (e.g. ``from module import + <fromlist>``). The 'level' argument represents the package + location to import from in a relative import (e.g. ``from + ..pkg import mod`` would have a 'level' of 2). + + """ + self.__old_last_caller = self.__last_caller + self.__last_caller = caller + + try: + if level == 0: + module = self._gcd_import(name) + else: + package = self._calc___package__(caller) + module = self._gcd_import(name, package, level) + if fromlist: + self._handle_fromlist(module, fromlist, caller) + finally: + self.__last_caller = self.__old_last_caller + + + def safe_import_hook(self, name, caller=None, fromlist=(), level=0): + """Wrapper for import_hook() that catches ImportError. + + """ + INDENT = " " + self._info(name, caller, fromlist, level) + self._indent = self._indent + INDENT + try: + self.import_hook(name, caller, fromlist, level) + except ImportError: + if self._verbose > 1: + print("%s# -> ImportError" % self._indent[:-len(INDENT)]) + finally: + self._indent = self._indent[:-len(INDENT)] + + + def _info(self, name, caller, fromlist, level): + """Print the call as a Python import statement, indented. + + """ + if self._verbose == 0: + return + if caller: + caller_info = " # in %s" % caller.__name__ + else: + caller_info = "" + + if level == 0: + if fromlist: + text = "%sfrom %s import %s" % (self._indent, name, + ", ".join(fromlist)) + caller_info + else: + text = "%simport %s" % (self._indent, name) + caller_info + elif name: + text = "%sfrom %s import %s" % (self._indent, "."*level + name, + ", ".join(fromlist)) + caller_info + else: + text = "%sfrom %s import %s" % (self._indent, "."*level, + ", ".join(fromlist)) + caller_info + print(text) + + + def _handle_fromlist(self, mod, fromlist, caller): + """handle the fromlist. + + Names on the fromlist can be modules or global symbols. + """ + for x in fromlist: + if x == "*": + if caller is not None: + if mod.__code__ is None: + # 'from <mod> import *' We have no information + # about the symbols that are imported from + # extension, builtin, or frozen modules. Put a '*' + # symbol into __globalnames__ so that we can later + # use it in report_missing(). + caller.__globalnames__.add("*") + for n in mod.__globalnames__: + caller.__globalnames__.add(n) + continue + if hasattr(mod, x): + continue # subpackage already loaded + if x in mod.__globalnames__: + continue + if hasattr(mod, "__path__"): + try: + self._gcd_import('{}.{}'.format(mod.__name__, x)) + except ImportError: + # self._gcd_import has put an entry into self.badmodules, + # so continue processing + pass + ## else: + ## self._add_badmodule('{}.{}'.format(mod.__name__, x)) + + + def _resolve_name(self, name, package, level): + """Resolve a relative module name to an absolute one.""" + assert level > 0 + # This method must only be called for relative imports. + # Probably it could return <name> when level == 0; + # and we can save the 'if level > 0:' test in the calling code. + bits = package.rsplit('.', level - 1) + if len(bits) < level: + raise ValueError('attempted relative import beyond top-level package') + base = bits[0] + return '{}.{}'.format(base, name) if name else base + + + def _sanity_check(self, name, package, level): + """Verify arguments are 'sane'.""" + if not isinstance(name, str): + raise TypeError("module name must be str, not {}".format(type(name))) + if level < 0: + raise ValueError('level must be >= 0') + if package: + if not isinstance(package, str): + raise TypeError("__package__ not set to a string") + elif package not in self.modules: + msg = ("Parent module {!r} not loaded, cannot perform relative " + "import") + raise SystemError(msg.format(package)) + if not name and level == 0: + raise ValueError("Empty module name") + + + def _calc___package__(self, caller): + """Calculate what __package__ should be. + + __package__ is not guaranteed to be defined or could be set to None + to represent that its proper value is unknown. + + """ + package = caller.__package__ + if package is None: + package = caller.__name__ + if not hasattr(caller, "__path__"): + package = package.rpartition('.')[0] + return package + + + def _gcd_import(self, name, package=None, level=0): + """Import and return the module based on its name, the package + the call is being made from, and the level adjustment. + + """ + # __main__ is always the current main module; do never import that. + if name == "__main__": + raise ImportError() + + self._sanity_check(name, package, level) + if level > 0: + name = self._resolve_name(name, package, level) + # 'name' is now the fully qualified, absolute name of the + # module we want to import. + + caller = self.__last_caller.__name__ if self.__last_caller else "-" + + self._depgraph[name].add(caller) + + if name in self.excludes: + raise ImportError('No module named {!r}'.format(name), name=name) + + if name in self.modules: + return self.modules[name] + return self._find_and_load(name) + + + def _find_and_load(self, name): + """Find and load the module. + + Inserts the module into self.modules and returns it. + If the module is not found or could not be imported, + it is inserted in self.badmodules. + """ + path = self.path + parent = name.rpartition('.')[0] + if parent: + if parent not in self.modules: + self._gcd_import(parent) + # Crazy side-effects! + if name in self.modules: + return self.modules[name] + # Backwards-compatibility; be nicer to skip the dict lookup. + parent_module = self.modules[parent] + try: + path = parent_module.__path__ + except AttributeError: + # this fixes 'import os.path'. Does it create other problems? + child = name.rpartition('.')[2] + if child in parent_module.__globalnames__: + return parent_module + msg = ('No module named {!r}; {} is not a package').format(name, parent) + self._add_badmodule(name) + raise ImportError(msg, name=name) + loader = importlib.find_loader(name, path) + if loader is None: + self._add_badmodule(name) + raise ImportError(name) + elif name not in self.modules: + # The parent import may have already imported this module. + try: + self._load_module(loader, name) + except ImportError: + self._add_badmodule(name) + raise + + # Backwards-compatibility; be nicer to skip the dict lookup. + module = self.modules[name] + + if parent: + # Set the module as an attribute on its parent. + parent_module = self.modules[parent] + setattr(parent_module, name.rpartition('.')[2], module) + + # It is important that all the required __...__ attributes at + # the module are set before the code is scanned. + if module.__code__: + self._scan_code(module.__code__, module) + + return module + + + def _add_badmodule(self, name): + if name not in self.ignores: + self.badmodules.add(name) + + + def _add_module(self, name, mod): + self.modules[name] = mod + + + def _load_module(self, loader, name): + mod = Module(loader, name, self._optimize) + self._add_module(name, mod) + if name in self._package_paths: + mod.__path__.extend(self._package_paths[name]) + + + def _scan_code(self, code, mod): + """ + Scan the module bytecode. + + When we encounter in import statement, we simulate the import + by calling safe_import_hook() to find the imported modules. + + We also take note of 'static' global symbols in the module and + add them to __globalnames__. + """ + + for what, args in self._scan_opcodes(code): + if what == "store": + name, = args + mod.__globalnames__.add(name) + elif what == "import": + level, fromlist, name = args + self.safe_import_hook(name, mod, fromlist, level) + else: + # We don't expect anything else from the generator. + raise RuntimeError(what) + + for c in code.co_consts: + if isinstance(c, type(code)): + self._scan_code(c, mod) + + + def _scan_opcodes(self, co, unpack=struct.unpack): + """ + Scan the code object, and yield 'interesting' opcode combinations + + """ + code = co.co_code + names = co.co_names + consts = co.co_consts + LOAD_LOAD_AND_IMPORT = LOAD_CONST + LOAD_CONST + IMPORT_NAME + while code: + c = bytes([code[0]]) + if c in STORE_OPS: + oparg, = unpack('<H', code[1:3]) + yield "store", (names[oparg],) + code = code[3:] + continue + if code[:9:3] == LOAD_LOAD_AND_IMPORT: + oparg_1, oparg_2, oparg_3 = unpack('<xHxHxH', code[:9]) + yield "import", (consts[oparg_1], consts[oparg_2], names[oparg_3]) + code = code[9:] + continue + if c >= HAVE_ARGUMENT: + code = code[3:] + else: + code = code[1:] + + def ignore(self, name): + """If the module or package with the given name is not found, + don't record this as an error. If is is found, however, + include it. + """ + self.ignores.append(name) + + def missing(self): + """Return a set of modules that appear to be missing. Use + any_missing_maybe() if you want to know which modules are + certain to be missing, and which *may* be missing. + + """ + missing = set() + for name in self.badmodules: + package, _, symbol = name.rpartition(".") + if not package: + missing.add(name) + continue + elif package in missing: + continue + if symbol not in self.modules[package].__globalnames__: + missing.add(name) + return missing + + def missing_maybe(self): + """Return two sets, one with modules that are certainly + missing and one with modules that *may* be missing. The latter + names could either be submodules *or* just global names in the + package. + + The reason it can't always be determined is that it's impossible to + tell which names are imported when "from module import *" is done + with an extension module, short of actually importing it. + """ + missing = set() + maybe = set() + for name in self.badmodules: + package, _, symbol = name.rpartition(".") + if not package: + missing.add(name) + continue + elif package in missing: + continue + if symbol not in self.modules[package].__globalnames__: + if "*" in self.modules[package].__globalnames__: + maybe.add(name) + else: + missing.add(name) + return missing, maybe + + + def report_summary(self): + """Print the count of found and missing modules. + + """ + missing, maybe = self.missing_maybe() + print("Found %d modules, %d are missing, %d could be missing" + % (len(self.modules), len(missing), len(maybe))) + + def report(self): + """Print a report to stdout, listing the found modules with + their paths, as well as modules that are missing, or seem to + be missing. """ + + self.report_modules() + self.report_missing() + + + def report_modules(self): + """Print a report about found modules to stdout, with their + found paths. + """ + print() + print(" %-35s %s" % ("Name", "File")) + print(" %-35s %s" % ("----", "----")) + # Print modules found + for name in sorted(self.modules): + m = self.modules[name] + if m is None: + ## print("?", end=" ") + continue + elif getattr(m, "__path__", None): + print("P", end=" ") + else: + print("m", end=" ") + print("%-35s" % name, getattr(m, "__file__", + "(built-in, frozen, or namespace)")) + deps = sorted(self._depgraph[name]) + text = "\n".join(textwrap.wrap(", ".join(deps))) + print(" imported from:\n%s" % textwrap.indent(text, " ")) + + + def report_missing(self): + """Print a report to stdout, listing those modules that are + missing. + + """ + missing, maybe = self.missing_maybe() + print() + print(" %-35s" % ("%d missing Modules" % len(missing))) + print(" %-35s" % "------------------") + for name in sorted(missing): + deps = sorted(self._depgraph[name]) + print("? %-35s imported from %s" % (name, ", ".join(deps))) + + # Print modules that may be missing, but then again, maybe not... + if maybe: + print() + print(" %-35s" % + ("%d submodules that appear to be missing, but" + " could also be global names" + " in the parent package" % len(maybe))) + print(" %-35s" % + "-----------------------------------------" + "----------------------------------------------------") + for name in sorted(maybe): + deps = sorted(self._depgraph[name]) + print("? %-35s imported from %s" % (name, ", ".join(deps))) + + +################################################################ + + +class Module: + """Represents a Python module. + + These attributes are set, depending on the loader: + + __code__: the code object provided by the loader; can be None. + + __file__: The path to where the module data is stored (not set for + built-in or frozen modules). + + __globalnames__: a set containing the global names that are defined. + + __loader__: The loader for this module. + + __name__: The name of the module. + + __optimize__: Optimization level for the module's byte-code. + + __package__: The parent package for the module/package. If the + module is top-level then it has a value of the empty + string. + + __path__: A list of strings specifying the search path within a + package. This attribute is not set on modules. + + __source__: a property that gives access to the source code (if + the __loader__ provides it, not for builtin or + extension modules) + """ + + def __init__(self, loader, name, optimize): + self.__optimize__ = optimize + self.__globalnames__ = set() + + self.__name__ = name + self.__loader__ = loader + self.__code_object__ = None + + if hasattr(loader, "get_filename"): + # python modules + fnm = loader.get_filename(name) + self.__file__ = fnm + if loader.is_package(name): + self.__path__ = [os.path.dirname(fnm)] + elif hasattr(loader, "path"): + # extension modules + fnm = loader.path + self.__file__ = fnm + if loader.is_package(name): + self.__path__ = [os.path.dirname(fnm)] + else: + # frozen or builtin modules + if loader.is_package(name): + self.__path__ = [name] + + if getattr(self, '__package__', None) is None: + try: + self.__package__ = self.__name__ + if not hasattr(self, '__path__'): + self.__package__ = self.__package__.rpartition('.')[0] + except AttributeError: + pass + + + @property + def __code__(self): + if self.__code_object__ is None: + if self.__optimize__ == sys.flags.optimize: + self.__code_object__ = self.__loader__.get_code(self.__name__) + else: + source = self.__source__ + if source is not None: + # XXX??? for py3exe: + __file__ = self.__file__ \ + if hasattr(self, "__file__") else "<string>" + try: + self.__code_object__ = compile(source, __file__, "exec", + optimize=self.__optimize__) + except Exception as details: + import traceback; traceback.print_exc() + raise RuntimeError("compiling %r" % self) from None + elif hasattr(self, "__file__") and not self.__file__.endswith(".pyd"): + # XXX Remove the following line if the Bug is never triggered! + raise RuntimeError("should read __file__ to get the source???") + return self.__code_object__ + + + @property + def __source__(self): + return self.__loader__.get_source(self.__name__) + + + def __repr__(self): + s = "Module(%s" % self.__name__ + if getattr(self, "__file__", None) is not None: + s = s + ", %r" % (self.__file__,) + if getattr(self, "__path__", None) is not None: + s = s + ", %r" % (self.__path__,) + return s + ")" + + +################################################################ + + +def usage(script): + import textwrap + helptext = """\ + Usage: {0} [options] [scripts] + + ModuleFinder scans the bytecode of Python scripts and modules for + import statements, and collects the modules that are needed to run + this code. + + Options: + + -h + --help + Print this help + + What to scan: + + -i <modname> + --import <modname> + Import a module + + -p <packagename> + --package <packagename> + Import a complete package with all its modules + + -x <modname> + --exclude <modname> + Exclude a module + + How to scan: + + -O + --optimize + Use the optimized bytecode + + -v + --verbose + Print reconstructed import statements that are found while + scanning the byte code. + + Reporting: + + -f <modname> + --from <modname> + Print a listing of modules that import modname + + -r + --report + Print a detailed eport listing all the found modules, the + missing modules, and which module imported them. + + -s + --summary + Print a single line listing how many modules were found + and how many modules are missing + """ + + text = textwrap.dedent(helptext.format(os.path.basename(script))) + print(text) + +def main(): + import getopt + try: + opts, args = getopt.gnu_getopt(sys.argv[1:], + "x:f:hi:Op:rsv", + ["exclude=", + "from=", + "help", + "import=", + "optimize", + "package", + "report", + "summary", + "verbose", + ]) + except getopt.GetoptError as err: + print("Error: %s." % err) + sys.exit(2) + + verbose = 0 + excludes = [] + report = 0 + modules = [] + show_from = [] + optimize = 0 + summary = 0 + packages = [] + for o, a in opts: + if o in ("-h", "--help"): + usage(sys.argv[0]) + return 0 + if o in ("-x", "--excludes"): + excludes.append(a) + elif o in ("-i", "--import"): + modules.append(a) + elif o in ("-f", "--from"): + show_from.append(a) + elif o in ("-v", "--verbose"): + verbose += 1 + elif o in ("-r", "--report"): + report += 1 + elif o in ("-O", "--optimize"): + optimize += 1 + elif o in ("-s", "--summary"): + summary = 1 + elif o in ("-p", "--package"): + packages.append(a) + + mf = ModuleFinder( + excludes=excludes, + verbose=verbose, + optimize=optimize, + ) + for name in modules: + # Hm, call import_hook() or safe_import_hook() here? + if name.endswith(".*"): + mf.import_hook(name[:-2], None, ["*"]) + else: + mf.import_hook(name) + for name in packages: + mf.import_package(name) + for path in args: + mf.run_script(path) + if report: + mf.report() + if summary: + mf.report_summary() + for modname in show_from: + print(modname, "imported from:") + for x in sorted(mf._depgraph[modname]): + print(" ", x) + + +if __name__ == "__main__": + main() This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-09-11 07:21:58
|
Revision: 749 http://sourceforge.net/p/py2exe/svn/749 Author: theller Date: 2014-09-11 07:21:47 +0000 (Thu, 11 Sep 2014) Log Message: ----------- Print a meaningful error message when the build fails because bundle_files is too low for certain packages. Add ctypes to the modules needed for bootstrap; it is used by boot_common. Modified Paths: -------------- trunk/py2exe-3/ChangeLog trunk/py2exe-3/py2exe/runtime.py Modified: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog 2014-05-12 12:34:41 UTC (rev 748) +++ trunk/py2exe-3/ChangeLog 2014-09-11 07:21:47 UTC (rev 749) @@ -1,7 +1,17 @@ +2014-09-11 <th...@ct...> + + * py2exe/runtime.py Print a meaningful error message when the + build fails because bundle_files is too low for certain packages. + +2014-05-26 <th...@ct...> + + * py2exe/runtime.py (Runtime.bootstrap_modules): Add ctypes to the + modules needed for bootstrap; it is used by boot_common. + 2014-05-12 <th...@ct...> - * Add missing DeactivateActCtx() call. - Change version number to 0.9.2.1. + * Add missing DeactivateActCtx() call. Change version number to + 0.9.2.1. 2014-05-09 <th...@ct...> Modified: trunk/py2exe-3/py2exe/runtime.py =================================================================== --- trunk/py2exe-3/py2exe/runtime.py 2014-05-12 12:34:41 UTC (rev 748) +++ trunk/py2exe-3/py2exe/runtime.py 2014-09-11 07:21:47 UTC (rev 749) @@ -119,6 +119,7 @@ "codecs", "io", "encodings.*", + "ctypes", # needed for the boot_common boot script } def __init__(self, options): @@ -190,13 +191,23 @@ elif missing: mf.report_missing() + errors = [] for name, value in self.mf.get_min_bundle().items(): if value > self.options.bundle_files: # warn if modules are know to work only for a minimum # bundle_files value - print("OOPS:", name, value) - raise SystemExit(-1) + errors.append([name, value]) + if errors: + print("The following modules require a minimum bundle_files option,") + print("otherwise they will not work.") + print("Currently bundle_files is set to %d:\n" % self.options.bundle_files) + for name, value in errors: + print(" %s: %s" % (name, value)) + print("\nPlease change the bundle_files option and run the build again.") + print("Build failed.") + raise SystemExit(-1) + def build(self): """Build everything. """ @@ -574,11 +585,9 @@ code_objects.append(boot_code) - with open(target.script, "U") as script_file: + with open(target.script, "rb") as script_file: code_objects.append( - # XXX what about compiler options? - # XXX what about source file encodings? - compile(script_file.read() + "\n", + compile(script_file.read() + b"\n", os.path.basename(target.script), "exec", optimize=self.options.optimize)) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-05-12 12:34:44
|
Revision: 748 http://sourceforge.net/p/py2exe/svn/748 Author: theller Date: 2014-05-12 12:34:41 +0000 (Mon, 12 May 2014) Log Message: ----------- Bump version number to 0.9.2.1. Modified Paths: -------------- trunk/py2exe-3/ChangeLog Modified: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog 2014-05-12 12:33:42 UTC (rev 747) +++ trunk/py2exe-3/ChangeLog 2014-05-12 12:34:41 UTC (rev 748) @@ -1,3 +1,8 @@ +2014-05-12 <th...@ct...> + + * Add missing DeactivateActCtx() call. + Change version number to 0.9.2.1. + 2014-05-09 <th...@ct...> * Releasing py2exe for Python 3, version 0.9.2.0. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |