]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
Remove support for Python 3.5 and SQLAlchemy older than the 1.3 series.
authorCaselIT <cfederico87@gmail.com>
Fri, 16 Oct 2020 19:39:41 +0000 (21:39 +0200)
committerMike Bayer <mike_mp@zzzcomputing.com>
Mon, 26 Oct 2020 15:11:04 +0000 (11:11 -0400)
Fixes: #748
Change-Id: I18df97bdce5de6adb222d3f16486272e95b1b1a6

30 files changed:
README.unittests.rst
alembic/__init__.py
alembic/autogenerate/compare.py
alembic/autogenerate/render.py
alembic/config.py
alembic/ddl/impl.py
alembic/operations/ops.py
alembic/operations/toimpl.py
alembic/script/write_hooks.py
alembic/testing/fixtures.py
alembic/testing/requirements.py
alembic/util/__init__.py
alembic/util/compat.py
alembic/util/messaging.py
alembic/util/pyfiles.py
alembic/util/sqla_compat.py
docs/build/changelog.rst
docs/build/front.rst
docs/build/unreleased/748.rst [new file with mode: 0644]
setup.py
tests/requirements.py
tests/test_autogen_render.py
tests/test_batch.py
tests/test_environment.py
tests/test_mysql.py
tests/test_oracle.py
tests/test_postgresql.py
tests/test_sqlite.py
tests/test_version_traversal.py
tox.ini

index 60a64902603eadf3f17c115ff58c30953fd5123d..e03d7807d5fff4e259f100eacf23d574fbb14937 100644 (file)
@@ -34,12 +34,12 @@ against various combinations of databases.  The test suite can be
 run against SQLite with "backend" tests also running against a PostgreSQL
 database::
 
-    tox -e py36-sqlite-postgresql
+    tox -e py38-sqlite-postgresql
 
 Or to run just "backend" tests (NOTE: Alembic has no tests marked this
 way so this option is not important) against a MySQL databases::
 
-    tox -e py36-mysql-backendonly
+    tox -e py38-mysql-backendonly
 
 Running against backends other than SQLite requires that a database of that
 vendor be available at a specific URL.  See "Setting Up Databases" below
index 75dc7ded42371d935e0b695f3ee632ffb1e07f7f..0a640e30d8d971c6f6d3467944d089ed68a47693 100644 (file)
@@ -5,7 +5,7 @@ from . import op  # noqa
 from .runtime import environment
 from .runtime import migration
 
-__version__ = "1.4.4"
+__version__ = "1.5.0"
 
 sys.modules["alembic.migration"] = migration
 sys.modules["alembic.environment"] = environment
index 1b8fb52016a4877b74785dd2c40e3938f3c2dcd3..08d3b3bb71e3e31b4decfd8ad8b04e593c69ec77 100644 (file)
@@ -1047,7 +1047,7 @@ def _compare_column_comment(
     metadata_col,
 ):
 
-    if not sqla_compat._dialect_supports_comments(autogen_context.dialect):
+    if not autogen_context.dialect.supports_comments:
         return
 
     metadata_comment = metadata_col.comment
@@ -1181,7 +1181,7 @@ def _compare_table_comment(
     metadata_table,
 ):
 
-    if not sqla_compat._dialect_supports_comments(autogen_context.dialect):
+    if not autogen_context.dialect.supports_comments:
         return
 
     # if we're doing CREATE TABLE, comments will be created inline
index 99c15c3835e710c9a051344629278096919aafa2..a960d31cb950f49950704f6b208b2b17066f04e4 100644 (file)
@@ -197,7 +197,7 @@ def _add_table(autogen_context, op):
     if op.schema:
         text += ",\nschema=%r" % _ident(op.schema)
 
-    comment = sqla_compat._comment_attribute(table)
+    comment = table.comment
     if comment:
         text += ",\ncomment=%r" % _ident(comment)
     for k in sorted(op.kw):
@@ -620,7 +620,7 @@ def _render_column(column, autogen_context):
     if column.system:
         opts.append(("system", column.system))
 
-    comment = sqla_compat._comment_attribute(column)
+    comment = column.comment
     if comment:
         opts.append(("comment", "%r" % comment))
 
index 6c9019dea865e3ba5f9e939152f8e99ce62f32a4..f9f94dbc8b578d05baab31aa74fa7bc59958239a 100644 (file)
@@ -100,9 +100,7 @@ class Config(object):
         config_args=util.immutabledict(),
         attributes=None,
     ):
-        """Construct a new :class:`.Config`
-
-        """
+        """Construct a new :class:`.Config`"""
         self.config_file_name = file_
         self.config_ini_section = ini_section
         self.output_buffer = output_buffer
@@ -270,9 +268,7 @@ class Config(object):
         self.file_config.set(section, name, value)
 
     def get_section_option(self, section, name, default=None):
-        """Return an option from the given section of the .ini file.
-
-        """
+        """Return an option from the given section of the .ini file."""
         if not self.file_config.has_section(section):
             raise util.CommandError(
                 "No config file %r found, or file has no "
index 7b32b01d1ebd40600afbbb1369bee34b7bb14ce7..d0e64585520b0315ff68f26f7c24eaeaa4548ab4 100644 (file)
@@ -264,15 +264,14 @@ class DefaultImpl(with_metaclass(ImplMeta)):
             self._exec(schema.CreateIndex(index))
 
         with_comment = (
-            sqla_compat._dialect_supports_comments(self.dialect)
-            and not self.dialect.inline_comments
+            self.dialect.supports_comments and not self.dialect.inline_comments
         )
-        comment = sqla_compat._comment_attribute(table)
+        comment = table.comment
         if comment and with_comment:
             self.create_table_comment(table)
 
         for column in table.columns:
-            comment = sqla_compat._comment_attribute(column)
+            comment = column.comment
             if comment and with_comment:
                 self.create_column_comment(column)
 
@@ -426,7 +425,7 @@ class DefaultImpl(with_metaclass(ImplMeta)):
         inspector_params = self._tokenize_column_type(inspector_column)
         metadata_params = self._tokenize_column_type(metadata_column)
 
-        if not self._column_types_match(inspector_params, metadata_params,):
+        if not self._column_types_match(inspector_params, metadata_params):
             return True
         if not self._column_args_match(inspector_params, metadata_params):
             return True
index 71294722e9adbe92b5dcf05a6e50b552a00956dc..9160bc154fe49257de9f7dcc3787e62456a90061 100644 (file)
@@ -1358,8 +1358,7 @@ class RenameTableOp(AlterTableOp):
 
 @Operations.register_operation("create_table_comment")
 class CreateTableCommentOp(AlterTableOp):
-    """Represent a COMMENT ON `table` operation.
-    """
+    """Represent a COMMENT ON `table` operation."""
 
     def __init__(
         self, table_name, comment, schema=None, existing_comment=None
@@ -1407,8 +1406,7 @@ class CreateTableCommentOp(AlterTableOp):
         return operations.invoke(op)
 
     def reverse(self):
-        """Reverses the COMMENT ON operation against a table.
-        """
+        """Reverses the COMMENT ON operation against a table."""
         if self.existing_comment is None:
             return DropTableCommentOp(
                 self.table_name,
@@ -1436,8 +1434,7 @@ class CreateTableCommentOp(AlterTableOp):
 
 @Operations.register_operation("drop_table_comment")
 class DropTableCommentOp(AlterTableOp):
-    """Represent an operation to remove the comment from a table.
-    """
+    """Represent an operation to remove the comment from a table."""
 
     def __init__(self, table_name, schema=None, existing_comment=None):
         self.table_name = table_name
@@ -1469,8 +1466,7 @@ class DropTableCommentOp(AlterTableOp):
         return operations.invoke(op)
 
     def reverse(self):
-        """Reverses the COMMENT ON operation against a table.
-        """
+        """Reverses the COMMENT ON operation against a table."""
         return CreateTableCommentOp(
             self.table_name, self.existing_comment, schema=self.schema
         )
@@ -2159,7 +2155,7 @@ class BulkInsertOp(MigrateOperation):
 
            .. versionadded:: 0.6.4
 
-          """
+        """
 
         op = cls(table, rows, multiinsert=multiinsert)
         operations.invoke(op)
index 3114a66fe0c945be98e9a45e9a57398e1d70358f..30edd8492ee80dc60e02174fd79d6df030a6afc4 100644 (file)
@@ -2,7 +2,6 @@ from sqlalchemy import schema as sa_schema
 
 from . import ops
 from .base import Operations
-from ..util import sqla_compat
 
 
 @Operations.implementation_for(ops.AlterColumnOp)
@@ -138,10 +137,10 @@ def add_column(operations, operation):
         operations.impl.create_index(index)
 
     with_comment = (
-        sqla_compat._dialect_supports_comments(operations.impl.dialect)
+        operations.impl.dialect.supports_comments
         and not operations.impl.dialect.inline_comments
     )
-    comment = sqla_compat._comment_attribute(column)
+    comment = column.comment
     if comment and with_comment:
         operations.impl.create_column_comment(column)
 
index 61a6a2766d43cfe9b9881ebdc888b154fae5c3a7..7d0843b8c292824d7cc6b179395ed25ac0110f4b 100644 (file)
@@ -48,9 +48,7 @@ def _invoke(name, revision, options):
 
 
 def _run_hooks(path, hook_config):
-    """Invoke hooks for a generated revision.
-
-    """
+    """Invoke hooks for a generated revision."""
 
     from .base import _split_on_space_comma
 
index 6acfa9bfd45608f6544bdbcd267c9dae8441667b..dd1d2f16409c5129df9cd2103c9b2e77fa165973 100644 (file)
@@ -182,7 +182,7 @@ class AlterColRoundTripFixture(object):
     # the type / server default compare logic might not work on older
     # SQLAlchemy versions as seems to be the case for SQLAlchemy 1.1 on Oracle
 
-    __requires__ = ("alter_column", "sqlalchemy_12")
+    __requires__ = ("alter_column",)
 
     def setUp(self):
         self.conn = config.db.connect()
index 4804646130a2bfbfc45340e60ca6c2887b6b3d54..a9a1059d1a94e362c348b97d3b3013d9271c5ba3 100644 (file)
@@ -62,21 +62,6 @@ class SuiteRequirements(Requirements):
     def reflects_fk_options(self):
         return exclusions.closed()
 
-    @property
-    def sqlalchemy_issue_3740(self):
-        """Fixes percent sign escaping for paramstyles that don't require it"""
-        return exclusions.skip_if(
-            lambda config: not util.sqla_120,
-            "SQLAlchemy 1.2 or greater required",
-        )
-
-    @property
-    def sqlalchemy_12(self):
-        return exclusions.skip_if(
-            lambda config: not util.sqla_1216,
-            "SQLAlchemy 1.2.16 or greater required",
-        )
-
     @property
     def sqlalchemy_13(self):
         return exclusions.skip_if(
@@ -91,36 +76,6 @@ class SuiteRequirements(Requirements):
             "SQLAlchemy 1.4 or greater required",
         )
 
-    @property
-    def sqlalchemy_1115(self):
-        return exclusions.skip_if(
-            lambda config: not util.sqla_1115,
-            "SQLAlchemy 1.1.15 or greater required",
-        )
-
-    @property
-    def sqlalchemy_110(self):
-        return exclusions.skip_if(
-            lambda config: not util.sqla_110,
-            "SQLAlchemy 1.1.0 or greater required",
-        )
-
-    @property
-    def sqlalchemy_issue_4436(self):
-        def check(config):
-            vers = sqla_compat._vers
-
-            if vers == (1, 3, 0, "b1"):
-                return True
-            elif vers >= (1, 2, 16):
-                return False
-            else:
-                return True
-
-        return exclusions.skip_if(
-            check, "SQLAlchemy 1.2.16, 1.3.0b2 or greater required"
-        )
-
     @property
     def python3(self):
         return exclusions.skip_if(
@@ -135,15 +90,9 @@ class SuiteRequirements(Requirements):
     @property
     def comments(self):
         return exclusions.only_if(
-            lambda config: sqla_compat._dialect_supports_comments(
-                config.db.dialect
-            )
+            lambda config: config.db.dialect.supports_comments
         )
 
-    @property
-    def comments_api(self):
-        return exclusions.only_if(lambda config: util.sqla_120)
-
     @property
     def alter_column(self):
         return exclusions.open()
index cc86111bf893138cbecd3a0d4154a159d3db861f..141ba4502528f57aafb8fb868d755d530df079dc 100644 (file)
@@ -24,13 +24,9 @@ from .pyfiles import load_python_file  # noqa
 from .pyfiles import pyc_file_from_path  # noqa
 from .pyfiles import template_to_file  # noqa
 from .sqla_compat import has_computed  # noqa
-from .sqla_compat import sqla_110  # noqa
-from .sqla_compat import sqla_1115  # noqa
-from .sqla_compat import sqla_120  # noqa
-from .sqla_compat import sqla_1216  # noqa
 from .sqla_compat import sqla_13  # noqa
 from .sqla_compat import sqla_14  # noqa
 
 
-if not sqla_110:
-    raise CommandError("SQLAlchemy 1.1.0 or greater is required. ")
+if not sqla_13:
+    raise CommandError("SQLAlchemy 1.3.0 or greater is required.")
index c9c2a588f123390fa20b715548c49b2f8de59e0a..f5a04ef05deace5818e2df32d68a3a572b9d0afb 100644 (file)
@@ -3,10 +3,8 @@ import inspect
 import io
 import sys
 
-py27 = sys.version_info >= (2, 7)
 py2k = sys.version_info.major < 3
 py3k = sys.version_info.major >= 3
-py35 = sys.version_info >= (3, 5)
 py36 = sys.version_info >= (3, 6)
 
 
@@ -88,11 +86,10 @@ if py3k:
 else:
     import collections as collections_abc  # noqa
 
-if py35:
+if py3k:
 
     def _formatannotation(annotation, base_module=None):
-        """vendored from python 3.7
-        """
+        """vendored from python 3.7"""
 
         if getattr(annotation, "__module__", None) == "typing":
             return repr(annotation).replace("typing.", "")
@@ -174,10 +171,11 @@ else:
 if py2k:
     from mako.util import parse_encoding
 
-if py35:
-    import importlib.util
+if py3k:
     import importlib.machinery
 
+    import importlib.util
+
     def load_module_py(module_id, path):
         spec = importlib.util.spec_from_file_location(module_id, path)
         module = importlib.util.module_from_spec(spec)
@@ -190,27 +188,6 @@ if py35:
         spec.loader.exec_module(module)
         return module
 
-
-elif py3k:
-    import importlib.machinery
-
-    def load_module_py(module_id, path):
-        module = importlib.machinery.SourceFileLoader(
-            module_id, path
-        ).load_module(module_id)
-        del sys.modules[module_id]
-        return module
-
-    def load_module_pyc(module_id, path):
-        module = importlib.machinery.SourcelessFileLoader(
-            module_id, path
-        ).load_module(module_id)
-        del sys.modules[module_id]
-        return module
-
-
-if py3k:
-
     def get_bytecode_suffixes():
         try:
             return importlib.machinery.BYTECODE_SUFFIXES
@@ -218,7 +195,7 @@ if py3k:
             return importlib.machinery.DEBUG_BYTECODE_SUFFIXES
 
     def get_current_bytecode_suffixes():
-        if py35:
+        if py3k:
             suffixes = importlib.machinery.BYTECODE_SUFFIXES
         else:
             if sys.flags.optimize:
@@ -229,17 +206,7 @@ if py3k:
         return suffixes
 
     def has_pep3147():
-
-        if py35:
-            return True
-        else:
-            # TODO: not sure if we are supporting old versions of Python
-            # the import here emits a deprecation warning which the test
-            # suite only catches if imp wasn't imported alreadt
-            # http://www.python.org/dev/peps/pep-3147/#detecting-pep-3147-availability
-            import imp
-
-            return hasattr(imp, "get_tag")
+        return True
 
 
 else:
index 65b92c8ed3154bc3a63ab53be6676b4351246f32..38a3f13e006abee60e15466da84e900666e1d28b 100644 (file)
@@ -7,14 +7,12 @@ from sqlalchemy.engine import url
 
 from .compat import binary_type
 from .compat import collections_abc
-from .compat import py27
 from .compat import string_types
 
 log = logging.getLogger(__name__)
 
-if py27:
-    # disable "no handler found" errors
-    logging.getLogger("alembic").addHandler(logging.NullHandler())
+# disable "no handler found" errors
+logging.getLogger("alembic").addHandler(logging.NullHandler())
 
 
 try:
index 013b147d061489b409abb19450d4f6373771f6ad..b65df2c4886df8cbea75e9b925da5398ab329d05 100644 (file)
@@ -9,7 +9,7 @@ from .compat import get_current_bytecode_suffixes
 from .compat import has_pep3147
 from .compat import load_module_py
 from .compat import load_module_pyc
-from .compat import py35
+from .compat import py3k
 from .exc import CommandError
 
 
@@ -50,12 +50,10 @@ def coerce_resource_to_filename(fname):
 
 
 def pyc_file_from_path(path):
-    """Given a python source path, locate the .pyc.
-
-    """
+    """Given a python source path, locate the .pyc."""
 
     if has_pep3147():
-        if py35:
+        if py3k:
             import importlib
 
             candidate = importlib.util.cache_from_source(path)
index 5fc5e05acc3160b4e8c3a0f3a8fcf25a579dff3f..5ac8d5d660409d80d3e1f7f9b16f7287a45a8325 100644 (file)
@@ -28,10 +28,6 @@ def _safe_int(value):
 _vers = tuple(
     [_safe_int(x) for x in re.findall(r"(\d+|[abc]\d)", __version__)]
 )
-sqla_110 = _vers >= (1, 1, 0)
-sqla_1115 = _vers >= (1, 1, 15)
-sqla_120 = _vers >= (1, 2, 0)
-sqla_1216 = _vers >= (1, 2, 16)
 sqla_13 = _vers >= (1, 3)
 sqla_14 = _vers >= (1, 4)
 try:
@@ -272,22 +268,6 @@ def _constraint_is_named(constraint, dialect):
         return constraint.name is not None
 
 
-def _dialect_supports_comments(dialect):
-    if sqla_120:
-        return dialect.supports_comments
-    else:
-        return False
-
-
-def _comment_attribute(obj):
-    """return the .comment attribute from a Table or Column"""
-
-    if sqla_120:
-        return obj.comment
-    else:
-        return None
-
-
 def _is_mariadb(mysql_dialect):
     if sqla_14:
         return mysql_dialect.is_mariadb
index 24e0da8606a9fae5b2ee3c8238e2fd67670c65e7..376f0000d02c1e8d3fbe92b61cec947e99a00fa1 100644 (file)
@@ -4,7 +4,7 @@ Changelog
 ==========
 
 .. changelog::
-    :version: 1.4.4
+    :version: 1.5.0
     :include_notes_from: unreleased
 
 .. changelog::
index f5a6f059d65b43ff439ad3719fc9f48c9cba6ccd..09d7b6bcb90a7d09bc22f880dfcf5694697b6a72 100644 (file)
@@ -80,16 +80,13 @@ Dependencies
 
 Alembic's install process will ensure that SQLAlchemy_
 is installed, in addition to other dependencies.  Alembic will work with
-SQLAlchemy as of version **0.9.0**, however more features are available with
-newer versions such as the 1.1 or 1.2 series.
+SQLAlchemy as of version **1.3.0**.
 
-.. versionchanged:: 1.0.0 Support for SQLAlchemy 0.8 and 0.7.9 was dropped.
+.. versionchanged:: 1.5.0 Support for SQLAlchemy older than 1.3.0 was dropped.
 
-Alembic supports Python versions 2.7, 3.5 and above.
+Alembic supports Python versions 2.7, 3.6 and above.
 
-.. versionchanged::  1.0.0  Support for Python 2.6 and 3.3 was dropped.
-
-.. versionchanged::  1.1.1  Support for Python 3.4 was dropped.
+.. versionchanged::  1.5.0  Support for Python 3.5 was dropped.
 
 Community
 =========
diff --git a/docs/build/unreleased/748.rst b/docs/build/unreleased/748.rst
new file mode 100644 (file)
index 0000000..9e20003
--- /dev/null
@@ -0,0 +1,7 @@
+.. change::
+    :tags: change
+    :tickets: 711
+
+    Alembic 1.5.0 now supports **Python 2.7 and Python 3.6 and above**, as well
+    as **SQLAlchemy 1.3.0 and above**.  Support is removed for Python 3
+    versions prior to 3.6 and SQLAlchemy versions prior to the 1.3 series.
index 7fbf4be66a829eba63080d8dd4390bfd8326dbd2..54374390dd047a313ada1be30ef8ac62f2777628 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -19,7 +19,7 @@ v.close()
 readme = os.path.join(os.path.dirname(__file__), "README.rst")
 
 requires = [
-    "SQLAlchemy>=1.1.0",
+    "SQLAlchemy>=1.3.0",
     "Mako",
     "python-editor>=0.3",
     "python-dateutil",
@@ -46,7 +46,9 @@ setup(
     version=VERSION,
     description="A database migration tool for SQLAlchemy.",
     long_description=open(readme).read(),
-    python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
+    python_requires=(
+        ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
+    ),
     classifiers=[
         "Development Status :: 5 - Production/Stable",
         "Environment :: Console",
@@ -56,10 +58,10 @@ setup(
         "Programming Language :: Python :: 2",
         "Programming Language :: Python :: 2.7",
         "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.5",
         "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
+        "Programming Language :: Python :: 3.9",
         "Programming Language :: Python :: Implementation :: CPython",
         "Programming Language :: Python :: Implementation :: PyPy",
         "Topic :: Database :: Front-Ends",
index 4599013856bbf9b144fc2d9c0f6f52a6e35bcf62..eb6066db6c70a5188b3a92bfd28303b07242f2ec 100644 (file)
@@ -218,36 +218,6 @@ class DefaultRequirements(SuiteRequirements):
             self._mysql_and_check_constraints_exist,
         )
 
-    @property
-    def mysql_check_reflection_or_none(self):
-        # succeed if:
-        # 1. SQLAlchemy does not reflect CHECK constraints
-        # 2. SQLAlchemy does reflect CHECK constraints, but MySQL does not.
-        def go(config):
-            return (
-                not self._mysql_check_constraints_exist(config)
-                or self.sqlalchemy_1115.enabled
-            )
-
-        return exclusions.succeeds_if(go)
-
-    @property
-    def mysql_timestamp_reflection(self):
-        def go(config):
-            return (
-                not self._mariadb_102(config) or self.sqlalchemy_1115.enabled
-            )
-
-        return exclusions.only_if(go)
-
-    def _mariadb_102(self, config):
-        return (
-            exclusions.against(config, ["mysql", "mariadb"])
-            and sqla_compat._is_mariadb(config.db.dialect)
-            and sqla_compat._mariadb_normalized_version_info(config.db.dialect)
-            > (10, 2)
-        )
-
     def mysql_check_col_name_change(self, config):
         # MySQL has check constraints that enforce an reflect, however
         # they prevent a column's name from being changed due to a bug in
@@ -281,22 +251,3 @@ class DefaultRequirements(SuiteRequirements):
                 return norm_version_info >= (8, 0, 16)
         else:
             return False
-
-    def _mysql_check_constraints_exist(self, config):
-        # 1. we dont have mysql / mariadb or
-        # 2. we have mysql / mariadb that enforces check constraints
-        return not exclusions.against(
-            config, ["mysql", "mariadb"]
-        ) or self._mysql_and_check_constraints_exist(config)
-
-    def _mysql_check_constraints_dont_exist(self, config):
-        # 1. we have mysql / mariadb and
-        # 2. they dont enforce check constraints
-        return not self._mysql_check_constraints_exist(config)
-
-    def _mysql_not_mariadb_102(self, config):
-        return exclusions.against(config, ["mysql", "mariadb"]) and (
-            not sqla_compat._is_mariadb(config.db.dialect)
-            or sqla_compat._mariadb_normalized_version_info(config.db.dialect)
-            < (10, 2)
-        )
index d86e934d65d2d09f5200168b4fc7c9462df113fe..e7999f49b401b99b0810a9ee097fecf1e0184f26 100644 (file)
@@ -1168,7 +1168,6 @@ class AutogenRenderTest(TestBase):
             "nullable=False)",
         )
 
-    @config.requirements.comments_api
     def test_render_col_with_comment(self):
         c = Column("some_key", Integer, comment="This is a comment")
         Table("some_table", MetaData(), c)
@@ -1180,7 +1179,6 @@ class AutogenRenderTest(TestBase):
             "comment='This is a comment')",
         )
 
-    @config.requirements.comments_api
     def test_render_col_comment_with_quote(self):
         c = Column("some_key", Integer, comment="This is a john's comment")
         Table("some_table", MetaData(), c)
@@ -1865,7 +1863,6 @@ class AutogenRenderTest(TestBase):
             op_obj,
         )
 
-    @config.requirements.comments_api
     def test_render_alter_column_modify_comment(self):
         op_obj = ops.AlterColumnOp(
             "sometable", "somecolumn", modify_comment="This is a comment"
@@ -1876,7 +1873,6 @@ class AutogenRenderTest(TestBase):
             "comment='This is a comment')",
         )
 
-    @config.requirements.comments_api
     def test_render_alter_column_existing_comment(self):
         op_obj = ops.AlterColumnOp(
             "sometable", "somecolumn", existing_comment="This is a comment"
@@ -1887,7 +1883,6 @@ class AutogenRenderTest(TestBase):
             "existing_comment='This is a comment')",
         )
 
-    @config.requirements.comments_api
     def test_render_col_drop_comment(self):
         op_obj = ops.AlterColumnOp(
             "sometable",
@@ -1902,7 +1897,6 @@ class AutogenRenderTest(TestBase):
             "existing_comment='This is a comment')",
         )
 
-    @config.requirements.comments_api
     def test_render_table_with_comment(self):
         m = MetaData()
         t = Table(
@@ -1924,7 +1918,6 @@ class AutogenRenderTest(TestBase):
             ")",
         )
 
-    @config.requirements.comments_api
     def test_render_add_column_with_comment(self):
         op_obj = ops.AddColumnOp(
             "foo", Column("x", Integer, comment="This is a Column")
@@ -1935,7 +1928,6 @@ class AutogenRenderTest(TestBase):
             "nullable=True, comment='This is a Column'))",
         )
 
-    @config.requirements.comments_api
     def test_render_create_table_comment_op(self):
         op_obj = ops.CreateTableCommentOp("table_name", "comment")
         eq_ignore_whitespace(
@@ -1948,7 +1940,6 @@ class AutogenRenderTest(TestBase):
             ")",
         )
 
-    @config.requirements.comments_api
     def test_render_create_table_comment_with_quote_op(self):
         op_obj = ops.CreateTableCommentOp(
             "table_name",
index faff4f58c479a14bead228572819475b6763c23d..9501e3234ac0702653c8395b79a7387839c88562 100644 (file)
@@ -1365,7 +1365,6 @@ class BatchRoundTripTest(TestBase):
             [(datetime.datetime(2012, 5, 18, 15, 32, 5),)],
         )
 
-    @config.requirements.sqlalchemy_12
     def test_no_net_change_timestamp_w_default(self):
         t = self._timestamp_w_expr_default_fixture()
 
@@ -1932,11 +1931,9 @@ class BatchRoundTripMySQLTest(BatchRoundTripTest):
     def test_rename_column_boolean(self):
         super(BatchRoundTripMySQLTest, self).test_rename_column_boolean()
 
-    @config.requirements.mysql_check_reflection_or_none
     def test_change_type_boolean_to_int(self):
         super(BatchRoundTripMySQLTest, self).test_change_type_boolean_to_int()
 
-    @config.requirements.mysql_check_reflection_or_none
     def test_change_type_int_to_boolean(self):
         super(BatchRoundTripMySQLTest, self).test_change_type_int_to_boolean()
 
index 7e5eb8393594d8a2be96a399b7113255f8f6b3e7..4fb6bbe19c4bc9e7c8e00b43184d9adf93460639 100644 (file)
@@ -66,7 +66,6 @@ class EnvironmentTest(TestBase):
         ctx = MigrationContext(ctx.dialect, None, {})
         is_(ctx.config, None)
 
-    @config.requirements.sqlalchemy_issue_3740
     def test_sql_mode_parameters(self):
         env = self._fixture()
 
index 4ab43309c3920cc2184fbfebf7527fddaa3b9d5a..d064b92de8f9fa65cb02def8c08ba5e212441dc6 100644 (file)
@@ -27,7 +27,6 @@ from alembic.util import sqla_compat
 
 
 class MySQLOpTest(TestBase):
-    @config.requirements.comments_api
     def test_create_table_with_comment(self):
         context = op_fixture("mysql")
         op.create_table(
@@ -37,7 +36,6 @@ class MySQLOpTest(TestBase):
         )
         context.assert_contains("COMMENT='This is a table comment'")
 
-    @config.requirements.comments_api
     def test_create_table_with_column_comments(self):
         context = op_fixture("mysql")
         op.create_table(
@@ -56,7 +54,6 @@ class MySQLOpTest(TestBase):
             "COMMENT='This is a table comment'"
         )
 
-    @config.requirements.comments_api
     def test_add_column_with_comment(self):
         context = op_fixture("mysql")
         op.add_column("t", Column("q", Integer, comment="This is a comment"))
@@ -281,7 +278,6 @@ class MySQLOpTest(TestBase):
             server_default="q",
         )
 
-    @config.requirements.comments_api
     def test_alter_column_add_comment(self):
         context = op_fixture("mysql")
         op.alter_column(
@@ -297,7 +293,6 @@ class MySQLOpTest(TestBase):
             "COMMENT 'This is a column comment'"
         )
 
-    @config.requirements.comments_api
     def test_alter_column_add_comment_quoting(self):
         context = op_fixture("mysql")
         op.alter_column(
@@ -313,7 +308,6 @@ class MySQLOpTest(TestBase):
             "COMMENT 'This is a ''column'' comment'"
         )
 
-    @config.requirements.comments_api
     def test_alter_column_drop_comment(self):
         context = op_fixture("mysql")
         op.alter_column(
@@ -327,7 +321,6 @@ class MySQLOpTest(TestBase):
 
         context.assert_("ALTER TABLE foo.t MODIFY c BOOL NULL")
 
-    @config.requirements.comments_api
     def test_alter_column_existing_comment(self):
         context = op_fixture("mysql")
         op.alter_column(
@@ -343,7 +336,6 @@ class MySQLOpTest(TestBase):
             "COMMENT 'existing column comment'"
         )
 
-    @config.requirements.comments_api
     def test_rename_column_existing_comment(self):
         context = op_fixture("mysql")
         op.alter_column(
@@ -360,7 +352,6 @@ class MySQLOpTest(TestBase):
             "COMMENT 'existing column comment'"
         )
 
-    @config.requirements.comments_api
     def test_alter_column_new_comment_replaces_existing(self):
         context = op_fixture("mysql")
         op.alter_column(
@@ -377,15 +368,12 @@ class MySQLOpTest(TestBase):
             "COMMENT 'This is a column comment'"
         )
 
-    @config.requirements.comments_api
     def test_create_table_comment(self):
         # this is handled by SQLAlchemy's compilers
         context = op_fixture("mysql")
         op.create_table_comment("t2", comment="t2 table", schema="foo")
         context.assert_("ALTER TABLE foo.t2 COMMENT 't2 table'")
 
-    @config.requirements.comments_api
-    @config.requirements.sqlalchemy_issue_4436
     def test_drop_table_comment(self):
         # this is handled by SQLAlchemy's compilers
         context = op_fixture("mysql")
@@ -537,8 +525,6 @@ class MySQLDefaultCompareTest(TestBase):
     __only_on__ = "mysql"
     __backend__ = True
 
-    __requires__ = ("mysql_timestamp_reflection",)
-
     @classmethod
     def setup_class(cls):
         cls.bind = config.db
index b2e704f93f668d0f4f9e386eb8922a0f8ec701c3..784574500563f5b34ed72c94e39cf46e43fc2943 100644 (file)
@@ -123,15 +123,12 @@ class OpTest(TestBase):
             "ALTER TABLE t MODIFY c INTEGER", "COMMENT ON COLUMN t.c IS ''"
         )
 
-    @config.requirements.comments_api
     def test_create_table_comment(self):
         # this is handled by SQLAlchemy's compilers
         context = op_fixture("oracle")
         op.create_table_comment("t2", comment="t2 table", schema="foo")
         context.assert_("COMMENT ON TABLE foo.t2 IS 't2 table'")
 
-    @config.requirements.comments_api
-    @config.requirements.sqlalchemy_issue_4436
     def test_drop_table_comment(self):
         # this is handled by SQLAlchemy's compilers
         context = op_fixture("oracle")
index 8c435102b7300512188974d146c6f0e4e824593c..f928868fd6d1fc5897c520e34ea527e535a5c3be 100644 (file)
@@ -155,7 +155,6 @@ class PostgresqlOpTest(TestBase):
             'USING gist ("SomeColumn" WITH >) WHERE ("SomeColumn" > 5)'
         )
 
-    @config.requirements.comments_api
     def test_add_column_with_comment(self):
         context = op_fixture("postgresql")
         op.add_column("t", Column("q", Integer, comment="This is a comment"))
@@ -164,7 +163,6 @@ class PostgresqlOpTest(TestBase):
             "COMMENT ON COLUMN t.q IS 'This is a comment'",
         )
 
-    @config.requirements.comments_api
     def test_alter_column_with_comment(self):
         context = op_fixture("postgresql")
         op.alter_column(
@@ -181,7 +179,6 @@ class PostgresqlOpTest(TestBase):
             "COMMENT ON COLUMN foo.t.c IS 'This is a column comment'",
         )
 
-    @config.requirements.comments_api
     def test_alter_column_add_comment(self):
         context = op_fixture("postgresql")
         op.alter_column(
@@ -196,7 +193,6 @@ class PostgresqlOpTest(TestBase):
             "COMMENT ON COLUMN foo.t.c IS 'This is a column comment'"
         )
 
-    @config.requirements.comments_api
     def test_alter_column_add_comment_table_and_column_quoting(self):
         context = op_fixture("postgresql")
         op.alter_column(
@@ -211,7 +207,6 @@ class PostgresqlOpTest(TestBase):
             'COMMENT ON COLUMN foo."T"."C" IS \'This is a column comment\''
         )
 
-    @config.requirements.comments_api
     def test_alter_column_add_comment_quoting(self):
         context = op_fixture("postgresql")
         op.alter_column(
@@ -226,7 +221,6 @@ class PostgresqlOpTest(TestBase):
             "COMMENT ON COLUMN foo.t.c IS 'This is a column ''comment'''"
         )
 
-    @config.requirements.comments_api
     def test_alter_column_drop_comment(self):
         context = op_fixture("postgresql")
         op.alter_column(
@@ -240,7 +234,6 @@ class PostgresqlOpTest(TestBase):
 
         context.assert_("COMMENT ON COLUMN foo.t.c IS NULL")
 
-    @config.requirements.comments_api
     def test_create_table_with_comment(self):
         context = op_fixture("postgresql")
         op.create_table(
@@ -255,7 +248,6 @@ class PostgresqlOpTest(TestBase):
             "COMMENT ON TABLE t2 IS 't2 comment'",
         )
 
-    @config.requirements.comments_api
     def test_create_table_with_column_comments(self):
         context = op_fixture("postgresql")
         op.create_table(
@@ -272,14 +264,12 @@ class PostgresqlOpTest(TestBase):
             "COMMENT ON COLUMN t2.c2 IS 'c2 comment'",
         )
 
-    @config.requirements.comments_api
     def test_create_table_comment(self):
         # this is handled by SQLAlchemy's compilers
         context = op_fixture("postgresql")
         op.create_table_comment("t2", comment="t2 table", schema="foo")
         context.assert_("COMMENT ON TABLE foo.t2 IS 't2 table'")
 
-    @config.requirements.comments_api
     def test_drop_table_comment(self):
         # this is handled by SQLAlchemy's compilers
         context = op_fixture("postgresql")
index 76bf65d7be357a30e36618b8941eeb163756e00b..3ea1975c1fa2a9acf6f4445d82d2a0a66ea55d94 100644 (file)
@@ -159,13 +159,11 @@ class SQLiteDefaultCompareTest(TestBase):
             None, col, rendered, cols[0]["default"]
         )
 
-    @config.requirements.sqlalchemy_12
     def test_compare_current_timestamp_func(self):
         self._compare_default_roundtrip(
             DateTime(), func.datetime("now", "localtime")
         )
 
-    @config.requirements.sqlalchemy_12
     def test_compare_current_timestamp_func_now(self):
         self._compare_default_roundtrip(DateTime(), func.now())
 
index 5d22d1cfdb509a12150c1b394c7a11af84f95424..dc5683f9ad8a419ba12ecada6232da86deef9116 100644 (file)
@@ -563,9 +563,7 @@ class TwinMergeTest(MigrationTest):
 
 
 class NotQuiteTwinMergeTest(MigrationTest):
-    """Test a variant of #297.
-
-    """
+    """Test a variant of #297."""
 
     @classmethod
     def setup_class(cls):
diff --git a/tox.ini b/tox.ini
index f1447547f1fc2c46afb02f25de2ade59e0dceda9..eea75145e79653fa5d6de086d29e34286ed907ba 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -10,8 +10,6 @@ cov_args=--cov=alembic --cov-report term --cov-report xml
 deps=pytest>4.6
      pytest-xdist
      mock
-     sqla11: {[tox]SQLA_REPO}@rel_1_1
-     sqla12: {[tox]SQLA_REPO}@rel_1_2
      sqla13: {[tox]SQLA_REPO}@rel_1_3
      sqlamaster: {[tox]SQLA_REPO}@master
      postgresql: psycopg2