def versionUpgrade(self): """(internal) Do a version upgrade. """ bases = _aybabtu(self.__class__) # put the bases in order so superclasses' persistenceVersion methods # will be called first. bases.reverse() bases.append(self.__class__) # don't forget me!! # first let's look for old-skool versioned's if self.__dict__.has_key("persistenceVersion"): # Hacky heuristic: if more than one class subclasses Versioned, # we'll assume that the higher version number wins for the older # class, so we'll consider the attribute the version of the older # class. There are obviously possibly times when this will # eventually be an incorrect assumption, but hopefully old-school # persistenceVersion stuff won't make it that far into multiple # classes inheriting from Versioned. pver = self.__dict__['persistenceVersion'] del self.__dict__['persistenceVersion'] highestVersion = 0 highestBase = None for base in bases: if not base.__dict__.has_key('persistenceVersion'): continue if base.persistenceVersion > highestVersion: highestBase = base highestVersion = base.persistenceVersion if highestBase: self.__dict__['%s.persistenceVersion' % reflect.qual(highestBase)] = pver for base in bases: # ugly hack, but it's what the user expects, really if (Versioned not in base.__bases__ and not base.__dict__.has_key('persistenceVersion')): continue currentVers = base.persistenceVersion pverName = '%s.persistenceVersion' % reflect.qual(base) persistVers = (self.__dict__.get(pverName) or 0) if persistVers: del self.__dict__[pverName] assert persistVers <= currentVers, "Sorry, can't go backwards in time." while persistVers < currentVers: persistVers = persistVers + 1 method = base.__dict__.get('upgradeToVersion%s' % persistVers, None) if method: log.msg("Upgrading %s (of %s @ %s) to version %s" % (reflect.qual(base), reflect.qual( self.__class__), id(self), persistVers)) method(self) else: log.msg('Warning: cannot upgrade %s to version %s' % (base, persistVers))
def spewer(frame, s, ignored): """A trace function for sys.settrace that prints every function or method call.""" from lib.twisted.python import reflect if frame.f_locals.has_key('self'): se = frame.f_locals['self'] if hasattr(se, '__class__'): k = reflect.qual(se.__class__) else: k = reflect.qual(type(se)) print 'method %s of %s at %s' % (frame.f_code.co_name, k, id(se)) else: print 'function %s in %s, line %s' % ( frame.f_code.co_name, frame.f_code.co_filename, frame.f_lineno)
def versionUpgrade(self): """(internal) Do a version upgrade. """ bases = _aybabtu(self.__class__) # put the bases in order so superclasses' persistenceVersion methods # will be called first. bases.reverse() bases.append(self.__class__) # don't forget me!! # first let's look for old-skool versioned's if self.__dict__.has_key("persistenceVersion"): # Hacky heuristic: if more than one class subclasses Versioned, # we'll assume that the higher version number wins for the older # class, so we'll consider the attribute the version of the older # class. There are obviously possibly times when this will # eventually be an incorrect assumption, but hopefully old-school # persistenceVersion stuff won't make it that far into multiple # classes inheriting from Versioned. pver = self.__dict__['persistenceVersion'] del self.__dict__['persistenceVersion'] highestVersion = 0 highestBase = None for base in bases: if not base.__dict__.has_key('persistenceVersion'): continue if base.persistenceVersion > highestVersion: highestBase = base highestVersion = base.persistenceVersion if highestBase: self.__dict__['%s.persistenceVersion' % reflect.qual(highestBase)] = pver for base in bases: # ugly hack, but it's what the user expects, really if (Versioned not in base.__bases__ and not base.__dict__.has_key('persistenceVersion')): continue currentVers = base.persistenceVersion pverName = '%s.persistenceVersion' % reflect.qual(base) persistVers = (self.__dict__.get(pverName) or 0) if persistVers: del self.__dict__[pverName] assert persistVers <= currentVers, "Sorry, can't go backwards in time." while persistVers < currentVers: persistVers = persistVers + 1 method = base.__dict__.get('upgradeToVersion%s' % persistVers, None) if method: log.msg( "Upgrading %s (of %s @ %s) to version %s" % (reflect.qual(base), reflect.qual(self.__class__), id(self), persistVers) ) method(self) else: log.msg( 'Warning: cannot upgrade %s to version %s' % (base, persistVers) )
def showwarning(self, message, category, filename, lineno, file=None, line=None): """ Twisted-enabled wrapper around L{warnings.showwarning}. If C{file} is C{None}, the default behaviour is to emit the warning to the log system, otherwise the original L{warnings.showwarning} Python function is called. """ if file is None: self.msg( warning=message, category=reflect.qual(category), filename=filename, lineno=lineno, format="%(filename)s:%(lineno)s: %(category)s: %(warning)s") else: if sys.version_info < (2, 6): _oldshowwarning(message, category, filename, lineno, file) else: _oldshowwarning(message, category, filename, lineno, file, line)
def proxyForInterface(iface, originalAttribute='original'): """ Create a class which proxies all method calls which adhere to an interface to another provider of that interface. This function is intended for creating specialized proxies. The typical way to use it is by subclassing the result:: class MySpecializedProxy(proxyForInterface(IFoo)): def someInterfaceMethod(self, arg): if arg == 3: return 3 return self.original.someInterfaceMethod(arg) @param iface: The Interface to which the resulting object will conform, and which the wrapped object must provide. @param originalAttribute: name of the attribute used to save the original object in the resulting class. Default to C{original}. @type originalAttribute: C{str} @return: A class whose constructor takes the original object as its only argument. Constructing the class creates the proxy. """ def __init__(self, original): setattr(self, originalAttribute, original) contents = {"__init__": __init__} for name in iface: contents[name] = _ProxyDescriptor(name, originalAttribute) proxy = type("(Proxy for %s)" % (reflect.qual(iface),), (object,), contents) declarations.classImplements(proxy, iface) return proxy
def getComponent(self, interface, default=None): """Create or retrieve an adapter for the given interface. If such an adapter has already been created, retrieve it from the cache that this instance keeps of all its adapters. Adapters created through this mechanism may safely store system-specific state. If you want to register an adapter that will be created through getComponent, but you don't require (or don't want) your adapter to be cached and kept alive for the lifetime of this Componentized object, set the attribute 'temporaryAdapter' to True on your adapter class. If you want to automatically register an adapter for all appropriate interfaces (with addComponent), set the attribute 'multiComponent' to True on your adapter class. """ k = reflect.qual(interface) if self._adapterCache.has_key(k): return self._adapterCache[k] else: adapter = interface.__adapt__(self) if adapter is not None and not ( hasattr(adapter, "temporaryAdapter") and adapter.temporaryAdapter): self._adapterCache[k] = adapter if (hasattr(adapter, "multiComponent") and adapter.multiComponent): self.addComponent(adapter) if adapter is None: return default return adapter
def proxyForInterface(iface, originalAttribute='original'): """ Create a class which proxies all method calls which adhere to an interface to another provider of that interface. This function is intended for creating specialized proxies. The typical way to use it is by subclassing the result:: class MySpecializedProxy(proxyForInterface(IFoo)): def someInterfaceMethod(self, arg): if arg == 3: return 3 return self.original.someInterfaceMethod(arg) @param iface: The Interface to which the resulting object will conform, and which the wrapped object must provide. @param originalAttribute: name of the attribute used to save the original object in the resulting class. Default to C{original}. @type originalAttribute: C{str} @return: A class whose constructor takes the original object as its only argument. Constructing the class creates the proxy. """ def __init__(self, original): setattr(self, originalAttribute, original) contents = {"__init__": __init__} for name in iface: contents[name] = _ProxyDescriptor(name, originalAttribute) proxy = type("(Proxy for %s)" % (reflect.qual(iface), ), (object, ), contents) declarations.classImplements(proxy, iface) return proxy
def getComponent(self, interface, default=None): """Create or retrieve an adapter for the given interface. If such an adapter has already been created, retrieve it from the cache that this instance keeps of all its adapters. Adapters created through this mechanism may safely store system-specific state. If you want to register an adapter that will be created through getComponent, but you don't require (or don't want) your adapter to be cached and kept alive for the lifetime of this Componentized object, set the attribute 'temporaryAdapter' to True on your adapter class. If you want to automatically register an adapter for all appropriate interfaces (with addComponent), set the attribute 'multiComponent' to True on your adapter class. """ k = reflect.qual(interface) if self._adapterCache.has_key(k): return self._adapterCache[k] else: adapter = interface.__adapt__(self) if adapter is not None and not (hasattr( adapter, "temporaryAdapter") and adapter.temporaryAdapter): self._adapterCache[k] = adapter if (hasattr(adapter, "multiComponent") and adapter.multiComponent): self.addComponent(adapter) if adapter is None: return default return adapter
def doRead(self): """Called when data is avaliable for reading. Subclasses must override this method. The result will be interpreted in the same way as a result of doWrite(). """ raise NotImplementedError("%s does not implement doRead" % reflect.qual(self.__class__))
def spewer(frame, s, ignored): """A trace function for sys.settrace that prints every function or method call.""" from lib.twisted.python import reflect if frame.f_locals.has_key('self'): se = frame.f_locals['self'] if hasattr(se, '__class__'): k = reflect.qual(se.__class__) else: k = reflect.qual(type(se)) print 'method %s of %s at %s' % ( frame.f_code.co_name, k, id(se) ) else: print 'function %s in %s, line %s' % ( frame.f_code.co_name, frame.f_code.co_filename, frame.f_lineno)
def _callProcessExited(self, reason): default = object() processExited = getattr(self.proto, 'processExited', default) if processExited is default: getWarningMethod()( _missingProcessExited % (qual(self.proto.__class__),), DeprecationWarning, stacklevel=0) else: processExited(Failure(reason))
def _transPopulateSchema(self): """Used to construct the row classes in a single interaction. """ for rc in self.rowClasses: if not issubclass(rc, RowObject): raise DBError("Stub class (%s) is not derived from RowObject" % reflect.qual(rc.rowClass)) self._populateSchemaFor(rc) self.populated = 1
def __getattr__(self, name): """ A getattr method to cause a class to be refreshed. """ if name == '__del__': raise AttributeError("Without this, Python segfaults.") updateInstance(self) log.msg("(rebuilding stale %s instance (%s))" % (reflect.qual(self.__class__), name)) result = getattr(self, name) return result
def _callProcessExited(self, reason): default = object() processExited = getattr(self.proto, 'processExited', default) if processExited is default: getWarningMethod()(_missingProcessExited % (qual(self.proto.__class__), ), DeprecationWarning, stacklevel=0) else: processExited(Failure(reason))
def writeSomeData(self, data): """ Write as much as possible of the given data, immediately. This is called to invoke the lower-level writing functionality, such as a socket's send() method, or a file's write(); this method returns an integer or an exception. If an integer, it is the number of bytes written (possibly zero); if an exception, it indicates the connection was lost. """ raise NotImplementedError("%s does not implement writeSomeData" % reflect.qual(self.__class__))
def check(self, *errorTypes): """Check if this failure's type is in a predetermined list. @type errorTypes: list of L{Exception} classes or fully-qualified class names. @returns: the matching L{Exception} type, or None if no match. """ for error in errorTypes: err = error if inspect.isclass(error) and issubclass(error, Exception): err = reflect.qual(error) if err in self.parents: return error return None
def __getstate__(self, dict=None): """Get state, adding a version number to it on its way out. """ dct = copy.copy(dict or self.__dict__) bases = _aybabtu(self.__class__) bases.reverse() bases.append(self.__class__) # don't forget me!! for base in bases: if base.__dict__.has_key('persistenceForgets'): for slot in base.persistenceForgets: if dct.has_key(slot): del dct[slot] if base.__dict__.has_key('persistenceVersion'): dct['%s.persistenceVersion' % reflect.qual(base)] = base.persistenceVersion return dct
def _makeContext(self): ctx = SSL.Context(self.method) if self.certificate is not None and self.privateKey is not None: ctx.use_certificate(self.certificate) ctx.use_privatekey(self.privateKey) # Sanity check ctx.check_privatekey() verifyFlags = SSL.VERIFY_NONE if self.verify: verifyFlags = SSL.VERIFY_PEER if self.requireCertificate: verifyFlags |= SSL.VERIFY_FAIL_IF_NO_PEER_CERT if self.verifyOnce: verifyFlags |= SSL.VERIFY_CLIENT_ONCE if self.caCerts: store = ctx.get_cert_store() for cert in self.caCerts: store.add_cert(cert) # It'd be nice if pyOpenSSL let us pass None here for this behavior (as # the underlying OpenSSL API call allows NULL to be passed). It # doesn't, so we'll supply a function which does the same thing. def _verifyCallback(conn, cert, errno, depth, preverify_ok): return preverify_ok ctx.set_verify(verifyFlags, _verifyCallback) if self.verifyDepth is not None: ctx.set_verify_depth(self.verifyDepth) if self.enableSingleUseKeys: ctx.set_options(SSL.OP_SINGLE_DH_USE) if self.fixBrokenPeers: ctx.set_options(self._OP_ALL) if self.enableSessions: sessionName = md5( "%s-%d" % (reflect.qual(self.__class__), _sessionCounter())).hexdigest() ctx.set_session_id(sessionName) if not self.enableSessionTickets: ctx.set_options(self._OP_NO_TICKET) return ctx
def _makeContext(self): ctx = SSL.Context(self.method) if self.certificate is not None and self.privateKey is not None: ctx.use_certificate(self.certificate) ctx.use_privatekey(self.privateKey) # Sanity check ctx.check_privatekey() verifyFlags = SSL.VERIFY_NONE if self.verify: verifyFlags = SSL.VERIFY_PEER if self.requireCertificate: verifyFlags |= SSL.VERIFY_FAIL_IF_NO_PEER_CERT if self.verifyOnce: verifyFlags |= SSL.VERIFY_CLIENT_ONCE if self.caCerts: store = ctx.get_cert_store() for cert in self.caCerts: store.add_cert(cert) # It'd be nice if pyOpenSSL let us pass None here for this behavior (as # the underlying OpenSSL API call allows NULL to be passed). It # doesn't, so we'll supply a function which does the same thing. def _verifyCallback(conn, cert, errno, depth, preverify_ok): return preverify_ok ctx.set_verify(verifyFlags, _verifyCallback) if self.verifyDepth is not None: ctx.set_verify_depth(self.verifyDepth) if self.enableSingleUseKeys: ctx.set_options(SSL.OP_SINGLE_DH_USE) if self.fixBrokenPeers: ctx.set_options(self._OP_ALL) if self.enableSessions: sessionName = md5("%s-%d" % (reflect.qual(self.__class__), _sessionCounter())).hexdigest() ctx.set_session_id(sessionName) if not self.enableSessionTickets: ctx.set_options(self._OP_NO_TICKET) return ctx
def showwarning(self, message, category, filename, lineno, file=None, line=None): """ Twisted-enabled wrapper around L{warnings.showwarning}. If C{file} is C{None}, the default behaviour is to emit the warning to the log system, otherwise the original L{warnings.showwarning} Python function is called. """ if file is None: self.msg(warning=message, category=reflect.qual(category), filename=filename, lineno=lineno, format="%(filename)s:%(lineno)s: %(category)s: %(warning)s") else: if sys.version_info < (2, 6): _oldshowwarning(message, category, filename, lineno, file) else: _oldshowwarning(message, category, filename, lineno, file, line)
def addComponent(self, component, ignoreClass=0): """ Add a component to me, for all appropriate interfaces. In order to determine which interfaces are appropriate, the component's provided interfaces will be scanned. If the argument 'ignoreClass' is True, then all interfaces are considered appropriate. Otherwise, an 'appropriate' interface is one for which its class has been registered as an adapter for my class according to the rules of getComponent. @return: the list of appropriate interfaces """ for iface in declarations.providedBy(component): if (ignoreClass or (self.locateAdapterClass( self.__class__, iface, None) == component.__class__)): self._adapterCache[reflect.qual(iface)] = component
def addComponent(self, component, ignoreClass=0): """ Add a component to me, for all appropriate interfaces. In order to determine which interfaces are appropriate, the component's provided interfaces will be scanned. If the argument 'ignoreClass' is True, then all interfaces are considered appropriate. Otherwise, an 'appropriate' interface is one for which its class has been registered as an adapter for my class according to the rules of getComponent. @return: the list of appropriate interfaces """ for iface in declarations.providedBy(component): if (ignoreClass or (self.locateAdapterClass(self.__class__, iface, None) == component.__class__)): self._adapterCache[reflect.qual(iface)] = component
def doIteration(self, delay): """ Do one iteration over the readers and writers which have been added. """ raise NotImplementedError( reflect.qual(self.__class__) + " did not implement doIteration")
def installWaker(self): raise NotImplementedError( reflect.qual(self.__class__) + " did not implement installWaker")
def removeWriter(self, writer): raise NotImplementedError(reflect.qual(self.__class__) + " did not implement removeWriter")
def doIteration(self, delay): """ Do one iteration over the readers and writers which have been added. """ raise NotImplementedError(reflect.qual(self.__class__) + " did not implement doIteration")
def jellyFor(self, jellier): return reflect.qual(PBMind), jellier.invoker.registerReference(self)
def removeAll(self): raise NotImplementedError( reflect.qual(self.__class__) + " did not implement removeAll")
def jellyToAO(self, obj): """I turn an object into an AOT and return it.""" objType = type(obj) self.stack.append(repr(obj)) #immutable: We don't care if these have multiple refs! if objType in _SIMPLE_BUILTINS: retval = obj elif objType is types.MethodType: # TODO: make methods 'prefer' not to jelly the object internally, # so that the object will show up where it's referenced first NOT # by a method. retval = InstanceMethod(obj.im_func.__name__, reflect.qual(obj.im_class), self.jellyToAO(obj.im_self)) elif objType is types.ModuleType: retval = Module(obj.__name__) elif objType is types.ClassType: retval = Class(reflect.qual(obj)) elif issubclass(objType, type): retval = Class(reflect.qual(obj)) elif objType is types.FunctionType: retval = Function(reflect.fullFuncName(obj)) else: #mutable! gotta watch for refs. #Marmalade had the nicety of being able to just stick a 'reference' attribute #on any Node object that was referenced, but in AOT, the referenced object #is *inside* of a Ref call (Ref(num, obj) instead of #<objtype ... reference="1">). The problem is, especially for built-in types, #I can't just assign some attribute to them to give them a refnum. So, I have #to "wrap" a Ref(..) around them later -- that's why I put *everything* that's #mutable inside one. The Ref() class will only print the "Ref(..)" around an #object if it has a Reference explicitly attached. if self.prepared.has_key(id(obj)): oldRef = self.prepared[id(obj)] if oldRef.refnum: # it's been referenced already key = oldRef.refnum else: # it hasn't been referenced yet self._ref_id = self._ref_id + 1 key = self._ref_id oldRef.setRef(key) return Deref(key) retval = Ref() self.prepareForRef(retval, obj) if objType is types.ListType: retval.setObj(map(self.jellyToAO, obj)) #hah! elif objType is types.TupleType: retval.setObj(tuple(map(self.jellyToAO, obj))) elif objType is types.DictionaryType: d = {} for k,v in obj.items(): d[self.jellyToAO(k)] = self.jellyToAO(v) retval.setObj(d) elif objType is types.InstanceType: if hasattr(obj, "__getstate__"): state = self.jellyToAO(obj.__getstate__()) else: state = self.jellyToAO(obj.__dict__) retval.setObj(Instance(reflect.qual(obj.__class__), state)) elif copy_reg.dispatch_table.has_key(objType): unpickleFunc, state = copy_reg.dispatch_table[objType](obj) retval.setObj(Copyreg( reflect.fullFuncName(unpickleFunc), self.jellyToAO(state))) else: raise TypeError("Unsupported type: %s" % objType.__name__) del self.stack[-1] return retval
def jellyFor(self, jellier): return reflect.qual(self.__class__), jellier.invoker.registerReference(self)
def __init__(self, exc_value=None, exc_type=None, exc_tb=None): """ Initialize me with an explanation of the error. By default, this will use the current C{exception} (L{sys.exc_info}()). However, if you want to specify a particular kind of failure, you can pass an exception as an argument. If no C{exc_value} is passed, then an "original" C{Failure} will be searched for. If the current exception handler that this C{Failure} is being constructed in is handling an exception raised by L{raiseException}, then this C{Failure} will act like the original C{Failure}. For C{exc_tb} only L{traceback} instances or C{None} are allowed. If C{None} is supplied for C{exc_value}, the value of C{exc_tb} is ignored, otherwise if C{exc_tb} is C{None}, it will be found from execution context (ie, L{sys.exc_info}). """ global count count = count + 1 self.count = count self.type = self.value = tb = None #strings Exceptions/Failures are bad, mmkay? if isinstance(exc_value, (str, unicode)) and exc_type is None: import warnings warnings.warn( "Don't pass strings (like %r) to failure.Failure (replacing with a DefaultException)." % exc_value, DeprecationWarning, stacklevel=2) exc_value = DefaultException(exc_value) stackOffset = 0 if exc_value is None: exc_value = self._findFailure() if exc_value is None: self.type, self.value, tb = sys.exc_info() if self.type is None: raise NoCurrentExceptionError() stackOffset = 1 elif exc_type is None: if isinstance(exc_value, Exception): self.type = exc_value.__class__ else: #allow arbitrary objects. self.type = type(exc_value) self.value = exc_value else: self.type = exc_type self.value = exc_value if isinstance(self.value, Failure): self.__dict__ = self.value.__dict__ return if tb is None: if exc_tb: tb = exc_tb # else: # log.msg("Erf, %r created with no traceback, %s %s." % ( # repr(self), repr(exc_value), repr(exc_type))) # for s in traceback.format_stack(): # log.msg(s) frames = self.frames = [] stack = self.stack = [] # added 2003-06-23 by Chris Armstrong. Yes, I actually have a # use case where I need this traceback object, and I've made # sure that it'll be cleaned up. self.tb = tb if tb: f = tb.tb_frame elif not isinstance(self.value, Failure): # we don't do frame introspection since it's expensive, # and if we were passed a plain exception with no # traceback, it's not useful anyway f = stackOffset = None while stackOffset and f: # This excludes this Failure.__init__ frame from the # stack, leaving it to start with our caller instead. f = f.f_back stackOffset -= 1 # Keeps the *full* stack. Formerly in spread.pb.print_excFullStack: # # The need for this function arises from the fact that several # PB classes have the peculiar habit of discarding exceptions # with bareword "except:"s. This premature exception # catching means tracebacks generated here don't tend to show # what called upon the PB object. while f: localz = f.f_locals.copy() if f.f_locals is f.f_globals: globalz = {} else: globalz = f.f_globals.copy() for d in globalz, localz: if d.has_key("__builtins__"): del d["__builtins__"] stack.insert(0, [ f.f_code.co_name, f.f_code.co_filename, f.f_lineno, localz.items(), globalz.items(), ]) f = f.f_back while tb is not None: f = tb.tb_frame localz = f.f_locals.copy() if f.f_locals is f.f_globals: globalz = {} else: globalz = f.f_globals.copy() for d in globalz, localz: if d.has_key("__builtins__"): del d["__builtins__"] frames.append([ f.f_code.co_name, f.f_code.co_filename, tb.tb_lineno, localz.items(), globalz.items(), ]) tb = tb.tb_next if inspect.isclass(self.type) and issubclass(self.type, Exception): parentCs = reflect.allYourBase(self.type) self.parents = map(reflect.qual, parentCs) self.parents.append(reflect.qual(self.type)) else: self.parents = [self.type]
def setLogStr(self): self.logstr = reflect.qual(self.protocol.__class__) + " (UDP)"
def printTraceback(self, file=None, elideFrameworkCode=False, detail='default'): """ Emulate Python's standard error reporting mechanism. @param file: If specified, a file-like object to which to write the traceback. @param elideFrameworkCode: A flag indicating whether to attempt to remove uninteresting frames from within Twisted itself from the output. @param detail: A string indicating how much information to include in the traceback. Must be one of C{'brief'}, C{'default'}, or C{'verbose'}. """ if file is None: file = log.logerr w = file.write # Preamble if detail == 'verbose': w( '*--- Failure #%d%s---\n' % (self.count, (self.pickled and ' (pickled) ') or ' ')) elif detail == 'brief': if self.frames: hasFrames = 'Traceback' else: hasFrames = 'Traceback (failure with no frames)' w("%s: %s: %s\n" % ( hasFrames, reflect.safe_str(self.type), reflect.safe_str(self.value))) else: w( 'Traceback (most recent call last):\n') # Frames, formatted in appropriate style if self.frames: if not elideFrameworkCode: format_frames(self.stack[-traceupLength:], w, detail) w("%s\n" % (EXCEPTION_CAUGHT_HERE,)) format_frames(self.frames, w, detail) elif not detail == 'brief': # Yeah, it's not really a traceback, despite looking like one... w("Failure: ") # postamble, if any if not detail == 'brief': # Unfortunately, self.type will not be a class object if this # Failure was created implicitly from a string exception. # qual() doesn't make any sense on a string, so check for this # case here and just write out the string if that's what we # have. if isinstance(self.type, (str, unicode)): w(self.type + "\n") else: w("%s: %s\n" % (reflect.qual(self.type), reflect.safe_str(self.value))) # chaining if isinstance(self.value, Failure): # TODO: indentation for chained failures? file.write(" (chained Failure)\n") self.value.printTraceback(file, elideFrameworkCode, detail) if detail == 'verbose': w('*--- End of Failure #%d ---\n' % self.count)
def addReader(self, reader): raise NotImplementedError( reflect.qual(self.__class__) + " did not implement addReader")
def jellyFor(self, jellier): return reflect.qual(self.__class__), self.group.name.encode('utf-8'), jellier.invoker.registerReference(self)
def removeWriter(self, writer): raise NotImplementedError( reflect.qual(self.__class__) + " did not implement removeWriter")
def getWriters(self): raise NotImplementedError(reflect.qual(self.__class__) + " did not implement getWriters")
def getWriters(self): raise NotImplementedError( reflect.qual(self.__class__) + " did not implement getWriters")
def removeAll(self): raise NotImplementedError(reflect.qual(self.__class__) + " did not implement removeAll")
def addReader(self, reader): raise NotImplementedError(reflect.qual(self.__class__) + " did not implement addReader")
def getDestination(self): raise NotImplementedError( reflect.qual(self.__class__) + " did not implement " "getDestination")
def rebuild(module, doLog=1): """ Reload a module and do as much as possible to replace its references. """ global lastRebuild lastRebuild = time.time() if hasattr(module, 'ALLOW_TWISTED_REBUILD'): # Is this module allowed to be rebuilt? if not module.ALLOW_TWISTED_REBUILD: raise RuntimeError("I am not allowed to be rebuilt.") if doLog: log.msg('Rebuilding %s...' % str(module.__name__)) ## Safely handle adapter re-registration from lib.twisted.python import components components.ALLOW_DUPLICATES = True d = module.__dict__ _modDictIDMap[id(d)] = module newclasses = {} classes = {} functions = {} values = {} if doLog: log.msg(' (scanning %s): ' % str(module.__name__)) for k, v in d.items(): if type(v) == types.ClassType: # Failure condition -- instances of classes with buggy # __hash__/__cmp__ methods referenced at the module level... if v.__module__ == module.__name__: classes[v] = 1 if doLog: log.logfile.write("c") log.logfile.flush() elif type(v) == types.FunctionType: if v.func_globals is module.__dict__: functions[v] = 1 if doLog: log.logfile.write("f") log.logfile.flush() elif isinstance(v, type): if v.__module__ == module.__name__: newclasses[v] = 1 if doLog: log.logfile.write("o") log.logfile.flush() values.update(classes) values.update(functions) fromOldModule = values.has_key newclasses = newclasses.keys() classes = classes.keys() functions = functions.keys() if doLog: log.msg('') log.msg(' (reload %s)' % str(module.__name__)) # Boom. reload(module) # Make sure that my traceback printing will at least be recent... linecache.clearcache() if doLog: log.msg(' (cleaning %s): ' % str(module.__name__)) for clazz in classes: if getattr(module, clazz.__name__) is clazz: log.msg("WARNING: class %s not replaced by reload!" % reflect.qual(clazz)) else: if doLog: log.logfile.write("x") log.logfile.flush() clazz.__bases__ = () clazz.__dict__.clear() clazz.__getattr__ = __getattr__ clazz.__module__ = module.__name__ if newclasses: import gc for nclass in newclasses: ga = getattr(module, nclass.__name__) if ga is nclass: log.msg("WARNING: new-class %s not replaced by reload!" % reflect.qual(nclass)) else: for r in gc.get_referrers(nclass): if getattr(r, '__class__', None) is nclass: r.__class__ = ga if doLog: log.msg('') log.msg(' (fixing %s): ' % str(module.__name__)) modcount = 0 for mk, mod in sys.modules.items(): modcount = modcount + 1 if mod == module or mod is None: continue if not hasattr(mod, '__file__'): # It's a builtin module; nothing to replace here. continue if hasattr(mod, '__bundle__'): # PyObjC has a few buggy objects which segfault if you hash() them. # It doesn't make sense to try rebuilding extension modules like # this anyway, so don't try. continue changed = 0 for k, v in mod.__dict__.items(): try: hash(v) except Exception: continue if fromOldModule(v): if type(v) == types.ClassType: if doLog: log.logfile.write("c") log.logfile.flush() nv = latestClass(v) else: if doLog: log.logfile.write("f") log.logfile.flush() nv = latestFunction(v) changed = 1 setattr(mod, k, nv) else: # Replace bases of non-module classes just to be sure. if type(v) == types.ClassType: for base in v.__bases__: if fromOldModule(base): latestClass(v) if doLog and not changed and ((modcount % 10) ==0) : log.logfile.write(".") log.logfile.flush() components.ALLOW_DUPLICATES = False if doLog: log.msg('') log.msg(' Rebuilt %s.' % str(module.__name__)) return module
def doWrite(self): """Raises a RuntimeError""" raise RuntimeError, "doWrite called on a %s" % reflect.qual(self.__class__)
def __repr__(self): protocolName = reflect.qual(self.protocol.__class__,) if hasattr(self, 'socket'): return '<%s on %r>' % (protocolName, self.port) else: return '<%s (not listening)>' % (protocolName,)
def logPrefix(self): """ Returns the name of my class, to prefix log entries with. """ return reflect.qual(self.factory.__class__)
def printTraceback(self, file=None, elideFrameworkCode=False, detail='default'): """ Emulate Python's standard error reporting mechanism. @param file: If specified, a file-like object to which to write the traceback. @param elideFrameworkCode: A flag indicating whether to attempt to remove uninteresting frames from within Twisted itself from the output. @param detail: A string indicating how much information to include in the traceback. Must be one of C{'brief'}, C{'default'}, or C{'verbose'}. """ if file is None: file = log.logerr w = file.write # Preamble if detail == 'verbose': w('*--- Failure #%d%s---\n' % (self.count, (self.pickled and ' (pickled) ') or ' ')) elif detail == 'brief': if self.frames: hasFrames = 'Traceback' else: hasFrames = 'Traceback (failure with no frames)' w("%s: %s: %s\n" % (hasFrames, reflect.safe_str( self.type), reflect.safe_str(self.value))) else: w('Traceback (most recent call last):\n') # Frames, formatted in appropriate style if self.frames: if not elideFrameworkCode: format_frames(self.stack[-traceupLength:], w, detail) w("%s\n" % (EXCEPTION_CAUGHT_HERE, )) format_frames(self.frames, w, detail) elif not detail == 'brief': # Yeah, it's not really a traceback, despite looking like one... w("Failure: ") # postamble, if any if not detail == 'brief': # Unfortunately, self.type will not be a class object if this # Failure was created implicitly from a string exception. # qual() doesn't make any sense on a string, so check for this # case here and just write out the string if that's what we # have. if isinstance(self.type, (str, unicode)): w(self.type + "\n") else: w("%s: %s\n" % (reflect.qual(self.type), reflect.safe_str(self.value))) # chaining if isinstance(self.value, Failure): # TODO: indentation for chained failures? file.write(" (chained Failure)\n") self.value.printTraceback(file, elideFrameworkCode, detail) if detail == 'verbose': w('*--- End of Failure #%d ---\n' % self.count)
def __repr__(self): factoryName = reflect.qual(self.factory.__class__) if hasattr(self, 'socket'): return '<%s on %r>' % (factoryName, self.port) else: return '<%s (not listening)>' % (factoryName,)