def latestClass(oldClass): """ Get the latest version of a class. """ module = reflect.namedModule(oldClass.__module__) newClass = getattr(module, oldClass.__name__) newBases = [latestClass(base) for base in newClass.__bases__] try: # This makes old-style stuff work newClass.__bases__ = tuple(newBases) return newClass except TypeError: if newClass.__module__ == "__builtin__": # __builtin__ members can't be reloaded sanely return newClass ctor = getattr(newClass, '__metaclass__', type) return ctor(newClass.__name__, tuple(newBases), dict(newClass.__dict__))
def unjellyAO(self, ao): """Unjelly an Abstract Object and everything it contains. I return the real object. """ self.stack.append(ao) t = type(ao) if t is types.InstanceType: #Abstract Objects c = ao.__class__ if c is Module: return reflect.namedModule(ao.name) elif c in [Class, Function] or issubclass(c, type): return reflect.namedObject(ao.name) elif c is InstanceMethod: im_name = ao.name im_class = reflect.namedObject(ao.klass) im_self = self.unjellyAO(ao.instance) if im_name in im_class.__dict__: if im_self is None: return getattr(im_class, im_name) elif isinstance(im_self, crefutil.NotKnown): return crefutil._InstanceMethod(im_name, im_self, im_class) else: return new.instancemethod(im_class.__dict__[im_name], im_self, im_class) else: raise TypeError("instance method changed") elif c is Instance: klass = reflect.namedObject(ao.klass) state = self.unjellyAO(ao.state) if hasattr(klass, "__setstate__"): inst = new.instance(klass, {}) self.callAfter(inst.__setstate__, state) else: inst = new.instance(klass, state) return inst elif c is Ref: o = self.unjellyAO(ao.obj) #THIS IS CHANGING THE REF OMG refkey = ao.refnum ref = self.references.get(refkey) if ref is None: self.references[refkey] = o elif isinstance(ref, crefutil.NotKnown): ref.resolveDependants(o) self.references[refkey] = o elif refkey is None: # This happens when you're unjellying from an AOT not read from source pass else: raise ValueError("Multiple references with the same ID: %s, %s, %s!" % (ref, refkey, ao)) return o elif c is Deref: num = ao.refnum ref = self.references.get(num) if ref is None: der = crefutil._Dereference(num) self.references[num] = der return der return ref elif c is Copyreg: loadfunc = reflect.namedObject(ao.loadfunc) d = self.unjellyLater(ao.state).addCallback( lambda result, _l: apply(_l, result), loadfunc) return d #Types elif t in _SIMPLE_BUILTINS: return ao elif t is types.ListType: l = [] for x in ao: l.append(None) self.unjellyInto(l, len(l)-1, x) return l elif t is types.TupleType: l = [] tuple_ = tuple for x in ao: l.append(None) if isinstance(self.unjellyInto(l, len(l)-1, x), crefutil.NotKnown): tuple_ = crefutil._Tuple return tuple_(l) elif t is types.DictType: d = {} for k,v in ao.items(): kvd = crefutil._DictKeyAndValue(d) self.unjellyInto(kvd, 0, k) self.unjellyInto(kvd, 1, v) return d else: raise TypeError("Unsupported AOT type: %s" % t) del self.stack[-1]
def __init__(self, dbapiName, *connargs, **connkw): """Create a new ConnectionPool. Any positional or keyword arguments other than those documented here are passed to the DB-API object when connecting. Use these arguments to pass database names, usernames, passwords, etc. @param dbapiName: an import string to use to obtain a DB-API compatible module (e.g. 'pyPgSQL.PgSQL') @param cp_min: the minimum number of connections in pool (default 3) @param cp_max: the maximum number of connections in pool (default 5) @param cp_noisy: generate informational log messages during operation (default False) @param cp_openfun: a callback invoked after every connect() on the underlying DB-API object. The callback is passed a new DB-API connection object. This callback can setup per-connection state such as charset, timezone, etc. @param cp_reconnect: detect connections which have failed and reconnect (default False). Failed connections may result in ConnectionLost exceptions, which indicate the query may need to be re-sent. @param cp_good_sql: an sql query which should always succeed and change no state (default 'select 1') @param cp_reactor: use this reactor instead of the global reactor (added in Twisted 10.2). @type cp_reactor: L{IReactorCore} provider """ self.dbapiName = dbapiName self.dbapi = reflect.namedModule(dbapiName) if getattr(self.dbapi, 'apilevel', None) != '2.0': log.msg('DB API module not DB API 2.0 compliant.') if getattr(self.dbapi, 'threadsafety', 0) < 1: log.msg('DB API module not sufficiently thread-safe.') reactor = connkw.pop('cp_reactor', None) if reactor is None: from lib.twisted.internet import reactor self._reactor = reactor self.connargs = connargs self.connkw = connkw for arg in self.CP_ARGS: cp_arg = 'cp_%s' % arg if connkw.has_key(cp_arg): setattr(self, arg, connkw[cp_arg]) del connkw[cp_arg] self.min = min(self.min, self.max) self.max = max(self.min, self.max) self.connections = {} # all connections, hashed on thread id # these are optional so import them here from lib.twisted.python import threadpool import thread self.threadID = thread.get_ident self.threadpool = threadpool.ThreadPool(self.min, self.max) self.startID = self._reactor.callWhenRunning(self._start)
def unjellyAO(self, ao): """Unjelly an Abstract Object and everything it contains. I return the real object. """ self.stack.append(ao) t = type(ao) if t is types.InstanceType: #Abstract Objects c = ao.__class__ if c is Module: return reflect.namedModule(ao.name) elif c in [Class, Function] or issubclass(c, type): return reflect.namedObject(ao.name) elif c is InstanceMethod: im_name = ao.name im_class = reflect.namedObject(ao.klass) im_self = self.unjellyAO(ao.instance) if im_name in im_class.__dict__: if im_self is None: return getattr(im_class, im_name) elif isinstance(im_self, crefutil.NotKnown): return crefutil._InstanceMethod( im_name, im_self, im_class) else: return new.instancemethod(im_class.__dict__[im_name], im_self, im_class) else: raise TypeError("instance method changed") elif c is Instance: klass = reflect.namedObject(ao.klass) state = self.unjellyAO(ao.state) if hasattr(klass, "__setstate__"): inst = new.instance(klass, {}) self.callAfter(inst.__setstate__, state) else: inst = new.instance(klass, state) return inst elif c is Ref: o = self.unjellyAO(ao.obj) #THIS IS CHANGING THE REF OMG refkey = ao.refnum ref = self.references.get(refkey) if ref is None: self.references[refkey] = o elif isinstance(ref, crefutil.NotKnown): ref.resolveDependants(o) self.references[refkey] = o elif refkey is None: # This happens when you're unjellying from an AOT not read from source pass else: raise ValueError( "Multiple references with the same ID: %s, %s, %s!" % (ref, refkey, ao)) return o elif c is Deref: num = ao.refnum ref = self.references.get(num) if ref is None: der = crefutil._Dereference(num) self.references[num] = der return der return ref elif c is Copyreg: loadfunc = reflect.namedObject(ao.loadfunc) d = self.unjellyLater(ao.state).addCallback( lambda result, _l: apply(_l, result), loadfunc) return d #Types elif t in _SIMPLE_BUILTINS: return ao elif t is types.ListType: l = [] for x in ao: l.append(None) self.unjellyInto(l, len(l) - 1, x) return l elif t is types.TupleType: l = [] tuple_ = tuple for x in ao: l.append(None) if isinstance(self.unjellyInto(l, len(l) - 1, x), crefutil.NotKnown): tuple_ = crefutil._Tuple return tuple_(l) elif t is types.DictType: d = {} for k, v in ao.items(): kvd = crefutil._DictKeyAndValue(d) self.unjellyInto(kvd, 0, k) self.unjellyInto(kvd, 1, v) return d else: raise TypeError("Unsupported AOT type: %s" % t) del self.stack[-1]