From: <th...@us...> - 2014-05-08 19:55:07
|
Revision: 741 http://sourceforge.net/p/py2exe/svn/741 Author: theller Date: 2014-05-08 19:55:04 +0000 (Thu, 08 May 2014) Log Message: ----------- README.rst updates. Modified Paths: -------------- trunk/py2exe-3/README.rst Added Paths: ----------- trunk/py2exe-3/publish/ Property Changed: ---------------- trunk/py2exe-3/ trunk/py2exe-3/py2exe/ Index: trunk/py2exe-3 =================================================================== --- trunk/py2exe-3 2014-05-08 18:40:18 UTC (rev 740) +++ trunk/py2exe-3 2014-05-08 19:55:04 UTC (rev 741) Property changes on: trunk/py2exe-3 ___________________________________________________________________ Added: svn:ignore ## -0,0 +1,2 ## +dist +build Modified: trunk/py2exe-3/README.rst =================================================================== --- trunk/py2exe-3/README.rst 2014-05-08 18:40:18 UTC (rev 740) +++ trunk/py2exe-3/README.rst 2014-05-08 19:55:04 UTC (rev 741) @@ -2,10 +2,13 @@ =================== `py2exe` is a distutils extension which allows to build standalone -Windows executable programs from Python scripts; Python 3.3 and Python -3.4 are supported. +Windows executable programs (32-bit and 64-bit) from Python scripts; +Python 3.3 and Python 3.4 are supported. It can build console +executables, windows (GUI) executables, windows services, and DLL/EXE +COM servers. -`py2exe` for ``Python 2`` is available at http://sourceforge.net/project/showfiles.php?group_id=15583 +py2exe for Python 2 is still available at +http://sourceforge.net/project/showfiles.php?group_id=15583. .. contents:: @@ -13,12 +16,15 @@ News ---- + Create an exe-file with a simple command ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -In addition to you beloved setup.py scripts, there is now a -command-line utility which allows to build the exe without any effort: +In addition to your beloved setup.py scripts :-), there is now also a +command-line utility which allows to build the exe without any effort. +Running + :: py -3.3 -m py2exe.build_exe myscript.py @@ -32,9 +38,9 @@ will create an executable `myscript.exe` in the `dist` subdirectory. -If you add the ``-W <setup-script.py>`` switch to the command line it -will write a *commented* ``setup.py`` script for you, which can be -customized further: +If you add the ``-W <setup-script.py>`` switch to the above command +line a *commented* ``setup.py`` script will be generated which can be +used to further customize the exe: :: @@ -119,19 +125,20 @@ relative pathname of the python archive -b option, --bundle-files option - How to bundle the files. 3 - create an .exe, a zip- - archive, and .pyd files in the file system. 2 - create - .exe and a zip-archive that contains the pyd files. + How to bundle the files: + 3 - create script.exe, python.dll, extensions.pyd, others.dll. + 2 - create script.exe, python.dll, others.dll. + 1 - create script.exe, others.dll. + 0 - create script.exe. -W setup_path, --write-setup-script setup_path Do not build the executables; instead write a setup script that allows further customizations of the build process. - --service modname + -svc svnmodule, --service svcmodule The name of a module that contains a service - Using a setup-script -------------------- @@ -140,6 +147,105 @@ switches are the same as before; but they are *NOT* compatible with the command-line switches for the builder mentioned above. +Documentation about the setup-script and other usage tips are in the +wiki pages at http://www.py2exe.org. + + +The bundle-files option explained +--------------------------------- + +The applications that py2exe creates will always need the following +parts: + +1. The exe-file(s) itself. py2exe can build several executables at the + same time; this is especially useful if these are related to each + other since some parts can be shared. +2. The python-dll. +3. The pure python modules needed to run the app. The byte-code for these + modules is always packed into a zip-archive. +4. Compiled python-extension modules. +5. Supporting dlls, if any. + +The bundle-files option determines how these files are packed together +for your application. This is explained with a script ``test_sqlite.py`` +that simply contains this code: + +:: + + import sqlite3 + print(sqlite3) + +The command to build the exe-file is: + +:: + + py2exe.build_exe test_sqlite.py -c --bundle-files <option> + +The ``-c`` option specifies to create a compressed zip-archive. + +``--bundle-files 3`` is the simplest way. These files will be +created in a ``dist`` subdirectory, about 8 MB total size: + +:: + + test_sqlite.exe + _bz2.pyd + _ctypes.pyd + _hashlib.pyd + _lzma.pyd + _socket.pyd + _sqlite3.pyd + _ssl.pyd + _win32sysloader.pyd + pyexpat.pyd + python34.dll + pywintypes34.dll + select.pyd + sqlite3.dll + unicodedata.pyd + win32api.pyd + win32evtlog.pyd + +The zip-archive is appended to the test_sqlite.exe file itself, which +has a size of 1.5 MB in this case. + +``--bundle-files 2`` will include all the Python extensions into the +appended zip-archive; they are loaded via special code at runtime +*without* being unpacked to the file-system. The files in the +``dist`` directory now are these: + +:: + + test_sqlite.exe + python34.dll + sqlite3.dll + +``--bundle-files 1`` will additionally pack the python-dll into the +zip-archive: + +:: + + test_sqlite.exe + sqlite3.dll + +``--bundle-files 0`` now finally creates a real single-file executable +of 6 MB: + +:: + + test_sqlite.exe + +If you are building several related executables that you plan to +distribute together, it may make sense to specify a zip-archive shared +by all the exes with the ``--library libname`` option. The +executables will then become quite small (about 25 kB), since nearly +all code will be in the separate shared archive. + +*Note that not all applications will work with ``bundle-files`` set to +0 or 1*. Be sure to test them. + + + Bugs ---- Index: trunk/py2exe-3/publish =================================================================== --- trunk/py2exe-3/publish 2014-05-08 18:40:18 UTC (rev 740) +++ trunk/py2exe-3/publish 2014-05-08 19:55:04 UTC (rev 741) Property changes on: trunk/py2exe-3/publish ___________________________________________________________________ Added: svn:ignore ## -0,0 +1,2 ## +dist +__pycache__ Index: trunk/py2exe-3/py2exe =================================================================== --- trunk/py2exe-3/py2exe 2014-05-08 18:40:18 UTC (rev 740) +++ trunk/py2exe-3/py2exe 2014-05-08 19:55:04 UTC (rev 741) Property changes on: trunk/py2exe-3/py2exe ___________________________________________________________________ Added: svn:ignore ## -0,0 +1 ## +__pycache__ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <th...@us...> - 2014-05-09 17:44:20
|
Revision: 743 http://sourceforge.net/p/py2exe/svn/743 Author: theller Date: 2014-05-09 17:44:17 +0000 (Fri, 09 May 2014) Log Message: ----------- Ready for release. Version 0.9.2.0. Modified Paths: -------------- trunk/py2exe-3/README.rst trunk/py2exe-3/py2exe/__init__.py Added Paths: ----------- trunk/py2exe-3/ChangeLog Added: trunk/py2exe-3/ChangeLog =================================================================== --- trunk/py2exe-3/ChangeLog (rev 0) +++ trunk/py2exe-3/ChangeLog 2014-05-09 17:44:17 UTC (rev 743) @@ -0,0 +1,3 @@ +2014-05-09 <th...@ct...> + + * Releasing py2exe for Python 3, version 0.9.2.0. Modified: trunk/py2exe-3/README.rst =================================================================== --- trunk/py2exe-3/README.rst 2014-05-09 17:25:07 UTC (rev 742) +++ trunk/py2exe-3/README.rst 2014-05-09 17:44:17 UTC (rev 743) @@ -3,9 +3,8 @@ `py2exe` is a distutils extension which allows to build standalone Windows executable programs (32-bit and 64-bit) from Python scripts; -Python 3.3 and Python 3.4 are supported. It can build console -executables, windows (GUI) executables, windows services, and DLL/EXE -COM servers. +Python 3.3 and later are supported. It can build console executables, +windows (GUI) executables, windows services, and DLL/EXE COM servers. py2exe for Python 2 is still available at http://sourceforge.net/project/showfiles.php?group_id=15583. @@ -16,10 +15,24 @@ News ---- +The C-runtime library for Python 3 does NOT need a windows manifest +any longer to load correctly (this is a feature of Python, not of +py2exe). -Create an exe-file with a simple command -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +`py2exe` now contains a hooks module which contains information about +some standard packages. The goal is to fine-tune the build process so +that no (at least less) warnings are emitted from modulefinder. +Thanks to a brand new modulefinder (based on Python's importlib) +py2exe can now find and extract modules even from packages you have +installed as zipped eggs. + +py2exe now longer uses a `build` directory for temporary files. + +It is planned to achive full compatibility with the setup-scripts for +Python 2; however this is probably not yet the case. + + In addition to your beloved setup.py scripts :-), there is now also a command-line utility which allows to build the exe without any effort. @@ -27,7 +40,7 @@ :: - py -3.3 -m py2exe.build_exe myscript.py + py -3.4 -m py2exe.build_exe myscript.py or (if you have the Python ``Scripts`` directory on your PATH): @@ -44,39 +57,17 @@ :: - py -3.3 -m py2exe myscript.py -W mysetup.py + py -3.4 -m py2exe myscript.py -W mysetup.py ... edit myssetup.py - py -3.3 mysetup.py py2exe + py -3.4 mysetup.py py2exe -Hooks -~~~~~ -`py2exe` now contains a hooks module which allows to customize the -build-process. The goal is to fine-tune the build process so that no -warnings are emitted from modulefinder. - -The hooks module is the `py2exe\\hooks.py` file in your installation; -it currently contains hooks for quite some libraries. Patches for -more libraries will gratefully be accepted. - -Windows C-runtime library -~~~~~~~~~~~~~~~~~~~~~~~~~ - -The C-runtime library for Python 3 does NOT need a windows manifest -any longer, unless you have special requirements. - -Compatibility with py2exe for Python 2 -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It is planned to achive full compatibility with the setup-scripts for -Python 2; however this is probably not yet the case. - Installation ------------ :: - py -3.3 -m pip install py2exe + py -3.4 -m pip install py2exe or @@ -251,3 +242,5 @@ Building isapi extensions is not supported: I don't use them so I will not implement this. + +The modulefinder does not yet Modified: trunk/py2exe-3/py2exe/__init__.py =================================================================== --- trunk/py2exe-3/py2exe/__init__.py 2014-05-09 17:25:07 UTC (rev 742) +++ trunk/py2exe-3/py2exe/__init__.py 2014-05-09 17:44:17 UTC (rev 743) @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- """py2exe package """ -__version__ = "0.9.1.8" +__version__ = "0.9.2.0" 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-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-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-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-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-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-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-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 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-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...> - 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. |