annotate mercurial/demandload.py @ 2178:00205fe76993

merge with crew.
author Vadim Gelfer <vadim.gelfer@gmail.com>
date Tue, 02 May 2006 14:38:32 -0700
parents f3abe0bdccdd
children d01eac5968c6
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1826
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
1 '''Demand load modules when used, not when imported.'''
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
2
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
3 __author__ = '''Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>.
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
4 This software may be used and distributed according to the terms
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
5 of the GNU General Public License, incorporated herein by reference.'''
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
6
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
7 # this is based on matt's original demandload module. it is a
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
8 # complete rewrite. some time, we may need to support syntax of
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
9 # "import foo as bar".
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
10
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
11 class _importer(object):
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
12 '''import a module. it is not imported until needed, and is
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
13 imported at most once per scope.'''
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
14
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
15 def __init__(self, scope, modname, fromlist):
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
16 '''scope is context (globals() or locals()) in which import
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
17 should be made. modname is name of module to import.
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
18 fromlist is list of modules for "from foo import ..."
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
19 emulation.'''
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
20
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
21 self.scope = scope
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
22 self.modname = modname
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
23 self.fromlist = fromlist
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
24 self.mod = None
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
25
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
26 def module(self):
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
27 '''import the module if needed, and return.'''
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
28 if self.mod is None:
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
29 self.mod = __import__(self.modname, self.scope, self.scope,
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
30 self.fromlist)
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
31 del self.modname, self.fromlist
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
32 return self.mod
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
33
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
34 class _replacer(object):
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
35 '''placeholder for a demand loaded module. demandload puts this in
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
36 a target scope. when an attribute of this object is looked up,
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
37 this object is replaced in the target scope with the actual
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
38 module.
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
39
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
40 we use __getattribute__ to avoid namespace clashes between
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
41 placeholder object and real module.'''
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
42
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
43 def __init__(self, importer, target):
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
44 self.importer = importer
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
45 self.target = target
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
46 # consider case where we do this:
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
47 # demandload(globals(), 'foo.bar foo.quux')
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
48 # foo will already exist in target scope when we get to
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
49 # foo.quux. so we remember that we will need to demandload
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
50 # quux into foo's scope when we really load it.
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
51 self.later = []
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
52
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
53 def module(self):
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
54 return object.__getattribute__(self, 'importer').module()
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
55
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
56 def __getattribute__(self, key):
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
57 '''look up an attribute in a module and return it. replace the
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
58 name of the module in the caller\'s dict with the actual
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
59 module.'''
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents:
diff changeset
60
1826
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
61 module = object.__getattribute__(self, 'module')()
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
62 target = object.__getattribute__(self, 'target')
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
63 importer = object.__getattribute__(self, 'importer')
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
64 later = object.__getattribute__(self, 'later')
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
65
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
66 if later:
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
67 demandload(module.__dict__, ' '.join(later))
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
68
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
69 importer.scope[target] = module
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
70
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
71 return getattr(module, key)
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
72
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
73 class _replacer_from(_replacer):
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
74 '''placeholder for a demand loaded module. used for "from foo
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
75 import ..." emulation. semantics of this are different than
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
76 regular import, so different implementation needed.'''
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
77
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
78 def module(self):
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
79 importer = object.__getattribute__(self, 'importer')
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
80 target = object.__getattribute__(self, 'target')
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
81
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
82 return getattr(importer.module(), target)
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
83
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
84 def demandload(scope, modules):
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
85 '''import modules into scope when each is first used.
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
86
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
87 scope should be the value of globals() in the module calling this
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
88 function, or locals() in the calling function.
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
89
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
90 modules is a string listing module names, separated by white
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
91 space. names are handled like this:
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents:
diff changeset
92
1826
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
93 foo import foo
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
94 foo bar import foo, bar
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
95 foo.bar import foo.bar
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
96 foo:bar from foo import bar
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
97 foo:bar,quux from foo import bar, quux
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
98 foo.bar:quux from foo.bar import quux'''
262
3db700146536 implement demand loading hack
mpm@selenic.com
parents:
diff changeset
99
1826
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
100 for mod in modules.split():
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
101 col = mod.find(':')
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
102 if col >= 0:
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
103 fromlist = mod[col+1:].split(',')
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
104 mod = mod[:col]
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
105 else:
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
106 fromlist = []
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
107 importer = _importer(scope, mod, fromlist)
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
108 if fromlist:
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
109 for name in fromlist:
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
110 scope[name] = _replacer_from(importer, name)
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
111 else:
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
112 dot = mod.find('.')
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
113 if dot >= 0:
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
114 basemod = mod[:dot]
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
115 val = scope.get(basemod)
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
116 # if base module has already been demandload()ed,
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
117 # remember to load this submodule into its namespace
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
118 # when needed.
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
119 if isinstance(val, _replacer):
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
120 later = object.__getattribute__(val, 'later')
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
121 later.append(mod[dot+1:])
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
122 continue
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
123 else:
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
124 basemod = mod
f3abe0bdccdd rewrite demandload module to be more flexible.
Vadim Gelfer <vadim.gelger@gmail.com>
parents: 262
diff changeset
125 scope[basemod] = _replacer(importer, basemod)