diff options
author | Cyril Roelandt <cyril.roelandt@enovance.com> | 2014-03-19 15:02:40 +0100 |
---|---|---|
committer | Cyril Roelandt <cyril.roelandt@enovance.com> | 2014-04-09 17:32:52 +0200 |
commit | a03b141a954c7e644f0033defdb1b5b434a7c49a (patch) | |
tree | 3515ecc8ab1b2a2218b0fa60aec04de09def8ce5 /migrate/changeset/schema.py | |
parent | 07909159ae22dc0d399b9618dcf0f79a1d0332bf (diff) | |
download | sqlalchemy-migrate-a03b141a954c7e644f0033defdb1b5b434a7c49a.tar.gz |
Port to Python3
Brief summary of the modifications:
* Use six for compatibility with both Python 2 and 3;
* Replace UserDict.DictMixin with collections.MutableMapping;
* Fix relative imports;
* Use test-requirements.txt for requirements that are common to both Python 2
and 3, and test-requirements-py{2,3}.txt for version-specific requirements;
* Miscellaneous fixes.
* Use a specific test_db_py3.cfg file for Python 3, that only runs tests on
sqlite.
Thanks to Victor Stinner who co-wrote this patch.
Change-Id: Ia6dc536c39d274924c21fd5bb619e8e5721e04c4
Co-Authored-By: Victor Stinner <victor.stinner@enovance.com>
Diffstat (limited to 'migrate/changeset/schema.py')
-rw-r--r-- | migrate/changeset/schema.py | 58 |
1 files changed, 50 insertions, 8 deletions
diff --git a/migrate/changeset/schema.py b/migrate/changeset/schema.py index 913b90f..a0e42cc 100644 --- a/migrate/changeset/schema.py +++ b/migrate/changeset/schema.py @@ -1,10 +1,14 @@ """ Schema module providing common schema operations. """ +import abc +try: # Python 3 + from collections import MutableMapping as DictMixin +except ImportError: # Python 2 + from UserDict import DictMixin import warnings -from UserDict import DictMixin - +import six import sqlalchemy from sqlalchemy.schema import ForeignKeyConstraint @@ -163,7 +167,39 @@ def _to_index(index, table=None, engine=None): return ret -class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem): + +# Python3: if we just use: +# +# class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem): +# ... +# +# We get the following error: +# TypeError: metaclass conflict: the metaclass of a derived class must be a +# (non-strict) subclass of the metaclasses of all its bases. +# +# The complete inheritance/metaclass relationship list of ColumnDelta can be +# summarized by this following dot file: +# +# digraph test123 { +# ColumnDelta -> MutableMapping; +# MutableMapping -> Mapping; +# Mapping -> {Sized Iterable Container}; +# {Sized Iterable Container} -> ABCMeta[style=dashed]; +# +# ColumnDelta -> SchemaItem; +# SchemaItem -> {SchemaEventTarget Visitable}; +# SchemaEventTarget -> object; +# Visitable -> {VisitableType object} [style=dashed]; +# VisitableType -> type; +# } +# +# We need to use a metaclass that inherits from all the metaclasses of +# DictMixin and sqlalchemy.schema.SchemaItem. Let's call it "MyMeta". +class MyMeta(sqlalchemy.sql.visitors.VisitableType, abc.ABCMeta, object): + pass + + +class ColumnDelta(six.with_metaclass(MyMeta, DictMixin, sqlalchemy.schema.SchemaItem)): """Extracts the differences between two columns/column-parameters May receive parameters arranged in several different ways: @@ -229,7 +265,7 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem): diffs = self.compare_1_column(*p, **kw) else: # Zero columns specified - if not len(p) or not isinstance(p[0], basestring): + if not len(p) or not isinstance(p[0], six.string_types): raise ValueError("First argument must be column name") diffs = self.compare_parameters(*p, **kw) @@ -254,6 +290,12 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem): def __delitem__(self, key): raise NotImplementedError + def __len__(self): + raise NotImplementedError + + def __iter__(self): + raise NotImplementedError + def keys(self): return self.diffs.keys() @@ -332,7 +374,7 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem): """Extracts data from p and modifies diffs""" p = list(p) while len(p): - if isinstance(p[0], basestring): + if isinstance(p[0], six.string_types): k.setdefault('name', p.pop(0)) elif isinstance(p[0], sqlalchemy.types.TypeEngine): k.setdefault('type', p.pop(0)) @@ -370,7 +412,7 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem): return getattr(self, '_table', None) def _set_table(self, table): - if isinstance(table, basestring): + if isinstance(table, six.string_types): if self.alter_metadata: if not self.meta: raise ValueError("metadata must be specified for table" @@ -587,7 +629,7 @@ populated with defaults if isinstance(cons,(ForeignKeyConstraint, UniqueConstraint)): for col_name in cons.columns: - if not isinstance(col_name,basestring): + if not isinstance(col_name,six.string_types): col_name = col_name.name if self.name==col_name: to_drop.add(cons) @@ -622,7 +664,7 @@ populated with defaults if (getattr(self, name[:-5]) and not obj): raise InvalidConstraintError("Column.create() accepts index_name," " primary_key_name and unique_name to generate constraints") - if not isinstance(obj, basestring) and obj is not None: + if not isinstance(obj, six.string_types) and obj is not None: raise InvalidConstraintError( "%s argument for column must be constraint name" % name) |