|
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(sou...
[truncated message content] |