|
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.
|