annotate mercurial/demandload.py @ 2076:d007df6daf8e

Create an atomic opener that does not automatically rename on close The revlog.checkinlinesize() uses an atomic opener to replace the index file after converting it from inline to traditional .i and .d files. If this operation is interrupted, the atomic file class can overwrite a valid file with a partially written one. This patch introduces an atomic opener that does not automatically replace the destination file with the tempfile. This way an interrupted checkinlinesize() call turns into a noop.
author mason@suse.com
date Tue, 04 Apr 2006 16:38:44 -0400
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)