Mercurial > hg
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 |
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 | 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 | 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 | 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) |