From: Hong Minhee Date: Fri, 12 Apr 2013 22:00:41 +0000 (+0900) Subject: Introduce compatibility module X-Git-Tag: rel_0_6_0~22^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8985077b31c371a3e97c38203a4af36c33728b73;p=thirdparty%2Fsqlalchemy%2Falembic.git Introduce compatibility module --- diff --git a/alembic/autogenerate.py b/alembic/autogenerate.py index 452fe7fe..348079a0 100644 --- a/alembic/autogenerate.py +++ b/alembic/autogenerate.py @@ -1,18 +1,16 @@ """Provide the 'autogenerate' feature which can produce migration operations automatically.""" -try: - import builtins -except ImportError: - import __builtin__ as builtins import logging import re -from . import util from sqlalchemy.engine.reflection import Inspector from sqlalchemy.util import OrderedSet from sqlalchemy import schema as sa_schema, types as sqltypes +from . import util +from .compat import string_types + log = logging.getLogger(__name__) ################################################### @@ -588,18 +586,17 @@ def _render_column(column, autogen_context): } def _render_server_default(default, autogen_context): - string_type = getattr(builtins, 'basestring', str) rendered = _user_defined_render("server_default", default, autogen_context) if rendered is not False: return rendered if isinstance(default, sa_schema.DefaultClause): - if isinstance(default.arg, string_type): + if isinstance(default.arg, string_types): default = default.arg else: default = str(default.arg.compile( dialect=autogen_context['dialect'])) - if isinstance(default, string_type): + if isinstance(default, string_types): # TODO: this is just a hack to get # tests to pass until we figure out # WTF sqlite is doing diff --git a/alembic/compat.py b/alembic/compat.py new file mode 100644 index 00000000..6619cb44 --- /dev/null +++ b/alembic/compat.py @@ -0,0 +1,29 @@ +import sys + + +py3k = sys.version_info >= (3, 0) +py3kwarning = getattr(sys, 'py3kwarning', False) or py3k +py26 = sys.version_info >= (2, 6) +jython = sys.platform.startswith('java') +win32 = sys.platform.startswith('win') +pypy = hasattr(sys, 'pypy_version_info') + +if py3k: + import builtins as compat_builtins + string_types = str, + binary_type = bytes + text_type = str +else: + import __builtin__ as compat_builtins + string_types = basestring, + binary_type = str + text_type = unicode + + +################################################ +# cross-compatible metaclass implementation +# Copyright (c) 2010-2012 Benjamin Peterson +def with_metaclass(meta, base=object): + """Create a base class with a metaclass.""" + return meta("%sBase" % meta.__name__, (base,), {}) +################################################ diff --git a/alembic/ddl/impl.py b/alembic/ddl/impl.py index af93349c..ab67e0c7 100644 --- a/alembic/ddl/impl.py +++ b/alembic/ddl/impl.py @@ -8,6 +8,7 @@ from sqlalchemy.ext.compiler import compiles from sqlalchemy import schema, text from sqlalchemy import types as sqltypes +from ..compat import string_types, text_type, with_metaclass from .. import util from . import base @@ -20,7 +21,7 @@ class ImplMeta(type): _impls = {} -class DefaultImpl(ImplMeta('_ImplBase', (object,), {})): +class DefaultImpl(with_metaclass(ImplMeta)): """Provide the entrypoint for major migration operations, including database-specific behavioral variances. @@ -54,7 +55,7 @@ class DefaultImpl(ImplMeta('_ImplBase', (object,), {})): return _impls[dialect.name] def static_output(self, text): - text_ = getattr(builtins, 'unicode', str)(text + '\n\n') + text_ = text_type(text + '\n\n') self.output_buffer.write(text_) if callable(getattr(self.output_buffer, 'flush', None)): self.output_buffer.flush() @@ -66,14 +67,13 @@ class DefaultImpl(ImplMeta('_ImplBase', (object,), {})): def _exec(self, construct, execution_options=None, multiparams=(), params=util.immutabledict()): - if isinstance(construct, getattr(builtins, 'basestring', str)): + if isinstance(construct, string_types): construct = text(construct) if self.as_sql: if multiparams or params: # TODO: coverage raise Exception("Execution arguments not allowed with as_sql") - unicode = getattr(builtins, 'unicode', str) - self.static_output(unicode( + self.static_output(text_type( construct.compile(dialect=self.dialect) ).replace("\t", " ").strip() + self.command_terminator) else: diff --git a/alembic/ddl/mysql.py b/alembic/ddl/mysql.py index 440eef15..ed48a59f 100644 --- a/alembic/ddl/mysql.py +++ b/alembic/ddl/mysql.py @@ -1,17 +1,13 @@ -try: - import builtins -except ImportError: - import __builtin__ as builtins - from sqlalchemy.ext.compiler import compiles from sqlalchemy import types as sqltypes from sqlalchemy import schema +from ..compat import string_types +from .. import util from .impl import DefaultImpl from .base import ColumnNullable, ColumnName, ColumnDefault, \ ColumnType, AlterColumn from .base import alter_table -from .. import util class MySQLImpl(DefaultImpl): __dialect__ = 'mysql' @@ -94,7 +90,7 @@ def _mysql_alter_column(element, compiler, **kw): ) def _render_value(compiler, expr): - if isinstance(expr, getattr(builtins, 'basestring', str)): + if isinstance(expr, string_types): return "'%s'" % expr else: return compiler.sql_compiler.process(expr) diff --git a/alembic/operations.py b/alembic/operations.py index 9f365024..441e54a2 100644 --- a/alembic/operations.py +++ b/alembic/operations.py @@ -1,13 +1,10 @@ -try: - import builtins -except ImportError: - import __builtin__ as builtins from contextlib import contextmanager from sqlalchemy.types import NULLTYPE, Integer from sqlalchemy import schema as sa_schema from . import util +from .compat import string_types from .ddl import impl __all__ = ('Operations',) @@ -147,7 +144,7 @@ class Operations(object): ForeignKey. """ - if isinstance(fk._colspec, getattr(builtins, 'basestring', str)): + if isinstance(fk._colspec, string_types): table_key, cname = fk._colspec.rsplit('.', 1) sname, tname = self._parse_table_key(table_key) if table_key not in metadata.tables: diff --git a/tests/__init__.py b/tests/__init__.py index 37f24d33..b838f384 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -22,6 +22,7 @@ from sqlalchemy.util import decorator import alembic from alembic import util +from alembic.compat import string_types, text_type from alembic.migration import MigrationContext from alembic.environment import EnvironmentContext from alembic.operations import Operations @@ -96,9 +97,8 @@ def _get_dialect(name): def assert_compiled(element, assert_string, dialect=None): dialect = _get_dialect(dialect) - unicode = getattr(builtins, 'unicode', str) eq_( - unicode(element.compile(dialect=dialect)).\ + text_type(element.compile(dialect=dialect)).\ replace("\n", "").replace("\t", ""), assert_string.replace("\n", "").replace("\t", "") ) @@ -151,7 +151,7 @@ def assert_raises_message(except_cls, msg, callable_, *args, **kwargs): assert False, "Callable did not raise an exception" except except_cls as e: assert re.search(msg, str(e)), "%r !~ %s" % (msg, e) - print(str(e)) + print(text_type(e)) def op_fixture(dialect='default', as_sql=False): impl = _impls[dialect] @@ -165,11 +165,9 @@ def op_fixture(dialect='default', as_sql=False): # as tests get more involved self.connection = None def _exec(self, construct, *args, **kw): - basestring = getattr(builtins, 'basestring', str) - unicode = getattr(builtins, 'unicode', str) - if isinstance(construct, basestring): + if isinstance(construct, string_types): construct = text(construct) - sql = unicode(construct.compile(dialect=self.dialect)) + sql = text_type(construct.compile(dialect=self.dialect)) sql = re.sub(r'[\n\t]', '', sql) self.assertion.append( sql diff --git a/tests/test_autogenerate.py b/tests/test_autogenerate.py index 4e8a05f9..c9400294 100644 --- a/tests/test_autogenerate.py +++ b/tests/test_autogenerate.py @@ -1,4 +1,3 @@ - import re import sys from unittest import TestCase