Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: third_party/twisted_8_1/twisted/python/rebuild.py

Issue 12261012: Remove third_party/twisted_8_1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/build
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # -*- test-case-name: twisted.test.test_rebuild -*-
2 # Copyright (c) 2001-2007 Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5
6 """
7 *Real* reloading support for Python.
8 """
9
10 # System Imports
11 import sys
12 import types
13 import time
14 import linecache
15
16 # Sibling Imports
17 from twisted.python import log, reflect
18
19 lastRebuild = time.time()
20
21
22 class Sensitive:
23 """
24 A utility mixin that's sensitive to rebuilds.
25
26 This is a mixin for classes (usually those which represent collections of
27 callbacks) to make sure that their code is up-to-date before running.
28 """
29
30 lastRebuild = lastRebuild
31
32 def needRebuildUpdate(self):
33 yn = (self.lastRebuild < lastRebuild)
34 return yn
35
36 def rebuildUpToDate(self):
37 self.lastRebuild = time.time()
38
39 def latestVersionOf(self, anObject):
40 """
41 Get the latest version of an object.
42
43 This can handle just about anything callable; instances, functions,
44 methods, and classes.
45 """
46 t = type(anObject)
47 if t == types.FunctionType:
48 return latestFunction(anObject)
49 elif t == types.MethodType:
50 if anObject.im_self is None:
51 return getattr(anObject.im_class, anObject.__name__)
52 else:
53 return getattr(anObject.im_self, anObject.__name__)
54 elif t == types.InstanceType:
55 # Kick it, if it's out of date.
56 getattr(anObject, 'nothing', None)
57 return anObject
58 elif t == types.ClassType:
59 return latestClass(anObject)
60 else:
61 log.msg('warning returning anObject!')
62 return anObject
63
64 _modDictIDMap = {}
65
66 def latestFunction(oldFunc):
67 """
68 Get the latest version of a function.
69 """
70 # This may be CPython specific, since I believe jython instantiates a new
71 # module upon reload.
72 dictID = id(oldFunc.func_globals)
73 module = _modDictIDMap.get(dictID)
74 if module is None:
75 return oldFunc
76 return getattr(module, oldFunc.__name__)
77
78
79 def latestClass(oldClass):
80 """
81 Get the latest version of a class.
82 """
83 module = reflect.namedModule(oldClass.__module__)
84 newClass = getattr(module, oldClass.__name__)
85 newBases = [latestClass(base) for base in newClass.__bases__]
86
87 try:
88 # This makes old-style stuff work
89 newClass.__bases__ = tuple(newBases)
90 return newClass
91 except TypeError:
92 if newClass.__module__ == "__builtin__":
93 # __builtin__ members can't be reloaded sanely
94 return newClass
95 ctor = getattr(newClass, '__metaclass__', type)
96 return ctor(newClass.__name__, tuple(newBases), dict(newClass.__dict__))
97
98
99 class RebuildError(Exception):
100 """
101 Exception raised when trying to rebuild a class whereas it's not possible.
102 """
103
104
105 def updateInstance(self):
106 """
107 Updates an instance to be current.
108 """
109 try:
110 self.__class__ = latestClass(self.__class__)
111 except TypeError:
112 if hasattr(self.__class__, '__slots__'):
113 raise RebuildError("Can't rebuild class with __slots__ on Python < 2 .6")
114 else:
115 raise
116
117
118 def __getattr__(self, name):
119 """
120 A getattr method to cause a class to be refreshed.
121 """
122 if name == '__del__':
123 raise AttributeError("Without this, Python segfaults.")
124 updateInstance(self)
125 log.msg("(rebuilding stale %s instance (%s))" % (reflect.qual(self.__class__ ), name))
126 result = getattr(self, name)
127 return result
128
129
130 def rebuild(module, doLog=1):
131 """
132 Reload a module and do as much as possible to replace its references.
133 """
134 global lastRebuild
135 lastRebuild = time.time()
136 if hasattr(module, 'ALLOW_TWISTED_REBUILD'):
137 # Is this module allowed to be rebuilt?
138 if not module.ALLOW_TWISTED_REBUILD:
139 raise RuntimeError("I am not allowed to be rebuilt.")
140 if doLog:
141 log.msg('Rebuilding %s...' % str(module.__name__))
142
143 ## Safely handle adapter re-registration
144 from twisted.python import components
145 components.ALLOW_DUPLICATES = True
146
147 d = module.__dict__
148 _modDictIDMap[id(d)] = module
149 newclasses = {}
150 classes = {}
151 functions = {}
152 values = {}
153 if doLog:
154 log.msg(' (scanning %s): ' % str(module.__name__))
155 for k, v in d.items():
156 if type(v) == types.ClassType:
157 # Failure condition -- instances of classes with buggy
158 # __hash__/__cmp__ methods referenced at the module level...
159 if v.__module__ == module.__name__:
160 classes[v] = 1
161 if doLog:
162 log.logfile.write("c")
163 log.logfile.flush()
164 elif type(v) == types.FunctionType:
165 if v.func_globals is module.__dict__:
166 functions[v] = 1
167 if doLog:
168 log.logfile.write("f")
169 log.logfile.flush()
170 elif isinstance(v, type):
171 if v.__module__ == module.__name__:
172 newclasses[v] = 1
173 if doLog:
174 log.logfile.write("o")
175 log.logfile.flush()
176
177 values.update(classes)
178 values.update(functions)
179 fromOldModule = values.has_key
180 newclasses = newclasses.keys()
181 classes = classes.keys()
182 functions = functions.keys()
183
184 if doLog:
185 log.msg('')
186 log.msg(' (reload %s)' % str(module.__name__))
187
188 # Boom.
189 reload(module)
190 # Make sure that my traceback printing will at least be recent...
191 linecache.clearcache()
192
193 if doLog:
194 log.msg(' (cleaning %s): ' % str(module.__name__))
195
196 for clazz in classes:
197 if getattr(module, clazz.__name__) is clazz:
198 log.msg("WARNING: class %s not replaced by reload!" % reflect.qual(c lazz))
199 else:
200 if doLog:
201 log.logfile.write("x")
202 log.logfile.flush()
203 clazz.__bases__ = ()
204 clazz.__dict__.clear()
205 clazz.__getattr__ = __getattr__
206 clazz.__module__ = module.__name__
207 if newclasses:
208 import gc
209 for nclass in newclasses:
210 ga = getattr(module, nclass.__name__)
211 if ga is nclass:
212 log.msg("WARNING: new-class %s not replaced by reload!" % reflect.qu al(nclass))
213 else:
214 for r in gc.get_referrers(nclass):
215 if getattr(r, '__class__', None) is nclass:
216 r.__class__ = ga
217 if doLog:
218 log.msg('')
219 log.msg(' (fixing %s): ' % str(module.__name__))
220 modcount = 0
221 for mk, mod in sys.modules.items():
222 modcount = modcount + 1
223 if mod == module or mod is None:
224 continue
225
226 if not hasattr(mod, '__file__'):
227 # It's a builtin module; nothing to replace here.
228 continue
229 changed = 0
230
231 for k, v in mod.__dict__.items():
232 try:
233 hash(v)
234 except TypeError:
235 continue
236 if fromOldModule(v):
237 if type(v) == types.ClassType:
238 if doLog:
239 log.logfile.write("c")
240 log.logfile.flush()
241 nv = latestClass(v)
242 else:
243 if doLog:
244 log.logfile.write("f")
245 log.logfile.flush()
246 nv = latestFunction(v)
247 changed = 1
248 setattr(mod, k, nv)
249 else:
250 # Replace bases of non-module classes just to be sure.
251 if type(v) == types.ClassType:
252 for base in v.__bases__:
253 if fromOldModule(base):
254 latestClass(v)
255 if doLog and not changed and ((modcount % 10) ==0) :
256 log.logfile.write(".")
257 log.logfile.flush()
258
259 components.ALLOW_DUPLICATES = False
260 if doLog:
261 log.msg('')
262 log.msg(' Rebuilt %s.' % str(module.__name__))
263 return module
264
OLDNEW
« no previous file with comments | « third_party/twisted_8_1/twisted/python/randbytes.py ('k') | third_party/twisted_8_1/twisted/python/reflect.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698