def resolve_artifact_names(fn): """Decorator, augment function globals with tables and classes. Swaps out the function's globals at execution time. The 'global' statement will not work as expected inside a decorated function. """ # This could be automatically applied to framework and test_ methods in # the MappedTest-derived test suites but... *some* explicitness for this # magic is probably good. Especially as 'global' won't work- these # rebound functions aren't regular Python.. # # Also: it's lame that CPython accepts a dict-subclass for globals, but # only calls dict methods. That would allow 'global' to pass through to # the func_globals. def resolved(*args, **kwargs): self = args[0] context = dict(fn.func_globals) for source in self._artifact_registries: context.update(getattr(self, source)) # jython bug #1034 rebound = types.FunctionType(fn.func_code, context, fn.func_name, fn.func_defaults, fn.func_closure) return rebound(*args, **kwargs) return _function_named(resolved, fn.func_name)
def decorator(fn): def profiled(*args, **kw): if (target not in profile_config['targets'] and not target_opts.get('always', None)): return fn(*args, **kw) elapsed, load_stats, result = _profile(filename, fn, *args, **kw) if not testlib.config.options.quiet: print "Profiled target '%s', wall time: %.2f seconds" % ( target, elapsed) report = target_opts.get('report', profile_config['report']) if report and testlib.config.options.verbose: sort_ = target_opts.get('sort', profile_config['sort']) limit = target_opts.get('limit', profile_config['limit']) print "Profile report for target '%s' (%s)" % (target, filename) stats = load_stats() stats.sort_stats(*sort_) if limit: stats.print_stats(limit) else: stats.print_stats() #stats.print_callers() os.unlink(filename) return result return _function_named(profiled, fn.__name__)
def assert_conns_closed(fn): def decorated(*args, **kw): try: fn(*args, **kw) finally: testing_reaper.assert_all_closed() return _function_named(decorated, fn.__name__)
def decorator(fn): def counted(*args, **kw): try: filename = "%s.prof" % fn.__name__ elapsed, stat_loader, result = _profile( filename, fn, *args, **kw) stats = stat_loader() calls = stats.total_calls if testlib.config.options.verbose: stats.sort_stats('calls', 'cumulative') stats.print_stats() #stats.print_callers() deviance = int(count * variance) if (calls < (count - deviance) or calls > (count + deviance)): raise AssertionError( "Function call count %s not within %s%% " "of expected %s. (Python version %s)" % (calls, (variance * 100), count, py_version)) return result finally: if os.path.exists(filename): os.unlink(filename) return _function_named(counted, fn.__name__)
def decorate(fn): def safe(*args, **kw): global sa_exc if sa_exc is None: import sqlalchemy.exc as sa_exc # todo: should probably be strict about this, too filters = [ dict(action='ignore', category=sa_exc.SAPendingDeprecationWarning) ] if not messages: filters.append( dict(action='ignore', category=sa_exc.SADeprecationWarning)) else: filters.extend([ dict(action='ignore', message=message, category=sa_exc.SADeprecationWarning) for message in [(m.startswith('//') and ( 'Call to deprecated function ' + m[2:]) or m) for m in messages] ]) for f in filters: warnings.filterwarnings(**f) try: return fn(*args, **kw) finally: resetwarnings() return _function_named(safe, fn.__name__)
def decorator(fn): def profiled(*args, **kw): if (target not in profile_config['targets'] and not target_opts.get('always', None)): return fn(*args, **kw) elapsed, load_stats, result = _profile( filename, fn, *args, **kw) if not testlib.config.options.quiet: print "Profiled target '%s', wall time: %.2f seconds" % ( target, elapsed) report = target_opts.get('report', profile_config['report']) if report and testlib.config.options.verbose: sort_ = target_opts.get('sort', profile_config['sort']) limit = target_opts.get('limit', profile_config['limit']) print "Profile report for target '%s' (%s)" % ( target, filename) stats = load_stats() stats.sort_stats(*sort_) if limit: stats.print_stats(limit) else: stats.print_stats() #stats.print_callers() os.unlink(filename) return result return _function_named(profiled, fn.__name__)
def decorate(fn): def safe(*args, **kw): global sa_exc if sa_exc is None: import sqlalchemy.exc as sa_exc # todo: should probably be strict about this, too filters = [dict(action="ignore", category=sa_exc.SAPendingDeprecationWarning)] if not messages: filters.append(dict(action="ignore", category=sa_exc.SADeprecationWarning)) else: filters.extend( [ dict(action="ignore", message=message, category=sa_exc.SADeprecationWarning) for message in [ (m.startswith("//") and ("Call to deprecated function " + m[2:]) or m) for m in messages ] ] ) for f in filters: warnings.filterwarnings(**f) try: return fn(*args, **kw) finally: resetwarnings() return _function_named(safe, fn.__name__)
def decorator(fn): def counted(*args, **kw): try: filename = "%s.prof" % fn.__name__ elapsed, stat_loader, result = _profile( filename, fn, *args, **kw) stats = stat_loader() calls = stats.total_calls if testlib.config.options.verbose: stats.sort_stats('calls', 'cumulative') stats.print_stats() #stats.print_callers() deviance = int(count * variance) if (calls < (count - deviance) or calls > (count + deviance)): raise AssertionError( "Function call count %s not within %s%% " "of expected %s. (Python version %s)" % ( calls, (variance * 100), count, py_version)) return result finally: if os.path.exists(filename): os.unlink(filename) return _function_named(counted, fn.__name__)
def decorate(fn): def wrapped(*args, **kw): try: attributes._install_lookup_strategy(strategy) return fn(*args, **kw) finally: attributes._install_lookup_strategy(sa.util.symbol('native')) return _function_named(wrapped, fn.func_name)
def close_open_connections(fn): """Decorator that closes all connections after fn execution.""" def decorated(*args, **kw): try: fn(*args, **kw) finally: testing_reaper.close_all() return _function_named(decorated, fn.__name__)
def rollback_open_connections(fn): """Decorator that rolls back all open connections after fn execution.""" def decorated(*args, **kw): try: fn(*args, **kw) finally: testing_reaper.rollback_all() return _function_named(decorated, fn.__name__)
def modifies_instrumentation_finders(fn): def decorated(*args, **kw): pristine = attributes.instrumentation_finders[:] try: fn(*args, **kw) finally: del attributes.instrumentation_finders[:] attributes.instrumentation_finders.extend(pristine) return _function_named(decorated, fn.func_name)
def decorator(fn): def at_runtime(*args, **kw): criteria = categories.get(discriminator(), None) if criteria is None: return fn(*args, **kw) rewrapped = function_call_count(*criteria)(fn) return rewrapped(*args, **kw) return _function_named(at_runtime, fn.__name__)
def decorate(fn): def wrapped(*args, **kw): current = attributes._lookup_strategy try: attributes._install_lookup_strategy(strategy) return fn(*args, **kw) finally: attributes._install_lookup_strategy(current) return _function_named(wrapped, fn.func_name)
def decorate(fn): fn_name = fn.__name__ def maybe(*args, **kw): if predicate(): msg = "'%s' skipped on DB %s version '%s': %s" % ( fn_name, config.db.name, _server_version(), reason) print msg return True else: return fn(*args, **kw) return _function_named(maybe, fn_name)
def decorate(fn): fn_name = fn.__name__ def maybe(*args, **kw): if spec(config.db): msg = "'%s' unsupported on DB implementation '%s+%s': %s" % ( fn_name, config.db.name, config.db.driver, reason) print msg if carp: print >> sys.stderr, msg return True else: return fn(*args, **kw) return _function_named(maybe, fn_name)
def decorate(fn): fn_name = fn.__name__ def maybe(*args, **kw): if _is_excluded(db, op, spec): msg = "'%s' unsupported on DB %s version '%s': %s" % ( fn_name, config.db.name, _server_version(), reason) print msg if carp: print >> sys.stderr, msg return True else: return fn(*args, **kw) return _function_named(maybe, fn_name)
def decorate(fn): fn_name = fn.__name__ def maybe(*args, **kw): if config.db.name == db: msg = "'%s' unsupported on DB implementation '%s': %s" % ( fn_name, config.db.name, reason) print msg if carp: print >> sys.stderr, msg return True else: return fn(*args, **kw) return _function_named(maybe, fn_name)
def decorate(fn): def maybe(*args, **kw): if isinstance(db, basestring): if not spec(config.db): return fn(*args, **kw) else: wrapped = emits_warning(*warnings)(fn) return wrapped(*args, **kw) else: if not _is_excluded(*db): return fn(*args, **kw) else: wrapped = emits_warning(*warnings)(fn) return wrapped(*args, **kw) return _function_named(maybe, fn.__name__)
def decorate(fn): def maybe(*args, **kw): if isinstance(db, basestring): if config.db.name != db: return fn(*args, **kw) else: wrapped = emits_warning(*warnings)(fn) return wrapped(*args, **kw) else: if not _is_excluded(*db): return fn(*args, **kw) else: wrapped = emits_warning(*warnings)(fn) return wrapped(*args, **kw) return _function_named(maybe, fn.__name__)
def create_backref_test(autoflush, saveuser): @testing.resolve_artifact_names def test_backref(self): mapper(User, users, properties={ 'addresses': dynamic_loader(mapper(Address, addresses), backref='user') }) sess = create_session(autoflush=autoflush) u = User(name='buffy') a = Address(email_address='*****@*****.**') a.user = u if saveuser: sess.add(u) else: sess.add(a) if not autoflush: sess.flush() assert u in sess assert a in sess self.assert_(list(u.addresses) == [a]) a.user = None if not autoflush: self.assert_(list(u.addresses) == [a]) if not autoflush: sess.flush() self.assert_(list(u.addresses) == []) test_backref = _function_named( test_backref, "test%s%s" % ((autoflush and "_autoflush" or ""), (saveuser and "_saveuser" or "_savead"))) setattr(FlushTest, test_backref.__name__, test_backref)
def create_backref_test(autoflush, saveuser): @testing.resolve_artifact_names def test_backref(self): mapper(User, users, properties={ 'addresses':dynamic_loader(mapper(Address, addresses), backref='user') }) sess = create_session(autoflush=autoflush) u = User(name='buffy') a = Address(email_address='*****@*****.**') a.user = u if saveuser: sess.add(u) else: sess.add(a) if not autoflush: sess.flush() assert u in sess assert a in sess self.assert_(list(u.addresses) == [a]) a.user = None if not autoflush: self.assert_(list(u.addresses) == [a]) if not autoflush: sess.flush() self.assert_(list(u.addresses) == []) test_backref = _function_named( test_backref, "test%s%s" % ((autoflush and "_autoflush" or ""), (saveuser and "_saveuser" or "_savead"))) setattr(FlushTest, test_backref.__name__, test_backref)
def maybe(*args, **kw): if not callable_(): return fn(*args, **kw) else: try: fn(*args, **kw) except Exception, ex: print("'%s' failed as expected (condition: %s): %s " % (fn_name, description, str(ex))) return True else: raise AssertionError( "Unexpected success for '%s' (condition: %s)" % (fn_name, description)) return _function_named(maybe, fn_name) return decorate def future(fn): """Mark a test as expected to unconditionally fail. Takes no arguments, omit parens when using as a decorator. """ fn_name = fn.__name__ def decorated(*args, **kw): try: fn(*args, **kw)
def decorate(fn): fn_name = fn.__name__ def maybe(*args, **kw): if not callable_(): return fn(*args, **kw) else: try: fn(*args, **kw) except Exception, ex: print ("'%s' failed as expected (condition: %s): %s " % (fn_name, description, str(ex))) return True else: raise AssertionError("Unexpected success for '%s' (condition: %s)" % (fn_name, description)) return _function_named(maybe, fn_name) return decorate def future(fn): """Mark a test as expected to unconditionally fail. Takes no arguments, omit parens when using as a decorator. """ fn_name = fn.__name__ def decorated(*args, **kw): try: fn(*args, **kw)