diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-03-01 17:36:39 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-03-01 17:36:39 -0500 |
commit | 908368b2bdc1397b0ab6cfad12d6532e9c4ebd4e (patch) | |
tree | 3be6547d76ad13562851bfdb9801e97f6ad09c7e | |
parent | fa23570a338b53c813b6342fba0cacd4f5e61384 (diff) | |
download | sqlalchemy-908368b2bdc1397b0ab6cfad12d6532e9c4ebd4e.tar.gz |
- remove lots of old and unused nose options
- alter the plugin/requirements system to support multiple --db/--dburi
options. The first option serves as the "default" database, and the
subsequent ones serve as "available" databases. the requirement
rules at the *class level only* now search among the "available" databases
in order to run per-database test suites at once. rationale is to support
using the test plugin system under Alembic as well, which already
takes advantage of multiple database tests.
-rw-r--r-- | lib/sqlalchemy/testing/__init__.py | 8 | ||||
-rw-r--r-- | lib/sqlalchemy/testing/config.py | 7 | ||||
-rw-r--r-- | lib/sqlalchemy/testing/engines.py | 6 | ||||
-rw-r--r-- | lib/sqlalchemy/testing/exclusions.py | 49 | ||||
-rw-r--r-- | lib/sqlalchemy/testing/plugin/noseplugin.py | 293 | ||||
-rw-r--r-- | lib/sqlalchemy/testing/requirements.py | 29 | ||||
-rw-r--r-- | test/dialect/postgresql/test_compiler.py | 1 | ||||
-rw-r--r-- | test/dialect/postgresql/test_types.py | 1 | ||||
-rw-r--r-- | test/requirements.py | 24 |
9 files changed, 209 insertions, 209 deletions
diff --git a/lib/sqlalchemy/testing/__init__.py b/lib/sqlalchemy/testing/__init__.py index 8ad856e2b..61e0f5429 100644 --- a/lib/sqlalchemy/testing/__init__.py +++ b/lib/sqlalchemy/testing/__init__.py @@ -10,8 +10,12 @@ from .warnings import testing_warn, assert_warnings, resetwarnings from . import config from .exclusions import db_spec, _is_excluded, fails_if, skip_if, future,\ - fails_on, fails_on_everything_except, skip, only_on, exclude, against,\ - _server_version, only_if + fails_on, fails_on_everything_except, skip, only_on, exclude, \ + against as _against, _server_version, only_if + + +def against(*queries): + return _against(config._current, *queries) from .assertions import emits_warning, emits_warning_on, uses_deprecated, \ eq_, ne_, is_, is_not_, startswith_, assert_raises, \ diff --git a/lib/sqlalchemy/testing/config.py b/lib/sqlalchemy/testing/config.py index 64f578dab..c25355396 100644 --- a/lib/sqlalchemy/testing/config.py +++ b/lib/sqlalchemy/testing/config.py @@ -6,3 +6,10 @@ requirements = None db = None +dbs = {} +db_opts = None +_current = None +file_config = None + +def _unique_configs(): + return set(dbs.values())
\ No newline at end of file diff --git a/lib/sqlalchemy/testing/engines.py b/lib/sqlalchemy/testing/engines.py index d85771f8a..6da19d776 100644 --- a/lib/sqlalchemy/testing/engines.py +++ b/lib/sqlalchemy/testing/engines.py @@ -188,7 +188,7 @@ class ReconnectFixture(object): def reconnecting_engine(url=None, options=None): - url = url or config.db_url + url = url or config.db.url dbapi = config.db.dialect.dbapi if not options: options = {} @@ -216,7 +216,7 @@ def testing_engine(url=None, options=None): else: use_reaper = options.pop('use_reaper', True) - url = url or config.db_url + url = url or config.db.url if options is None: options = config.db_opts @@ -244,7 +244,7 @@ def utf8_engine(url=None, options=None): config.db.driver in ['mysqldb', 'pymysql', 'cymysql']: # note 1.2.1.gamma.6 or greater of MySQLdb # needed here - url = url or config.db_url + url = url or config.db.url url = engine_url.make_url(url) url.query['charset'] = 'utf8' url.query['use_unicode'] = '0' diff --git a/lib/sqlalchemy/testing/exclusions.py b/lib/sqlalchemy/testing/exclusions.py index f868f6396..0f976e4e0 100644 --- a/lib/sqlalchemy/testing/exclusions.py +++ b/lib/sqlalchemy/testing/exclusions.py @@ -11,7 +11,7 @@ from ..util import decorator from . import config from .. import util import contextlib - +import inspect class skip_if(object): def __init__(self, predicate, reason=None): @@ -20,10 +20,6 @@ class skip_if(object): _fails_on = None - @property - def enabled(self): - return not self.predicate() - def __add__(self, other): def decorate(fn): return other(self(fn)) @@ -34,13 +30,13 @@ class skip_if(object): try: yield except Exception as ex: - if self.predicate(): + if self.predicate(config._current): print(("%s failed as expected (%s): %s " % ( name, self.predicate, str(ex)))) else: raise else: - if self.predicate(): + if self.predicate(config._current): raise AssertionError( "Unexpected success for '%s' (%s)" % (name, self.predicate)) @@ -48,7 +44,7 @@ class skip_if(object): def __call__(self, fn): @decorator def decorate(fn, *args, **kw): - if self.predicate(): + if self.predicate(config._current): if self.reason: msg = "'%s' : %s" % ( fn.__name__, @@ -122,7 +118,7 @@ class BooleanPredicate(Predicate): self.value = value self.description = description or "boolean %s" % value - def __call__(self): + def __call__(self, config): return self.value def _as_string(self, negate=False): @@ -153,9 +149,8 @@ class SpecPredicate(Predicate): 'between': lambda val, pair: val >= pair[0] and val <= pair[1], } - def __call__(self, engine=None): - if engine is None: - engine = config.db + def __call__(self, config): + engine = config.db if "+" in self.db: dialect, driver = self.db.split('+') @@ -205,7 +200,11 @@ class SpecPredicate(Predicate): class LambdaPredicate(Predicate): def __init__(self, lambda_, description=None, args=None, kw=None): - self.lambda_ = lambda_ + spec = inspect.getargspec(lambda_) + if not spec[0]: + self.lambda_ = lambda db: lambda_ + else: + self.lambda_ = lambda_ self.args = args or () self.kw = kw or {} if description: @@ -215,8 +214,8 @@ class LambdaPredicate(Predicate): else: self.description = "custom function" - def __call__(self): - return self.lambda_(*self.args, **self.kw) + def __call__(self, config): + return self.lambda_(config) def _as_string(self, negate=False): if negate: @@ -232,8 +231,8 @@ class NotPredicate(Predicate): def __init__(self, predicate): self.predicate = predicate - def __call__(self, *arg, **kw): - return not self.predicate(*arg, **kw) + def __call__(self, config): + return not self.predicate(config) def __str__(self): return self.predicate._as_string(True) @@ -244,9 +243,9 @@ class OrPredicate(Predicate): self.predicates = predicates self.description = description - def __call__(self, *arg, **kw): + def __call__(self, config): for pred in self.predicates: - if pred(*arg, **kw): + if pred(config): self._str = pred return True return False @@ -286,7 +285,7 @@ _as_predicate = Predicate.as_predicate def _is_excluded(db, op, spec): - return SpecPredicate(db, op, spec)() + return SpecPredicate(db, op, spec)(config._current) def _server_version(engine): @@ -301,7 +300,7 @@ def _server_version(engine): def db_spec(*dbs): return OrPredicate( - Predicate.as_predicate(db) for db in dbs + [Predicate.as_predicate(db) for db in dbs] ) @@ -314,8 +313,8 @@ def closed(): @decorator -def future(fn, *args, **kw): - return fails_if(LambdaPredicate(fn, *args, **kw), "Future feature") +def future(fn): + return fails_if(LambdaPredicate(fn), "Future feature") def fails_on(db, reason=None): @@ -344,8 +343,8 @@ def exclude(db, op, spec, reason=None): return skip_if(SpecPredicate(db, op, spec), reason) -def against(*queries): +def against(config, *queries): return OrPredicate([ Predicate.as_predicate(query) for query in queries - ])() + ])(config) diff --git a/lib/sqlalchemy/testing/plugin/noseplugin.py b/lib/sqlalchemy/testing/plugin/noseplugin.py index 27a028cd4..153d227a7 100644 --- a/lib/sqlalchemy/testing/plugin/noseplugin.py +++ b/lib/sqlalchemy/testing/plugin/noseplugin.py @@ -30,7 +30,6 @@ else: from nose.plugins import Plugin from nose import SkipTest import sys -import re # late imports fixtures = None @@ -41,19 +40,24 @@ profiling = None assertions = None requirements = None config = None +testing = None util = None file_config = None logging = None -db = None -db_label = None -db_url = None db_opts = {} options = None -_existing_engine = None +_existing_config_obj = None +class Config(object): + def __init__(self, db, db_opts, options, file_config): + self.db = db + self.db_opts = db_opts + self.options = options + self.file_config = file_config + def _log(option, opt_str, value, parser): global logging if not logging: @@ -77,10 +81,6 @@ def _server_side_cursors(options, opt_str, value, parser): db_opts['server_side_cursors'] = True -def _engine_strategy(options, opt_str, value, parser): - if value: - db_opts['strategy'] = value - pre_configure = [] post_configure = [] @@ -110,48 +110,38 @@ def _monkeypatch_cdecimal(options, file_config): @post def _engine_uri(options, file_config): - global db_label, db_url + from sqlalchemy.testing import engines, config + from sqlalchemy import testing if options.dburi: - db_url = options.dburi - db_label = db_url[:db_url.index(':')] - elif options.db: - db_label = options.db - db_url = None - - if db_url is None: - if db_label not in file_config.options('db'): - raise RuntimeError( - "Unknown URI specifier '%s'. Specify --dbs for known uris." - % db_label) - db_url = file_config.get('db', db_label) - - -@post -def _require(options, file_config): - if not(options.require or - (file_config.has_section('require') and - file_config.items('require'))): - return + db_urls = list(options.dburi) + else: + db_urls = [] + + if options.db: + for db in options.db: + if db not in file_config.options('db'): + raise RuntimeError( + "Unknown URI specifier '%s'. Specify --dbs for known uris." + % db) + else: + db_urls.append(file_config.get('db', db)) + + if not db_urls: + db_urls.append(file_config.get('db', 'default')) + + for db_url in db_urls: + eng = engines.testing_engine(db_url, db_opts) + eng.connect().close() + config_obj = Config(eng, db_opts, options, file_config) + if not config.db: + config.db = testing.db = eng + config._current = config_obj + config.dbs[eng.name] = config_obj + config.dbs[(eng.name, eng.dialect)] = config_obj + config.dbs[eng] = config_obj - try: - import pkg_resources - except ImportError: - raise RuntimeError("setuptools is required for version requirements") - - cmdline = [] - for requirement in options.require: - pkg_resources.require(requirement) - cmdline.append(re.split('\s*(<!>=)', requirement, 1)[0]) - - if file_config.has_section('require'): - for label, requirement in file_config.items('require'): - if not label == db_label or label.startswith('%s.' % db_label): - continue - seen = [c for c in cmdline if requirement.startswith(c)] - if seen: - continue - pkg_resources.require(requirement) + config.db_opts = db_opts @post @@ -160,55 +150,40 @@ def _engine_pool(options, file_config): from sqlalchemy import pool db_opts['poolclass'] = pool.AssertionPool - -@post -def _create_testing_engine(options, file_config): - from sqlalchemy.testing import engines, config - from sqlalchemy import testing - global db - config.db = testing.db = db = engines.testing_engine(db_url, db_opts) - config.db.connect().close() - config.db_opts = db_opts - config.db_url = db_url - - @post def _prep_testing_database(options, file_config): - from sqlalchemy.testing import engines + from sqlalchemy.testing import config from sqlalchemy import schema, inspect - # also create alt schemas etc. here? if options.dropfirst: - e = engines.utf8_engine() - inspector = inspect(e) - - try: - view_names = inspector.get_view_names() - except NotImplementedError: - pass - else: - for vname in view_names: - e.execute(schema._DropView(schema.Table(vname, schema.MetaData()))) - - try: - view_names = inspector.get_view_names(schema="test_schema") - except NotImplementedError: - pass - else: - for vname in view_names: - e.execute(schema._DropView( - schema.Table(vname, - schema.MetaData(), schema="test_schema"))) - - for tname in reversed(inspector.get_table_names(order_by="foreign_key")): - e.execute(schema.DropTable(schema.Table(tname, schema.MetaData()))) - - for tname in reversed(inspector.get_table_names( - order_by="foreign_key", schema="test_schema")): - e.execute(schema.DropTable( - schema.Table(tname, schema.MetaData(), schema="test_schema"))) - - e.dispose() + for e in set(config.dbs.values()): + inspector = inspect(e) + + try: + view_names = inspector.get_view_names() + except NotImplementedError: + pass + else: + for vname in view_names: + e.execute(schema._DropView(schema.Table(vname, schema.MetaData()))) + + try: + view_names = inspector.get_view_names(schema="test_schema") + except NotImplementedError: + pass + else: + for vname in view_names: + e.execute(schema._DropView( + schema.Table(vname, + schema.MetaData(), schema="test_schema"))) + + for tname in reversed(inspector.get_table_names(order_by="foreign_key")): + e.execute(schema.DropTable(schema.Table(tname, schema.MetaData()))) + + for tname in reversed(inspector.get_table_names( + order_by="foreign_key", schema="test_schema")): + e.execute(schema.DropTable( + schema.Table(tname, schema.MetaData(), schema="test_schema"))) @post @@ -255,8 +230,8 @@ def _setup_requirements(argument): for component in modname.split(".")[1:]: mod = getattr(mod, component) req_cls = getattr(mod, clsname) - config.requirements = testing.requires = req_cls(config) + config.requirements = testing.requires = req_cls() @post def _post_setup_options(opt, file_config): @@ -288,14 +263,13 @@ class NoseSQLAlchemy(Plugin): help="turn on info logging for <LOG> (multiple OK)") opt("--log-debug", action="callback", type="string", callback=_log, help="turn on debug logging for <LOG> (multiple OK)") - opt("--require", action="append", dest="require", default=[], - help="require a particular driver or module version (multiple OK)") - opt("--db", action="store", dest="db", default="default", - help="Use prefab database uri") + opt("--db", action="append", type="string", dest="db", + help="Use prefab database uri. Multiple OK, " + "first one is run by default.") opt('--dbs', action='callback', callback=_list_dbs, help="List available prefab dbs") - opt("--dburi", action="store", dest="dburi", - help="Database uri (overrides --db)") + opt("--dburi", action="append", type="string", dest="dburi", + help="Database uri. Multiple OK, first one is run by default.") opt("--dropfirst", action="store_true", dest="dropfirst", help="Drop all tables in the target database first") opt("--mockpool", action="store_true", dest="mockpool", @@ -303,9 +277,6 @@ class NoseSQLAlchemy(Plugin): opt("--low-connections", action="store_true", dest="low_connections", help="Use a low number of distinct connections - i.e. for Oracle TNS" ) - opt("--enginestrategy", action="callback", type="string", - callback=_engine_strategy, - help="Engine strategy (plain or threadlocal, defaults to plain)") opt("--reversetop", action="store_true", dest="reversetop", default=False, help="Use a random-ordering set implementation in the ORM (helps " "reveal dependency issues)") @@ -314,12 +285,6 @@ class NoseSQLAlchemy(Plugin): help="requirements class for testing, overrides setup.cfg") opt("--with-cdecimal", action="store_true", dest="cdecimal", default=False, help="Monkeypatch the cdecimal library into Python 'decimal' for all tests") - opt("--unhashable", action="store_true", dest="unhashable", default=False, - help="Disallow SQLAlchemy from performing a hash() on mapped test objects.") - opt("--noncomparable", action="store_true", dest="noncomparable", default=False, - help="Disallow SQLAlchemy from performing == on mapped test objects.") - opt("--truthless", action="store_true", dest="truthless", default=False, - help="Disallow SQLAlchemy from truth-evaluating mapped test objects.") opt("--serverside", action="callback", callback=_server_side_cursors, help="Turn on server side cursors for PG") opt("--mysql-engine", action="store", dest="mysql_engine", default=None, @@ -348,7 +313,8 @@ class NoseSQLAlchemy(Plugin): # as nose plugins like coverage global util, fixtures, engines, exclusions, \ assertions, warnings, profiling,\ - config + config, testing + from sqlalchemy import testing from sqlalchemy.testing import fixtures, engines, exclusions, \ assertions, warnings, profiling, config from sqlalchemy import util @@ -381,42 +347,34 @@ class NoseSQLAlchemy(Plugin): def _do_skips(self, cls): from sqlalchemy.testing import config + + all_configs = set(config._unique_configs()) + reasons = [] + if hasattr(cls, '__requires__'): - def test_suite(): - return 'ok' - test_suite.__name__ = cls.__name__ - for requirement in cls.__requires__: - check = getattr(config.requirements, requirement) - - if not check.enabled: - raise SkipTest( - check.reason if check.reason - else - ( - "'%s' unsupported on DB implementation '%s' == %s" % ( - cls.__name__, config.db.name, - config.db.dialect.server_version_info - ) - ) - ) + requirements = config.requirements + for config_obj in list(all_configs): + for requirement in cls.__requires__: + check = getattr(requirements, requirement) + + if check.predicate(config_obj): + all_configs.remove(config_obj) + if check.reason: + reasons.append(check.reason) + break if cls.__unsupported_on__: spec = exclusions.db_spec(*cls.__unsupported_on__) - if spec(config.db): - raise SkipTest( - "'%s' unsupported on DB implementation '%s' == %s" % ( - cls.__name__, config.db.name, - config.db.dialect.server_version_info) - ) + for config_obj in list(all_configs): + if spec(config_obj): + all_configs.remove(config_obj) if getattr(cls, '__only_on__', None): spec = exclusions.db_spec(*util.to_list(cls.__only_on__)) - if not spec(config.db): - raise SkipTest( - "'%s' unsupported on DB implementation '%s' == %s" % ( - cls.__name__, config.db.name, - config.db.dialect.server_version_info) - ) + for config_obj in list(all_configs): + if not spec(config_obj): + all_configs.remove(config_obj) + if getattr(cls, '__skip_if__', False): for c in getattr(cls, '__skip_if__'): @@ -425,11 +383,33 @@ class NoseSQLAlchemy(Plugin): cls.__name__, c.__name__) ) - for db, op, spec in getattr(cls, '__excluded_on__', ()): - exclusions.exclude(db, op, spec, - "'%s' unsupported on DB %s version %s" % ( - cls.__name__, config.db.name, - exclusions._server_version(config.db))) + for db_spec, op, spec in getattr(cls, '__excluded_on__', ()): + for config_obj in list(all_configs): + if exclusions.skip_if(exclusions.SpecPredicate(db_spec, op, spec)).predicate(config_obj): + all_configs.remove(config_obj) + + + if not all_configs: + raise SkipTest( + "'%s' unsupported on DB implementation %s%s" % ( + cls.__name__, + ", ".join("'%s' = %s" % (config_obj.db.name, config_obj.db.dialect.server_version_info) + for config_obj in config._unique_configs() + ), + ", ".join(reasons) + ) + ) + elif hasattr(cls, '__prefer__'): + non_preferred = set() + spec = exclusions.db_spec(*util.to_list(cls.__prefer__)) + for config_obj in all_configs: + if not spec(config_obj): + non_preferred.add(config_obj) + if all_configs.difference(non_preferred): + all_configs.difference_update(non_preferred) + + if config._current not in all_configs: + self._setup_config(all_configs.pop(), cls) def beforeTest(self, test): warnings.resetwarnings() @@ -439,17 +419,30 @@ class NoseSQLAlchemy(Plugin): engines.testing_reaper._after_test_ctx() warnings.resetwarnings() + def _setup_config(self, config_obj, ctx): + ctx.__use_config__ = config_obj + def _setup_engine(self, ctx): if getattr(ctx, '__engine_options__', None): - global _existing_engine - _existing_engine = config.db - config.db = engines.testing_engine(options=ctx.__engine_options__) + eng = engines.testing_engine(options=ctx.__engine_options__) + config_obj = Config(eng, db_opts, options, file_config) + elif getattr(ctx, '__use_config__', None): + config_obj = ctx.__use_config__ + else: + config_obj = None + + if config_obj: + global _existing_config_obj + _existing_config_obj = config._current + config._current = config_obj + config.db = testing.db = config_obj.db def _restore_engine(self, ctx): - global _existing_engine - if _existing_engine is not None: - config.db = _existing_engine - _existing_engine = None + global _existing_config_obj + if _existing_config_obj is not None: + config.db = testing.db = _existing_config_obj.db + config._current = _existing_config_obj + _existing_config_obj = None def startContext(self, ctx): if not isinstance(ctx, type) \ diff --git a/lib/sqlalchemy/testing/requirements.py b/lib/sqlalchemy/testing/requirements.py index 77a17c1bd..5dd2435d7 100644 --- a/lib/sqlalchemy/testing/requirements.py +++ b/lib/sqlalchemy/testing/requirements.py @@ -14,16 +14,11 @@ to provide specific inclusion/exlusions. """ -from . import exclusions, config +from . import exclusions class Requirements(object): - def __init__(self, config): - self.config = config - - @property - def db(self): - return config.db + pass class SuiteRequirements(Requirements): @@ -158,8 +153,8 @@ class SuiteRequirements(Requirements): INSERT DEFAULT VALUES or equivalent.""" return exclusions.only_if( - lambda: self.config.db.dialect.supports_empty_insert or \ - self.config.db.dialect.supports_default_values, + lambda config: config.db.dialect.supports_empty_insert or \ + config.db.dialect.supports_default_values, "empty inserts not supported" ) @@ -174,7 +169,7 @@ class SuiteRequirements(Requirements): """target platform supports RETURNING.""" return exclusions.only_if( - lambda: self.config.db.dialect.implicit_returning, + lambda config: config.db.dialect.implicit_returning, "'returning' not supported by database" ) @@ -184,7 +179,7 @@ class SuiteRequirements(Requirements): UPPERCASE as case insensitive names.""" return exclusions.skip_if( - lambda: not self.db.dialect.requires_name_normalize, + lambda config: not config.db.dialect.requires_name_normalize, "Backend does not require denormalized names." ) @@ -194,7 +189,7 @@ class SuiteRequirements(Requirements): INSERT statement.""" return exclusions.skip_if( - lambda: not self.db.dialect.supports_multivalues_insert, + lambda config: not config.db.dialect.supports_multivalues_insert, "Backend does not support multirow inserts." ) @@ -245,7 +240,7 @@ class SuiteRequirements(Requirements): """Target database must support SEQUENCEs.""" return exclusions.only_if([ - lambda: self.config.db.dialect.supports_sequences + lambda config: config.db.dialect.supports_sequences ], "no sequence support") @property @@ -254,8 +249,8 @@ class SuiteRequirements(Requirements): as a means of generating new PK values.""" return exclusions.only_if([ - lambda: self.config.db.dialect.supports_sequences and \ - self.config.db.dialect.sequences_optional + lambda config: config.db.dialect.supports_sequences and \ + config.db.dialect.sequences_optional ], "no sequence support, or sequences not optional") @@ -528,8 +523,8 @@ class SuiteRequirements(Requirements): """Catchall for a large variety of MySQL on Windows failures""" return exclusions.open() - def _has_mysql_on_windows(self): + def _has_mysql_on_windows(self, config): return False - def _has_mysql_fully_case_sensitive(self): + def _has_mysql_fully_case_sensitive(self, config): return False diff --git a/test/dialect/postgresql/test_compiler.py b/test/dialect/postgresql/test_compiler.py index e64afb186..db6efa34a 100644 --- a/test/dialect/postgresql/test_compiler.py +++ b/test/dialect/postgresql/test_compiler.py @@ -19,6 +19,7 @@ from sqlalchemy.sql import table, column, operators from sqlalchemy.util import u class SequenceTest(fixtures.TestBase, AssertsCompiledSQL): + __prefer__ = 'postgresql' def test_format(self): seq = Sequence('my_seq_no_schema') diff --git a/test/dialect/postgresql/test_types.py b/test/dialect/postgresql/test_types.py index 4540b7537..7450a5d2c 100644 --- a/test/dialect/postgresql/test_types.py +++ b/test/dialect/postgresql/test_types.py @@ -448,6 +448,7 @@ class TimezoneTest(fixtures.TestBase): class TimePrecisionTest(fixtures.TestBase, AssertsCompiledSQL): __dialect__ = postgresql.dialect() + __prefer__ = 'postgresql' def test_compile(self): for type_, expected in [ diff --git a/test/requirements.py b/test/requirements.py index c75a110c6..6f6945818 100644 --- a/test/requirements.py +++ b/test/requirements.py @@ -651,11 +651,11 @@ class DefaultRequirements(SuiteRequirements): @property def hstore(self): - def check_hstore(): - if not against("postgresql"): + def check_hstore(config): + if not against(config, "postgresql"): return False try: - self.db.execute("SELECT 'a=>1,a=>2'::hstore;") + config.db.execute("SELECT 'a=>1,a=>2'::hstore;") return True except: return False @@ -664,11 +664,11 @@ class DefaultRequirements(SuiteRequirements): @property def range_types(self): - def check_range_types(): - if not against("postgresql+psycopg2"): + def check_range_types(config): + if not against(config, "postgresql+psycopg2"): return False try: - self.db.execute("select '[1,2)'::int4range;") + config.db.execute("select '[1,2)'::int4range;") # only supported in psycopg 2.5+ from psycopg2.extras import NumericRange return True @@ -684,7 +684,7 @@ class DefaultRequirements(SuiteRequirements): @property def oracle_test_dblink(self): return skip_if( - lambda: not self.config.file_config.has_option( + lambda config: not config.file_config.has_option( 'sqla_testing', 'oracle_db_link'), "oracle_db_link option not specified in config" ) @@ -740,11 +740,11 @@ class DefaultRequirements(SuiteRequirements): except ImportError: return False - def _has_mysql_on_windows(self): - return against('mysql') and \ + def _has_mysql_on_windows(self, config): + return against(config.db, 'mysql') and \ self.db.dialect._detect_casing(self.db) == 1 - def _has_mysql_fully_case_sensitive(self): - return against('mysql') and \ - self.db.dialect._detect_casing(self.db) == 0 + def _has_mysql_fully_case_sensitive(self, config): + return against(config.db, 'mysql') and \ + config.db.dialect._detect_casing(config.db) == 0 |