Example #1
0
    def getComponent(self, interface, registry=None, 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.
        """
        registry = getRegistry(registry)
        k = reflect.qual(interface)
        if self._adapterCache.has_key(k):
            return self._adapterCache[k]
        elif implements(self, interface):
            return self
        else:
            adapter = registry.getAdapter(self, interface, default,
                                          lambda k, ik, d:
                                          self.locateAdapterClass(k, ik, d, registry))
            if adapter is not None and adapter is not _Nothing and not (
                hasattr(adapter, "temporaryAdapter") and
                adapter.temporaryAdapter):
                self._adapterCache[k] = adapter
                if (hasattr(adapter, "multiComponent") and
                    adapter.multiComponent and
                    hasattr(adapter, '__implements__')):
                    self.addComponent(adapter)
            return adapter
Example #2
0
 def check(self, *errorTypes):
     for error in errorTypes:
         err = error
         if isinstance(error, types.ClassType) and issubclass(error, Exception):
             err = reflect.qual(error)
         if err in self.parents:
             return error
     return None
Example #3
0
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
Example #4
0
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
Example #5
0
    def printTraceback(self,
                       file=None,
                       elideFrameworkCode=0, detail='default'):
        """
        Emulate Python's standard error reporting mechanism.
        """
        if file is None:
            #file = log.logerr
            file = sys.stderr  # changed by teratorn
        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, self.type, 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)
Example #6
0
    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
Example #7
0
    def addComponent(self, component, ignoreClass=0, registry=None):
        """
        Add a component to me, for all appropriate interfaces.

        In order to determine which interfaces are appropriate, the component's
        __implements__ attribute 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 tupleTreeToList(component.__implements__):
            if (ignoreClass or
                (self.locateAdapterClass(self.__class__, iface, None, registry)
                 == component.__class__)):
                self._adapterCache[reflect.qual(iface)] = component
Example #8
0
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'):
        if not module.ALLOW_TWISTED_REBUILD:
            raise RuntimeError, "I am not allowed to be rebuilt."
    if doLog:
        log.msg( 'Rebuilding %s...' % str(module.__name__))
    from twisted.python import components
    components.ALLOW_DUPLICATES = 1
    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:
            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__))
    reload(module)
    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__'):
            continue
        changed = 0
        for k, v in mod.__dict__.items():
            try:
                hash(v)
            except TypeError:
                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:
                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 = 0
    if doLog:
        log.msg('')
        log.msg('   Rebuilt %s.' % str(module.__name__))
    return module
Example #9
0
 def upgradeToVersion1(self):
     # To let Componentized instances interact correctly with
     # rebuild(), we cannot use class objects as dictionary keys.
     for (k, v) in self._adapterCache.items():
         self._adapterCache[reflect.qual(k)] = v
Example #10
0
 def unsetComponent(self, interfaceClass):
     """Remove my component specified by the given interface class."""
     del self._adapterCache[reflect.qual(interfaceClass)]
Example #11
0
 def setComponent(self, interfaceClass, component):
     """
     """
     self._adapterCache[reflect.qual(interfaceClass)] = component
Example #12
0
    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 X{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" Failure will
        be searched for. If the current exception handler that this
        Failure is being constructed in is handling an exception
        raised by L{raiseException}, then this Failure will act like
        the original Failure.
        """
        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]
Example #13
0
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 twisted.python import components
    components.ALLOW_DUPLICATES = 1

    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
        changed = 0

        for k, v in mod.__dict__.items():
            try:
                hash(v)
            except TypeError:
                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 = 0
    if doLog:
        log.msg('')
        log.msg('   Rebuilt %s.' % str(module.__name__))
    return module
Example #14
0
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 twisted.python import components
    components.ALLOW_DUPLICATES = 1
    
    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 object and 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
        if (2, 2, 0) <= sys.version_info[:3] < (2, 2, 2):
            hasBrokenRebuild = 1
            gc_objects = gc.get_objects()
        else:
            hasBrokenRebuild = 0
    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:
            if hasBrokenRebuild:
                for r in gc_objects:
                    if not getattr(r, '__class__', None) is nclass:
                        continue
                    r.__class__ = ga
            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
        changed = 0

        for k, v in mod.__dict__.items():
            try:
                hash(v)
            except TypeError:
                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 = 0
    if doLog:
        log.msg('')
        log.msg('   Rebuilt %s.' % str(module.__name__))
    return module