##// END OF EJS Templates
Support foo@bar notation as demandload module spec.
Shun-ichi GOTO -
r2993:985594e8 default
parent child Browse files
Show More
@@ -1,125 +1,128 b''
1 # packagescan.py - Helper module for identifing used modules.
1 # packagescan.py - Helper module for identifing used modules.
2 # Used for the py2exe distutil.
2 # Used for the py2exe distutil.
3 # This module must be the first mercurial module imported in setup.py
3 # This module must be the first mercurial module imported in setup.py
4 #
4 #
5 # Copyright 2005, 2006 Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
5 # Copyright 2005, 2006 Volker Kleinfeld <Volker.Kleinfeld@gmx.de>
6 #
6 #
7 # This software may be used and distributed according to the terms
7 # This software may be used and distributed according to the terms
8 # of the GNU General Public License, incorporated herein by reference.
8 # of the GNU General Public License, incorporated herein by reference.
9 import glob
9 import glob
10 import os
10 import os
11 import sys
11 import sys
12 import ihooks
12 import ihooks
13 import types
13 import types
14 import string
14 import string
15
15
16 # Install this module as fake demandload module
16 # Install this module as fake demandload module
17 sys.modules['mercurial.demandload'] = sys.modules[__name__]
17 sys.modules['mercurial.demandload'] = sys.modules[__name__]
18
18
19 # Requiredmodules contains the modules imported by demandload.
19 # Requiredmodules contains the modules imported by demandload.
20 # Please note that demandload can be invoked before the
20 # Please note that demandload can be invoked before the
21 # mercurial.packagescan.scan method is invoked in case a mercurial
21 # mercurial.packagescan.scan method is invoked in case a mercurial
22 # module is imported.
22 # module is imported.
23 requiredmodules = {}
23 requiredmodules = {}
24 def demandload(scope, modules):
24 def demandload(scope, modules):
25 """ fake demandload function that collects the required modules
25 """ fake demandload function that collects the required modules
26 foo import foo
26 foo import foo
27 foo bar import foo, bar
27 foo bar import foo, bar
28 foo@bar import foo as bar
28 foo.bar import foo.bar
29 foo.bar import foo.bar
29 foo:bar from foo import bar
30 foo:bar from foo import bar
30 foo:bar,quux from foo import bar, quux
31 foo:bar,quux from foo import bar, quux
31 foo.bar:quux from foo.bar import quux"""
32 foo.bar:quux from foo.bar import quux"""
32
33
33 for m in modules.split():
34 for m in modules.split():
34 mod = None
35 mod = None
35 try:
36 try:
36 module, fromlist = m.split(':')
37 module, fromlist = m.split(':')
37 fromlist = fromlist.split(',')
38 fromlist = fromlist.split(',')
38 except:
39 except:
39 module = m
40 module = m
40 fromlist = []
41 fromlist = []
42 if '@' in module:
43 module, as_ = module.split('@')
41 mod = __import__(module, scope, scope, fromlist)
44 mod = __import__(module, scope, scope, fromlist)
42 if fromlist == []:
45 if fromlist == []:
43 # mod is only the top package, but we need all packages
46 # mod is only the top package, but we need all packages
44 comp = module.split('.')
47 comp = module.split('.')
45 i = 1
48 i = 1
46 mn = comp[0]
49 mn = comp[0]
47 while True:
50 while True:
48 # mn and mod.__name__ might not be the same
51 # mn and mod.__name__ might not be the same
49 scope[mn] = mod
52 scope[mn] = mod
50 requiredmodules[mod.__name__] = 1
53 requiredmodules[mod.__name__] = 1
51 if len(comp) == i: break
54 if len(comp) == i: break
52 mod = getattr(mod,comp[i])
55 mod = getattr(mod,comp[i])
53 mn = string.join(comp[:i+1],'.')
56 mn = string.join(comp[:i+1],'.')
54 i += 1
57 i += 1
55 else:
58 else:
56 # mod is the last package in the component list
59 # mod is the last package in the component list
57 requiredmodules[mod.__name__] = 1
60 requiredmodules[mod.__name__] = 1
58 for f in fromlist:
61 for f in fromlist:
59 scope[f] = getattr(mod,f)
62 scope[f] = getattr(mod,f)
60 if type(scope[f]) == types.ModuleType:
63 if type(scope[f]) == types.ModuleType:
61 requiredmodules[scope[f].__name__] = 1
64 requiredmodules[scope[f].__name__] = 1
62
65
63 class SkipPackage(Exception):
66 class SkipPackage(Exception):
64 def __init__(self, reason):
67 def __init__(self, reason):
65 self.reason = reason
68 self.reason = reason
66
69
67 scan_in_progress = False
70 scan_in_progress = False
68
71
69 def scan(libpath,packagename):
72 def scan(libpath,packagename):
70 """ helper for finding all required modules of package <packagename> """
73 """ helper for finding all required modules of package <packagename> """
71 global scan_in_progress
74 global scan_in_progress
72 scan_in_progress = True
75 scan_in_progress = True
73 # Use the package in the build directory
76 # Use the package in the build directory
74 libpath = os.path.abspath(libpath)
77 libpath = os.path.abspath(libpath)
75 sys.path.insert(0,libpath)
78 sys.path.insert(0,libpath)
76 packdir = os.path.join(libpath,packagename.replace('.', '/'))
79 packdir = os.path.join(libpath,packagename.replace('.', '/'))
77 # A normal import would not find the package in
80 # A normal import would not find the package in
78 # the build directory. ihook is used to force the import.
81 # the build directory. ihook is used to force the import.
79 # After the package is imported the import scope for
82 # After the package is imported the import scope for
80 # the following imports is settled.
83 # the following imports is settled.
81 p = importfrom(packdir)
84 p = importfrom(packdir)
82 globals()[packagename] = p
85 globals()[packagename] = p
83 sys.modules[packagename] = p
86 sys.modules[packagename] = p
84 # Fetch the python modules in the package
87 # Fetch the python modules in the package
85 cwd = os.getcwd()
88 cwd = os.getcwd()
86 os.chdir(packdir)
89 os.chdir(packdir)
87 pymodulefiles = glob.glob('*.py')
90 pymodulefiles = glob.glob('*.py')
88 extmodulefiles = glob.glob('*.pyd')
91 extmodulefiles = glob.glob('*.pyd')
89 os.chdir(cwd)
92 os.chdir(cwd)
90 # Import all python modules and by that run the fake demandload
93 # Import all python modules and by that run the fake demandload
91 for m in pymodulefiles:
94 for m in pymodulefiles:
92 if m == '__init__.py': continue
95 if m == '__init__.py': continue
93 tmp = {}
96 tmp = {}
94 mname,ext = os.path.splitext(m)
97 mname,ext = os.path.splitext(m)
95 fullname = packagename+'.'+mname
98 fullname = packagename+'.'+mname
96 try:
99 try:
97 __import__(fullname,tmp,tmp)
100 __import__(fullname,tmp,tmp)
98 except SkipPackage, inst:
101 except SkipPackage, inst:
99 print >> sys.stderr, 'skipping %s: %s' % (fullname, inst.reason)
102 print >> sys.stderr, 'skipping %s: %s' % (fullname, inst.reason)
100 continue
103 continue
101 requiredmodules[fullname] = 1
104 requiredmodules[fullname] = 1
102 # Import all extension modules and by that run the fake demandload
105 # Import all extension modules and by that run the fake demandload
103 for m in extmodulefiles:
106 for m in extmodulefiles:
104 tmp = {}
107 tmp = {}
105 mname,ext = os.path.splitext(m)
108 mname,ext = os.path.splitext(m)
106 fullname = packagename+'.'+mname
109 fullname = packagename+'.'+mname
107 __import__(fullname,tmp,tmp)
110 __import__(fullname,tmp,tmp)
108 requiredmodules[fullname] = 1
111 requiredmodules[fullname] = 1
109
112
110 def getmodules():
113 def getmodules():
111 return requiredmodules.keys()
114 return requiredmodules.keys()
112
115
113 def importfrom(filename):
116 def importfrom(filename):
114 """
117 """
115 import module/package from a named file and returns the module.
118 import module/package from a named file and returns the module.
116 It does not check on sys.modules or includes the module in the scope.
119 It does not check on sys.modules or includes the module in the scope.
117 """
120 """
118 loader = ihooks.BasicModuleLoader()
121 loader = ihooks.BasicModuleLoader()
119 path, file = os.path.split(filename)
122 path, file = os.path.split(filename)
120 name, ext = os.path.splitext(file)
123 name, ext = os.path.splitext(file)
121 m = loader.find_module_in_dir(name, path)
124 m = loader.find_module_in_dir(name, path)
122 if not m:
125 if not m:
123 raise ImportError, name
126 raise ImportError, name
124 m = loader.load_module(name, m)
127 m = loader.load_module(name, m)
125 return m
128 return m
General Comments 0
You need to be logged in to leave comments. Login now