diff options
Diffstat (limited to 'lib/sqlalchemy')
33 files changed, 81 insertions, 631 deletions
diff --git a/lib/sqlalchemy/dialects/mssql/information_schema.py b/lib/sqlalchemy/dialects/mssql/information_schema.py index fa0386faa..f16d3b6a0 100644 --- a/lib/sqlalchemy/dialects/mssql/information_schema.py +++ b/lib/sqlalchemy/dialects/mssql/information_schema.py @@ -9,7 +9,6 @@ from ... import cast from ... import Column from ... import MetaData from ... import Table -from ... import util from ...ext.compiler import compiles from ...sql import expression from ...types import Boolean @@ -27,11 +26,6 @@ class CoerceUnicode(TypeDecorator): impl = Unicode cache_ok = True - def process_bind_param(self, value, dialect): - if util.py2k and isinstance(value, util.binary_type): - value = value.decode(dialect.encoding) - return value - def bind_expression(self, bindvalue): return _cast_on_2005(bindvalue) diff --git a/lib/sqlalchemy/dialects/oracle/base.py b/lib/sqlalchemy/dialects/oracle/base.py index c0bf985e5..9e62b931d 100644 --- a/lib/sqlalchemy/dialects/oracle/base.py +++ b/lib/sqlalchemy/dialects/oracle/base.py @@ -2468,8 +2468,6 @@ class OracleDialect(default.DefaultDialect): rp = connection.execute(sql.text(text), params).scalar() if rp: - if util.py2k: - rp = rp.decode(self.encoding) return rp else: return None diff --git a/lib/sqlalchemy/dialects/oracle/cx_oracle.py b/lib/sqlalchemy/dialects/oracle/cx_oracle.py index 3e705dced..38e864898 100644 --- a/lib/sqlalchemy/dialects/oracle/cx_oracle.py +++ b/lib/sqlalchemy/dialects/oracle/cx_oracle.py @@ -468,7 +468,6 @@ from ... import processors from ... import types as sqltypes from ... import util from ...engine import cursor as _cursor -from ...util import compat class _OracleInteger(sqltypes.Integer): @@ -745,24 +744,7 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): " cx_oracle" % (bindparam.key, bindparam.type) ) - if compat.py2k and dbtype in ( - cx_Oracle.CLOB, - cx_Oracle.NCLOB, - ): - outconverter = ( - processors.to_unicode_processor_factory( - self.dialect.encoding, - errors=self.dialect.encoding_errors, - ) - ) - self.out_parameters[name] = self.cursor.var( - dbtype, - outconverter=lambda value: outconverter( - value.read() - ), - ) - - elif dbtype in ( + if dbtype in ( cx_Oracle.BLOB, cx_Oracle.CLOB, cx_Oracle.NCLOB, @@ -770,18 +752,6 @@ class OracleExecutionContext_cx_oracle(OracleExecutionContext): self.out_parameters[name] = self.cursor.var( dbtype, outconverter=lambda value: value.read() ) - elif compat.py2k and isinstance( - type_impl, sqltypes.Unicode - ): - outconverter = ( - processors.to_unicode_processor_factory( - self.dialect.encoding, - errors=self.dialect.encoding_errors, - ) - ) - self.out_parameters[name] = self.cursor.var( - dbtype, outconverter=outconverter - ) else: self.out_parameters[name] = self.cursor.var(dbtype) self.parameters[0][ @@ -1182,45 +1152,23 @@ class OracleDialect_cx_oracle(OracleDialect): and default_type is not cx_Oracle.CLOB and default_type is not cx_Oracle.NCLOB ): - if compat.py2k: - outconverter = processors.to_unicode_processor_factory( - dialect.encoding, errors=dialect.encoding_errors - ) - return cursor.var( - cx_Oracle.STRING, - size, - cursor.arraysize, - outconverter=outconverter, - ) - else: - return cursor.var( - util.text_type, - size, - cursor.arraysize, - **dialect._cursor_var_unicode_kwargs - ) + return cursor.var( + util.text_type, + size, + cursor.arraysize, + **dialect._cursor_var_unicode_kwargs + ) elif dialect.auto_convert_lobs and default_type in ( cx_Oracle.CLOB, cx_Oracle.NCLOB, ): - if compat.py2k: - outconverter = processors.to_unicode_processor_factory( - dialect.encoding, errors=dialect.encoding_errors - ) - return cursor.var( - cx_Oracle.LONG_STRING, - size, - cursor.arraysize, - outconverter=outconverter, - ) - else: - return cursor.var( - cx_Oracle.LONG_STRING, - size, - cursor.arraysize, - **dialect._cursor_var_unicode_kwargs - ) + return cursor.var( + cx_Oracle.LONG_STRING, + size, + cursor.arraysize, + **dialect._cursor_var_unicode_kwargs + ) elif dialect.auto_convert_lobs and default_type in ( cx_Oracle.BLOB, diff --git a/lib/sqlalchemy/dialects/postgresql/hstore.py b/lib/sqlalchemy/dialects/postgresql/hstore.py index a4090f1ac..85d678ef5 100644 --- a/lib/sqlalchemy/dialects/postgresql/hstore.py +++ b/lib/sqlalchemy/dialects/postgresql/hstore.py @@ -228,42 +228,20 @@ class HSTORE(sqltypes.Indexable, sqltypes.Concatenable, sqltypes.TypeEngine): comparator_factory = Comparator def bind_processor(self, dialect): - if util.py2k: - encoding = dialect.encoding - - def process(value): - if isinstance(value, dict): - return _serialize_hstore(value).encode(encoding) - else: - return value - - else: - - def process(value): - if isinstance(value, dict): - return _serialize_hstore(value) - else: - return value + def process(value): + if isinstance(value, dict): + return _serialize_hstore(value) + else: + return value return process def result_processor(self, dialect, coltype): - if util.py2k: - encoding = dialect.encoding - - def process(value): - if value is not None: - return _parse_hstore(value.decode(encoding)) - else: - return value - - else: - - def process(value): - if value is not None: - return _parse_hstore(value) - else: - return value + def process(value): + if value is not None: + return _parse_hstore(value) + else: + return value return process diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py index 7512ab9b5..162ddde94 100644 --- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py +++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py @@ -478,7 +478,6 @@ from .base import _ColonCast from .base import _DECIMAL_TYPES from .base import _FLOAT_TYPES from .base import _INT_TYPES -from .base import ENUM from .base import PGCompiler from .base import PGDialect from .base import PGExecutionContext @@ -527,22 +526,6 @@ class _PGNumeric(sqltypes.Numeric): ) -class _PGEnum(ENUM): - def result_processor(self, dialect, coltype): - if util.py2k and self._expect_unicode is True: - # for py2k, if the enum type needs unicode data (which is set up as - # part of the Enum() constructor based on values passed as py2k - # unicode objects) we have to use our own converters since - # psycopg2's don't work, a rare exception to the "modern DBAPIs - # support unicode everywhere" theme of deprecating - # convert_unicode=True. Use the special "force_nocheck" directive - # which forces unicode conversion to happen on the Python side - # without an isinstance() check. in py3k psycopg2 does the right - # thing automatically. - self._expect_unicode = "force_nocheck" - return super(_PGEnum, self).result_processor(dialect, coltype) - - class _PGHStore(HSTORE): def bind_processor(self, dialect): if dialect._has_native_hstore: @@ -664,16 +647,6 @@ class PGDialect_psycopg2(PGDialect): driver = "psycopg2" supports_statement_cache = True - - if util.py2k: - # turn off supports_unicode_statements for Python 2. psycopg2 supports - # unicode statements in Py2K. But! it does not support unicode *bound - # parameter names* because it uses the Python "%" operator to - # interpolate these into the string, and this fails. So for Py2K, we - # have to use full-on encoding for statements and parameters before - # passing to cursor.execute(). - supports_unicode_statements = False - supports_server_side_cursors = True default_paramstyle = "pyformat" @@ -694,8 +667,6 @@ class PGDialect_psycopg2(PGDialect): PGDialect.colspecs, { sqltypes.Numeric: _PGNumeric, - ENUM: _PGEnum, # needs force_unicode - sqltypes.Enum: _PGEnum, # needs force_unicode HSTORE: _PGHStore, JSON: _PGJSON, sqltypes.JSON: _PGJSON, @@ -718,7 +689,7 @@ class PGDialect_psycopg2(PGDialect): ): PGDialect.__init__(self, **kwargs) self.use_native_unicode = use_native_unicode - if not use_native_unicode and not util.py2k: + if not use_native_unicode: raise exc.ArgumentError( "psycopg2 native_unicode mode is required under Python 3" ) @@ -854,7 +825,6 @@ class PGDialect_psycopg2(PGDialect): def on_connect(self): extras = self._psycopg2_extras - extensions = self._psycopg2_extensions fns = [] if self.client_encoding is not None: @@ -878,14 +848,6 @@ class PGDialect_psycopg2(PGDialect): fns.append(on_connect) - if util.py2k and self.dbapi and self.use_native_unicode: - - def on_connect(conn): - extensions.register_type(extensions.UNICODE, conn) - extensions.register_type(extensions.UNICODEARRAY, conn) - - fns.append(on_connect) - if self.dbapi and self.use_native_hstore: def on_connect(conn): @@ -893,8 +855,6 @@ class PGDialect_psycopg2(PGDialect): if hstore_oids is not None: oid, array_oid = hstore_oids kw = {"oid": oid} - if util.py2k: - kw["unicode"] = True kw["array_oid"] = array_oid extras.register_hstore(conn, **kw) diff --git a/lib/sqlalchemy/dialects/sqlite/pysqlite.py b/lib/sqlalchemy/dialects/sqlite/pysqlite.py index e9d5d9682..10912e0d5 100644 --- a/lib/sqlalchemy/dialects/sqlite/pysqlite.py +++ b/lib/sqlalchemy/dialects/sqlite/pysqlite.py @@ -454,23 +454,14 @@ class SQLiteDialect_pysqlite(SQLiteDialect): }, ) - if not util.py2k: - description_encoding = None + description_encoding = None driver = "pysqlite" @classmethod def dbapi(cls): - if util.py2k: - try: - from pysqlite2 import dbapi2 as sqlite - except ImportError: - try: - from sqlite3 import dbapi2 as sqlite - except ImportError as e: - raise e - else: - from sqlite3 import dbapi2 as sqlite + from sqlite3 import dbapi2 as sqlite + return sqlite @classmethod diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py index 373c90804..9ec6783b0 100644 --- a/lib/sqlalchemy/engine/default.py +++ b/lib/sqlalchemy/engine/default.py @@ -464,12 +464,7 @@ class DefaultDialect(interfaces.Dialect): return self.get_isolation_level(dbapi_conn) def _check_unicode_returns(self, connection, additional_tests=None): - # this now runs in py2k only and will be removed in 2.0; disabled for - # Python 3 in all cases under #5315 - if util.py2k and not self.supports_unicode_statements: - cast_to = util.binary_type - else: - cast_to = util.text_type + cast_to = util.text_type if self.positional: parameters = self.execute_sequence_format() @@ -523,12 +518,7 @@ class DefaultDialect(interfaces.Dialect): ) def _check_unicode_description(self, connection): - # all DBAPIs on Py2K return cursor.description as encoded - - if util.py2k and not self.supports_unicode_statements: - cast_to = util.binary_type - else: - cast_to = util.text_type + cast_to = util.text_type cursor = connection.connection.cursor() try: @@ -722,9 +712,6 @@ class DefaultDialect(interfaces.Dialect): def normalize_name(self, name): if name is None: return None - if util.py2k: - if isinstance(name, str): - name = name.decode(self.encoding) name_lower = name.lower() name_upper = name.upper() @@ -763,11 +750,6 @@ class DefaultDialect(interfaces.Dialect): self.identifier_preparer._requires_quotes )(name_lower): name = name_upper - if util.py2k: - if not self.supports_unicode_binds: - name = name.encode(self.encoding) - else: - name = unicode(name) # noqa return name def get_driver_connection(self, connection): @@ -968,12 +950,7 @@ class DefaultExecutionContext(interfaces.ExecutionContext): self.executemany = len(parameters) > 1 - # this must occur before create_cursor() since the statement - # has to be regexed in some cases for server side cursor - if util.py2k: - self.unicode_statement = util.text_type(compiled.string) - else: - self.unicode_statement = compiled.string + self.unicode_statement = compiled.string self.cursor = self.create_cursor() diff --git a/lib/sqlalchemy/engine/reflection.py b/lib/sqlalchemy/engine/reflection.py index 21d68a1a2..fed353e9c 100644 --- a/lib/sqlalchemy/engine/reflection.py +++ b/lib/sqlalchemy/engine/reflection.py @@ -766,12 +766,6 @@ class Inspector(object): # returned them table._validate_dialect_kwargs(tbl_opts) - if util.py2k: - if isinstance(schema, str): - schema = schema.decode(dialect.encoding) - if isinstance(table_name, str): - table_name = table_name.decode(dialect.encoding) - found_table = False cols_by_orig_name = {} diff --git a/lib/sqlalchemy/engine/result.py b/lib/sqlalchemy/engine/result.py index 79b07ab91..113cdcf35 100644 --- a/lib/sqlalchemy/engine/result.py +++ b/lib/sqlalchemy/engine/result.py @@ -20,7 +20,6 @@ from ..sql.base import _generative from ..sql.base import HasMemoized from ..sql.base import InPlaceGenerative from ..util import collections_abc -from ..util import py2k if _baserow_usecext: @@ -658,7 +657,6 @@ class ResultInternal(InPlaceGenerative): class _WithKeys(object): # used mainly to share documentation on the keys method. - # py2k does not allow overriding the __doc__ attribute. def keys(self): """Return an iterable view which yields the string keys that would be represented by each :class:`.Row`. @@ -946,11 +944,6 @@ class Result(_WithKeys, ResultInternal): def __next__(self): return self._next_impl() - if py2k: - - def next(self): # noqa - return self._next_impl() - def partitions(self, size=None): """Iterate through sub-lists of rows of the size given. @@ -1347,11 +1340,6 @@ class ScalarResult(FilterResult): def __next__(self): return self._next_impl() - if py2k: - - def next(self): # noqa - return self._next_impl() - def first(self): """Fetch the first object or None if no object is present. @@ -1490,11 +1478,6 @@ class MappingResult(_WithKeys, FilterResult): def __next__(self): return self._next_impl() - if py2k: - - def next(self): # noqa - return self._next_impl() - def first(self): """Fetch the first object or None if no object is present. diff --git a/lib/sqlalchemy/engine/url.py b/lib/sqlalchemy/engine/url.py index 488f73952..be330eb6c 100644 --- a/lib/sqlalchemy/engine/url.py +++ b/lib/sqlalchemy/engine/url.py @@ -745,8 +745,6 @@ def _parse_rfc1738_args(name): query = {} for key, value in util.parse_qsl(components["query"]): - if util.py2k: - key = key.encode("ascii") if key in query: query[key] = util.to_list(query[key]) query[key].append(value) diff --git a/lib/sqlalchemy/ext/associationproxy.py b/lib/sqlalchemy/ext/associationproxy.py index dd5c10ac9..a93f2c229 100644 --- a/lib/sqlalchemy/ext/associationproxy.py +++ b/lib/sqlalchemy/ext/associationproxy.py @@ -1295,30 +1295,11 @@ class _AssociationDict(_AssociationCollection): def keys(self): return self.col.keys() - if util.py2k: + def items(self): + return ((key, self._get(self.col[key])) for key in self.col) - def iteritems(self): - return ((key, self._get(self.col[key])) for key in self.col) - - def itervalues(self): - return (self._get(self.col[key]) for key in self.col) - - def iterkeys(self): - return self.col.iterkeys() - - def values(self): - return [self._get(member) for member in self.col.values()] - - def items(self): - return [(k, self._get(self.col[k])) for k in self] - - else: - - def items(self): - return ((key, self._get(self.col[key])) for key in self.col) - - def values(self): - return (self._get(self.col[key]) for key in self.col) + def values(self): + return (self._get(self.col[key]) for key in self.col) def pop(self, key, default=_NotProvided): if default is _NotProvided: diff --git a/lib/sqlalchemy/orm/collections.py b/lib/sqlalchemy/orm/collections.py index ec4d00cb0..f9afd4ebf 100644 --- a/lib/sqlalchemy/orm/collections.py +++ b/lib/sqlalchemy/orm/collections.py @@ -1250,27 +1250,6 @@ def _list_decorators(): _tidy(__delitem__) return __delitem__ - if util.py2k: - - def __setslice__(fn): - def __setslice__(self, start, end, values): - for value in self[start:end]: - __del(self, value) - values = [__set(self, value) for value in values] - fn(self, start, end, values) - - _tidy(__setslice__) - return __setslice__ - - def __delslice__(fn): - def __delslice__(self, start, end): - for value in self[start:end]: - __del(self, value) - fn(self, start, end) - - _tidy(__delslice__) - return __delslice__ - def extend(fn): def extend(self, iterable): for value in iterable: @@ -1300,16 +1279,14 @@ def _list_decorators(): _tidy(pop) return pop - if not util.py2k: - - def clear(fn): - def clear(self, index=-1): - for item in self: - __del(self, item) - fn(self) + def clear(fn): + def clear(self, index=-1): + for item in self: + __del(self, item) + fn(self) - _tidy(clear) - return clear + _tidy(clear) + return clear # __imul__ : not wrapping this. all members of the collection are already # present, so no need to fire appends... wrapping it with an explicit diff --git a/lib/sqlalchemy/orm/evaluator.py b/lib/sqlalchemy/orm/evaluator.py index 69d80dd8b..fcc7368c4 100644 --- a/lib/sqlalchemy/orm/evaluator.py +++ b/lib/sqlalchemy/orm/evaluator.py @@ -33,7 +33,6 @@ _straight_ops = set( "add", "mul", "sub", - "div", "mod", "truediv", "lt", diff --git a/lib/sqlalchemy/orm/identity.py b/lib/sqlalchemy/orm/identity.py index 6aea0d185..10d924b48 100644 --- a/lib/sqlalchemy/orm/identity.py +++ b/lib/sqlalchemy/orm/identity.py @@ -9,7 +9,6 @@ import weakref from . import util as orm_util from .. import exc as sa_exc -from .. import util class IdentityMap(object): @@ -201,19 +200,8 @@ class WeakInstanceDict(IdentityMap): def __iter__(self): return iter(self.keys()) - if util.py2k: - - def iteritems(self): - return iter(self.items()) - - def itervalues(self): - return iter(self.values()) - def all_states(self): - if util.py2k: - return self._dict.values() - else: - return list(self._dict.values()) + return list(self._dict.values()) def _fast_discard(self, state): # used by InstanceState for state being diff --git a/lib/sqlalchemy/orm/instrumentation.py b/lib/sqlalchemy/orm/instrumentation.py index 02fc73793..626643ce1 100644 --- a/lib/sqlalchemy/orm/instrumentation.py +++ b/lib/sqlalchemy/orm/instrumentation.py @@ -628,12 +628,8 @@ def __init__(%(apply_pos)s): func_vars = util.format_argspec_init(original_init, grouped=False) func_text = func_body % func_vars - if util.py2k: - func = getattr(original_init, "im_func", original_init) - func_defaults = getattr(func, "func_defaults", None) - else: - func_defaults = getattr(original_init, "__defaults__", None) - func_kw_defaults = getattr(original_init, "__kwdefaults__", None) + func_defaults = getattr(original_init, "__defaults__", None) + func_kw_defaults = getattr(original_init, "__kwdefaults__", None) env = locals().copy() env["__name__"] = __name__ @@ -644,7 +640,7 @@ def __init__(%(apply_pos)s): if func_defaults: __init__.__defaults__ = func_defaults - if not util.py2k and func_kw_defaults: + if func_kw_defaults: __init__.__kwdefaults__ = func_kw_defaults return __init__ diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 7a2333d91..bcede5d76 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -175,7 +175,6 @@ OPERATORS = { operators.add: " + ", operators.mul: " * ", operators.sub: " - ", - operators.div: " / ", operators.mod: " % ", operators.truediv: " / ", operators.neg: "-", diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py index e883454de..f1fe46fd2 100644 --- a/lib/sqlalchemy/sql/elements.py +++ b/lib/sqlalchemy/sql/elements.py @@ -5158,15 +5158,6 @@ class quoted_name(util.MemoizedSlots, util.text_type): else: return util.text_type(self).upper() - def __repr__(self): - if util.py2k: - backslashed = self.encode("ascii", "backslashreplace") - if not util.py2k: - backslashed = backslashed.decode("ascii") - return "'%s'" % backslashed - else: - return str.__repr__(self) - def _find_columns(clause): """locate Column objects within the given expression.""" diff --git a/lib/sqlalchemy/sql/operators.py b/lib/sqlalchemy/sql/operators.py index 695e086b8..b64bea07a 100644 --- a/lib/sqlalchemy/sql/operators.py +++ b/lib/sqlalchemy/sql/operators.py @@ -33,12 +33,6 @@ from operator import truediv from .. import util -if util.py2k: - from operator import div -else: - div = truediv - - class Operators(object): """Base of comparison and logical operators. @@ -1130,14 +1124,6 @@ class ColumnOperators(Operators): """ return self.reverse_operate(mul, other) - def __rdiv__(self, other): - """Implement the ``/`` operator in reverse. - - See :meth:`.ColumnOperators.__div__`. - - """ - return self.reverse_operate(div, other) - def __rmod__(self, other): """Implement the ``%`` operator in reverse. @@ -1223,14 +1209,6 @@ class ColumnOperators(Operators): """ return self.operate(mul, other) - def __div__(self, other): - """Implement the ``/`` operator. - - In a column context, produces the clause ``a / b``. - - """ - return self.operate(div, other) - def __mod__(self, other): """Implement the ``%`` operator. @@ -1240,7 +1218,7 @@ class ColumnOperators(Operators): return self.operate(mod, other) def __truediv__(self, other): - """Implement the ``//`` operator. + """Implement the ``/`` operator. In a column context, produces the clause ``a / b``. @@ -1248,7 +1226,7 @@ class ColumnOperators(Operators): return self.operate(truediv, other) def __rtruediv__(self, other): - """Implement the ``//`` operator in reverse. + """Implement the ``/`` operator in reverse. See :meth:`.ColumnOperators.__truediv__`. @@ -1610,7 +1588,6 @@ _PRECEDENCE = { json_path_getitem_op: 15, mul: 8, truediv: 8, - div: 8, mod: 8, neg: 8, add: 7, diff --git a/lib/sqlalchemy/sql/sqltypes.py b/lib/sqlalchemy/sql/sqltypes.py index ae589d648..77af76d0b 100644 --- a/lib/sqlalchemy/sql/sqltypes.py +++ b/lib/sqlalchemy/sql/sqltypes.py @@ -555,7 +555,6 @@ class Integer(_LookupExpressionAdapter, TypeEngine): Integer: self.__class__, Numeric: Numeric, }, - operators.div: {Integer: self.__class__, Numeric: Numeric}, operators.truediv: {Integer: self.__class__, Numeric: Numeric}, operators.sub: {Integer: self.__class__, Numeric: Numeric}, } @@ -753,7 +752,6 @@ class Numeric(_LookupExpressionAdapter, TypeEngine): Numeric: self.__class__, Integer: self.__class__, }, - operators.div: {Numeric: self.__class__, Integer: self.__class__}, operators.truediv: { Numeric: self.__class__, Integer: self.__class__, @@ -985,20 +983,13 @@ class _Binary(TypeEngine): # Python 3 has native bytes() type # both sqlite3 and pg8000 seem to return it, # psycopg2 as of 2.5 returns 'memoryview' - if util.py2k: - - def result_processor(self, dialect, coltype): - return processors.to_str - - else: - - def result_processor(self, dialect, coltype): - def process(value): - if value is not None: - value = bytes(value) - return value + def result_processor(self, dialect, coltype): + def process(value): + if value is not None: + value = bytes(value) + return value - return process + return process def coerce_compared_value(self, op, value): """See :meth:`.TypeEngine.coerce_compared_value` for a description.""" @@ -1494,14 +1485,7 @@ class Enum(Emulated, String, SchemaType): self.validate_strings = kw.pop("validate_strings", False) if convert_unicode is None: - for e in self.enums: - # this is all py2k logic that can go away for py3k only, - # "expect unicode" will always be implicitly true - if isinstance(e, util.text_type): - _expect_unicode = True - break - else: - _expect_unicode = False + _expect_unicode = True else: _expect_unicode = convert_unicode @@ -2011,7 +1995,6 @@ class _AbstractInterval(_LookupExpressionAdapter, TypeEngine): operators.sub: {Interval: self.__class__}, operators.mul: {Numeric: self.__class__}, operators.truediv: {Numeric: self.__class__}, - operators.div: {Numeric: self.__class__}, } @property diff --git a/lib/sqlalchemy/sql/type_api.py b/lib/sqlalchemy/sql/type_api.py index 2a4688bcc..f58851268 100644 --- a/lib/sqlalchemy/sql/type_api.py +++ b/lib/sqlalchemy/sql/type_api.py @@ -800,12 +800,7 @@ class TypeEngine(Traversible): return default.StrCompileDialect() def __str__(self): - if util.py2k: - return unicode(self.compile()).encode( # noqa - "ascii", "backslashreplace" - ) # noqa - else: - return str(self.compile()) + return str(self.compile()) def __repr__(self): return util.generic_repr(self) diff --git a/lib/sqlalchemy/testing/exclusions.py b/lib/sqlalchemy/testing/exclusions.py index d5522289b..e8fce5a4c 100644 --- a/lib/sqlalchemy/testing/exclusions.py +++ b/lib/sqlalchemy/testing/exclusions.py @@ -139,16 +139,10 @@ class compound(object): def _expect_failure(self, config, ex, name="block"): for fail in self.fails: if fail(config): - if util.py2k: - str_ex = unicode(ex).encode( # noqa: F821 - "utf-8", errors="ignore" - ) - else: - str_ex = str(ex) print( ( "%s failed as expected (%s): %s " - % (name, fail._as_string(config), str_ex) + % (name, fail._as_string(config), ex) ) ) break diff --git a/lib/sqlalchemy/testing/plugin/bootstrap.py b/lib/sqlalchemy/testing/plugin/bootstrap.py index b4691c57d..1220561e8 100644 --- a/lib/sqlalchemy/testing/plugin/bootstrap.py +++ b/lib/sqlalchemy/testing/plugin/bootstrap.py @@ -41,10 +41,6 @@ def load_file_as_module(name): if to_bootstrap == "pytest": sys.modules["sqla_plugin_base"] = load_file_as_module("plugin_base") sys.modules["sqla_plugin_base"].bootstrapped_as_sqlalchemy = True - if sys.version_info < (3, 0): - sys.modules["sqla_reinvent_fixtures"] = load_file_as_module( - "reinvent_fixtures_py2k" - ) sys.modules["sqla_pytestplugin"] = load_file_as_module("pytestplugin") else: raise Exception("unknown bootstrap: %s" % to_bootstrap) # noqa diff --git a/lib/sqlalchemy/testing/plugin/pytestplugin.py b/lib/sqlalchemy/testing/plugin/pytestplugin.py index 6c6287060..36aaa5d2a 100644 --- a/lib/sqlalchemy/testing/plugin/pytestplugin.py +++ b/lib/sqlalchemy/testing/plugin/pytestplugin.py @@ -25,14 +25,6 @@ except ImportError: has_xdist = False -py2k = sys.version_info < (3, 0) -if py2k: - try: - import sqla_reinvent_fixtures as reinvent_fixtures_py2k - except ImportError: - from . import reinvent_fixtures_py2k - - def pytest_addoption(parser): group = parser.getgroup("sqlalchemy") @@ -238,10 +230,6 @@ def pytest_collection_modifyitems(session, config, items): else: newitems.append(item) - if py2k: - for item in newitems: - reinvent_fixtures_py2k.scan_for_fixtures_to_use_for_class(item) - # seems like the functions attached to a test class aren't sorted already? # is that true and why's that? (when using unittest, they're sorted) items[:] = sorted( @@ -340,9 +328,7 @@ def _parametrize_cls(module, cls): for arg, val in zip(argname_split, param.values): cls_variables[arg] = val parametrized_name = "_".join( - # token is a string, but in py2k pytest is giving us a unicode, - # so call str() on it. - str(re.sub(r"\W", "", token)) + re.sub(r"\W", "", token) for param in full_param_set for token in param.id.split("-") ) @@ -457,14 +443,8 @@ def setup_class_methods(request): if hasattr(cls, "setup_test_class"): asyncio._maybe_async(cls.setup_test_class) - if py2k: - reinvent_fixtures_py2k.run_class_fixture_setup(request) - yield - if py2k: - reinvent_fixtures_py2k.run_class_fixture_teardown(request) - if hasattr(cls, "teardown_test_class"): asyncio._maybe_async(cls.teardown_test_class) @@ -484,9 +464,7 @@ def setup_test_methods(request): # 1. function level "autouse" fixtures under py3k (examples: TablesTest # define tables / data, MappedTest define tables / mappers / data) - # 2. run homegrown function level "autouse" fixtures under py2k - if py2k: - reinvent_fixtures_py2k.run_fn_fixture_setup(request) + # 2. was for p2k. no longer applies # 3. run outer xdist-style setup if hasattr(self, "setup_test"): @@ -529,9 +507,7 @@ def setup_test_methods(request): if hasattr(self, "teardown_test"): asyncio._maybe_async(self.teardown_test) - # 11. run homegrown function-level "autouse" fixtures under py2k - if py2k: - reinvent_fixtures_py2k.run_fn_fixture_teardown(request) + # 11. was for p2k. no longer applies # 12. function level "autouse" fixtures under py3k (examples: TablesTest / # MappedTest delete table data, possibly drop tables and clear mappers @@ -778,17 +754,8 @@ class PytestFixtureFunctions(plugin_base.FixtureFunctions): fn = asyncio._maybe_async_wrapper(fn) # other wrappers may be added here - if py2k and "autouse" in kw: - # py2k workaround for too-slow collection of autouse fixtures - # in pytest 4.6.11. See notes in reinvent_fixtures_py2k for - # rationale. - - # comment this condition out in order to disable the - # py2k workaround entirely. - reinvent_fixtures_py2k.add_fixture(fn, fixture) - else: - # now apply FixtureFunctionMarker - fn = fixture(fn) + # now apply FixtureFunctionMarker + fn = fixture(fn) return fn diff --git a/lib/sqlalchemy/testing/plugin/reinvent_fixtures_py2k.py b/lib/sqlalchemy/testing/plugin/reinvent_fixtures_py2k.py deleted file mode 100644 index 36b68417b..000000000 --- a/lib/sqlalchemy/testing/plugin/reinvent_fixtures_py2k.py +++ /dev/null @@ -1,112 +0,0 @@ -""" -invent a quick version of pytest autouse fixtures as pytest's unacceptably slow -collection/high memory use in pytest 4.6.11, which is the highest version that -works in py2k. - -by "too-slow" we mean the test suite can't even manage to be collected for a -single process in less than 70 seconds or so and memory use seems to be very -high as well. for two or four workers the job just times out after ten -minutes. - -so instead we have invented a very limited form of these fixtures, as our -current use of "autouse" fixtures are limited to those in fixtures.py. - -assumptions for these fixtures: - -1. we are only using "function" or "class" scope - -2. the functions must be associated with a test class - -3. the fixture functions cannot themselves use pytest fixtures - -4. the fixture functions must use yield, not return - -When py2k support is removed and we can stay on a modern pytest version, this -can all be removed. - - -""" -import collections - - -_py2k_fixture_fn_names = collections.defaultdict(set) -_py2k_class_fixtures = collections.defaultdict( - lambda: collections.defaultdict(set) -) -_py2k_function_fixtures = collections.defaultdict( - lambda: collections.defaultdict(set) -) - -_py2k_cls_fixture_stack = [] -_py2k_fn_fixture_stack = [] - - -def add_fixture(fn, fixture): - assert fixture.scope in ("class", "function") - _py2k_fixture_fn_names[fn.__name__].add((fn, fixture.scope)) - - -def scan_for_fixtures_to_use_for_class(item): - test_class = item.parent.parent.obj - - for name in _py2k_fixture_fn_names: - for fixture_fn, scope in _py2k_fixture_fn_names[name]: - meth = getattr(test_class, name, None) - if meth and meth.im_func is fixture_fn: - for sup in test_class.__mro__: - if name in sup.__dict__: - if scope == "class": - _py2k_class_fixtures[test_class][sup].add(meth) - elif scope == "function": - _py2k_function_fixtures[test_class][sup].add(meth) - break - break - - -def run_class_fixture_setup(request): - - cls = request.cls - self = cls.__new__(cls) - - fixtures_for_this_class = _py2k_class_fixtures.get(cls) - - if fixtures_for_this_class: - for sup_ in cls.__mro__: - for fn in fixtures_for_this_class.get(sup_, ()): - iter_ = fn(self) - next(iter_) - - _py2k_cls_fixture_stack.append(iter_) - - -def run_class_fixture_teardown(request): - while _py2k_cls_fixture_stack: - iter_ = _py2k_cls_fixture_stack.pop(-1) - try: - next(iter_) - except StopIteration: - pass - - -def run_fn_fixture_setup(request): - cls = request.cls - self = request.instance - - fixtures_for_this_class = _py2k_function_fixtures.get(cls) - - if fixtures_for_this_class: - for sup_ in reversed(cls.__mro__): - for fn in fixtures_for_this_class.get(sup_, ()): - iter_ = fn(self) - next(iter_) - - _py2k_fn_fixture_stack.append(iter_) - - -def run_fn_fixture_teardown(request): - while _py2k_fn_fixture_stack: - iter_ = _py2k_fn_fixture_stack.pop(-1) - try: - next(iter_) - except StopIteration: - pass diff --git a/lib/sqlalchemy/testing/requirements.py b/lib/sqlalchemy/testing/requirements.py index 3cf5c853e..8b385b5d2 100644 --- a/lib/sqlalchemy/testing/requirements.py +++ b/lib/sqlalchemy/testing/requirements.py @@ -1218,45 +1218,6 @@ class SuiteRequirements(Requirements): return exclusions.only_if(check) @property - def python2(self): - return exclusions.skip_if( - lambda: sys.version_info >= (3,), - "Python version 2.xx is required.", - ) - - @property - def python3(self): - return exclusions.skip_if( - lambda: sys.version_info < (3,), "Python version 3.xx is required." - ) - - @property - def pep520(self): - return self.python36 - - @property - def insert_order_dicts(self): - return self.python37 - - @property - def python36(self): - return exclusions.skip_if( - lambda: sys.version_info < (3, 6), - "Python version 3.6 or greater is required.", - ) - - @property - def python37(self): - return exclusions.skip_if( - lambda: sys.version_info < (3, 7), - "Python version 3.7 or greater is required.", - ) - - @property - def dataclasses(self): - return self.python37 - - @property def cpython(self): return exclusions.only_if( lambda: util.cpython, "cPython interpreter needed" diff --git a/lib/sqlalchemy/testing/suite/test_dialect.py b/lib/sqlalchemy/testing/suite/test_dialect.py index c2c17d0dd..32dfdedad 100644 --- a/lib/sqlalchemy/testing/suite/test_dialect.py +++ b/lib/sqlalchemy/testing/suite/test_dialect.py @@ -19,7 +19,6 @@ from ... import Integer from ... import literal_column from ... import select from ... import String -from ...util import compat class ExceptionTest(fixtures.TablesTest): @@ -77,12 +76,7 @@ class ExceptionTest(fixtures.TablesTest): assert str(err.orig) in str(err) - # test that we are actually getting string on Py2k, unicode - # on Py3k. - if compat.py2k: - assert isinstance(err_str, str) - else: - assert isinstance(err_str, str) + assert isinstance(err_str, str) class IsolationLevelTest(fixtures.TestBase): diff --git a/lib/sqlalchemy/testing/suite/test_types.py b/lib/sqlalchemy/testing/suite/test_types.py index 22b85f398..93d37d4d5 100644 --- a/lib/sqlalchemy/testing/suite/test_types.py +++ b/lib/sqlalchemy/testing/suite/test_types.py @@ -873,8 +873,11 @@ class JSONTest(_LiteralRoundTripFixture, fixtures.TablesTest): ("numeric", 1234567.89), # this one "works" because the float value you see here is # lost immediately to floating point stuff - ("numeric", 99998969694839.983485848, requirements.python3), - ("numeric", 99939.983485848, requirements.python3), + ( + "numeric", + 99998969694839.983485848, + ), + ("numeric", 99939.983485848), ("_decimal", decimal.Decimal("1234567.89")), ( "_decimal", @@ -991,8 +994,7 @@ class JSONTest(_LiteralRoundTripFixture, fixtures.TablesTest): roundtrip = conn.scalar(select(expr)) eq_(roundtrip, compare_value) - if util.py3k: # skip py2k to avoid comparing unicode to str etc. - is_(type(roundtrip), type(compare_value)) + is_(type(roundtrip), type(compare_value)) @_index_fixtures(True) @testing.emits_warning(r".*does \*not\* support Decimal objects natively") diff --git a/lib/sqlalchemy/testing/suite/test_unicode_ddl.py b/lib/sqlalchemy/testing/suite/test_unicode_ddl.py index a4ae3348e..1334eb8db 100644 --- a/lib/sqlalchemy/testing/suite/test_unicode_ddl.py +++ b/lib/sqlalchemy/testing/suite/test_unicode_ddl.py @@ -6,7 +6,6 @@ from sqlalchemy import ForeignKey from sqlalchemy import Integer from sqlalchemy import MetaData from sqlalchemy import testing -from sqlalchemy import util from sqlalchemy.testing import eq_ from sqlalchemy.testing import fixtures from sqlalchemy.testing.schema import Column @@ -183,24 +182,12 @@ class UnicodeSchemaTest(fixtures.TablesTest): t = Table( ue("\u6e2c\u8a66"), meta, Column(ue("\u6e2c\u8a66_id"), Integer) ) - - if util.py2k: - eq_( - repr(t), - ( - "Table('\\u6e2c\\u8a66', MetaData(), " - "Column('\\u6e2c\\u8a66_id', Integer(), " - "table=<\u6e2c\u8a66>), " - "schema=None)" - ), - ) - else: - eq_( - repr(t), - ( - "Table('測試', MetaData(), " - "Column('測試_id', Integer(), " - "table=<測試>), " - "schema=None)" - ), - ) + eq_( + repr(t), + ( + "Table('測試', MetaData(), " + "Column('測試_id', Integer(), " + "table=<測試>), " + "schema=None)" + ), + ) diff --git a/lib/sqlalchemy/testing/util.py b/lib/sqlalchemy/testing/util.py index a4d55a8f2..982e57517 100644 --- a/lib/sqlalchemy/testing/util.py +++ b/lib/sqlalchemy/testing/util.py @@ -27,7 +27,6 @@ from ..util import decorator from ..util import defaultdict from ..util import has_refcount_gc from ..util import inspect_getfullargspec -from ..util import py2k if not has_refcount_gc: @@ -47,14 +46,6 @@ else: def picklers(): picklers = set() - if py2k: - try: - import cPickle - - picklers.add(cPickle) - except ImportError: - pass - import pickle picklers.add(pickle) @@ -65,19 +56,8 @@ def picklers(): yield pickle_.loads, lambda d: pickle_.dumps(d, protocol) -if py2k: - - def random_choices(population, k=1): - pop = list(population) - # lame but works :) - random.shuffle(pop) - return pop[0:k] - - -else: - - def random_choices(population, k=1): - return random.choices(population, k=k) +def random_choices(population, k=1): + return random.choices(population, k=k) def round_decimal(value, prec): diff --git a/lib/sqlalchemy/util/__init__.py b/lib/sqlalchemy/util/__init__.py index bdd69431e..327f76715 100644 --- a/lib/sqlalchemy/util/__init__.py +++ b/lib/sqlalchemy/util/__init__.py @@ -75,7 +75,6 @@ from .compat import parse_qsl from .compat import perf_counter from .compat import pickle from .compat import print_ -from .compat import py2k from .compat import py37 from .compat import py38 from .compat import py39 diff --git a/lib/sqlalchemy/util/_collections.py b/lib/sqlalchemy/util/_collections.py index 535ae4780..54ed522d4 100644 --- a/lib/sqlalchemy/util/_collections.py +++ b/lib/sqlalchemy/util/_collections.py @@ -16,7 +16,6 @@ import weakref from .compat import binary_types from .compat import collections_abc from .compat import itertools_filterfalse -from .compat import py2k from .compat import py37 from .compat import string_types from .compat import threading @@ -322,17 +321,6 @@ else: def items(self): return [(key, self[key]) for key in self._list] - if py2k: - - def itervalues(self): - return iter(self.values()) - - def iterkeys(self): - return iter(self) - - def iteritems(self): - return iter(self.items()) - def __setitem__(self, key, obj): if key not in self: try: diff --git a/lib/sqlalchemy/util/compat.py b/lib/sqlalchemy/util/compat.py index 5914e8681..5749b3337 100644 --- a/lib/sqlalchemy/util/compat.py +++ b/lib/sqlalchemy/util/compat.py @@ -18,7 +18,6 @@ py39 = sys.version_info >= (3, 9) py38 = sys.version_info >= (3, 8) py37 = sys.version_info >= (3, 7) py3k = sys.version_info >= (3, 0) -py2k = sys.version_info < (3, 0) pypy = platform.python_implementation() == "PyPy" diff --git a/lib/sqlalchemy/util/langhelpers.py b/lib/sqlalchemy/util/langhelpers.py index 89ca4c1eb..84c5fddec 100644 --- a/lib/sqlalchemy/util/langhelpers.py +++ b/lib/sqlalchemy/util/langhelpers.py @@ -304,7 +304,7 @@ def %(name)s(%(args)s): % (decorated.__module__,) ) - if compat.py2k or hasattr(fn, "__func__"): + if hasattr(fn, "__func__"): fn.__func__.__doc__ = doc if not hasattr(fn.__func__, "_linked_to"): fn.__func__._linked_to = (decorated, location) @@ -888,24 +888,12 @@ def class_hierarchy(cls): will not be descended. """ - if compat.py2k: - if isinstance(cls, types.ClassType): - return list() hier = {cls} process = list(cls.__mro__) while process: c = process.pop() - if compat.py2k: - if isinstance(c, types.ClassType): - continue - bases = ( - _ - for _ in c.__bases__ - if _ not in hier and not isinstance(_, types.ClassType) - ) - else: - bases = (_ for _ in c.__bases__ if _ not in hier) + bases = (_ for _ in c.__bases__ if _ not in hier) for b in bases: process.append(b) |
