merge with crew.
authorVadim Gelfer <vadim.gelfer@gmail.com>
Fri, 19 May 2006 14:58:13 -0700
changeset 2327 185cb7fffbeb
parent 2326 d0ba2f6b9d97 (current diff)
parent 2325 c4ea7f927dab (diff)
child 2328 f789602ba840
merge with crew.
--- a/mercurial/packagescan.py	Fri May 19 14:57:45 2006 -0700
+++ b/mercurial/packagescan.py	Fri May 19 14:58:13 2006 -0700
@@ -1,5 +1,6 @@
 # packagescan.py - Helper module for identifing used modules.
 # Used for the py2exe distutil.
+# This module must be the first mercurial module imported in setup.py
 #
 # Copyright 2005 Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
 #
@@ -8,25 +9,58 @@
 import glob
 import os
 import sys
-import demandload
 import ihooks
+import types
+import string
+
+# Install this module as fake demandload module
+sys.modules['mercurial.demandload'] = sys.modules[__name__]
 
-requiredmodules = {} # Will contain the modules imported by demandload
+# Requiredmodules contains the modules imported by demandload.
+# Please note that demandload can be invoked before the 
+# mercurial.packagescan.scan method is invoked in case a mercurial
+# module is imported.
+requiredmodules = {} 
 def demandload(scope, modules):
-    """ fake demandload function that collects the required modules """
+    """ fake demandload function that collects the required modules 
+        foo            import foo
+        foo bar        import foo, bar
+        foo.bar        import foo.bar
+        foo:bar        from foo import bar
+        foo:bar,quux   from foo import bar, quux
+        foo.bar:quux   from foo.bar import quux"""
+
     for m in modules.split():
         mod = None
         try:
-            module, submodules = m.split(':')
-            submodules = submodules.split(',')
+            module, fromlist = m.split(':')
+            fromlist = fromlist.split(',')
         except:
             module = m
-            submodules = []
-        mod = __import__(module, scope, scope, submodules)
-        scope[module] = mod
-        requiredmodules[mod.__name__] = 1
+            fromlist = []
+        mod = __import__(module, scope, scope, fromlist)
+        if fromlist == []:
+            # mod is only the top package, but we need all packages
+            comp = module.split('.')
+            i = 1
+            mn = comp[0]
+            while True:
+                # mn and mod.__name__ might not be the same
+                scope[mn] = mod
+                requiredmodules[mod.__name__] = 1
+                if len(comp) == i: break
+                mod = getattr(mod,comp[i]) 
+                mn = string.join(comp[:i+1],'.')
+                i += 1
+        else:
+            # mod is the last package in the component list
+            requiredmodules[mod.__name__] = 1
+            for f in fromlist:
+                scope[f] = getattr(mod,f)
+                if type(scope[f]) == types.ModuleType:
+                    requiredmodules[scope[f].__name__] = 1
 
-def getmodules(libpath,packagename):
+def scan(libpath,packagename):
     """ helper for finding all required modules of package <packagename> """
     # Use the package in the build directory
     libpath = os.path.abspath(libpath)
@@ -45,8 +79,6 @@
     pymodulefiles = glob.glob('*.py')
     extmodulefiles = glob.glob('*.pyd')
     os.chdir(cwd)
-    # Install a fake demandload module
-    sys.modules['mercurial.demandload'] = sys.modules['mercurial.packagescan']
     # Import all python modules and by that run the fake demandload
     for m in pymodulefiles:
         if m == '__init__.py': continue
@@ -62,8 +94,9 @@
         fullname = packagename+'.'+mname
         __import__(fullname,tmp,tmp)
         requiredmodules[fullname] = 1
-    includes = requiredmodules.keys()
-    return includes
+
+def getmodules():
+    return requiredmodules.keys()
 
 def importfrom(filename):
     """
--- a/setup.py	Fri May 19 14:57:45 2006 -0700
+++ b/setup.py	Fri May 19 14:58:13 2006 -0700
@@ -13,6 +13,8 @@
 from distutils.core import setup, Extension
 from distutils.command.install_data import install_data
 
+# mercurial.packagescan must be the first mercurial module imported
+import mercurial.packagescan
 import mercurial.version
 
 # py2exe needs to be installed to work
@@ -36,7 +38,6 @@
     # Due to the use of demandload py2exe is not finding the modules.
     # packagescan.getmodules creates a list of modules included in
     # the mercurial package plus depdent modules.
-    import mercurial.packagescan
     from py2exe.build_exe import py2exe as build_exe
 
     class py2exe_for_demandload(build_exe):
@@ -54,12 +55,10 @@
                 self.includes = []
             else:
                 self.includes = self.includes.split(',')
-            self.includes += mercurial.packagescan.getmodules(self.build_lib,
-                                                              'mercurial')
-            self.includes += mercurial.packagescan.getmodules(self.build_lib,
-                                                              'mercurial/hgweb')
-            self.includes += mercurial.packagescan.getmodules(self.build_lib,
-                                                              'hgext')
+            mercurial.packagescan.scan(self.build_lib,'mercurial')
+            mercurial.packagescan.scan(self.build_lib,'mercurial/hgweb')
+            mercurial.packagescan.scan(self.build_lib,'hgext')
+            self.includes += mercurial.packagescan.getmodules()
             build_exe.finalize_options(self)
 except ImportError:
     py2exe_for_demandload = None