Various python 3.x compatibility fixes.
This commit is contained in:
@@ -1,9 +1,9 @@
|
|||||||
language: python
|
language: python
|
||||||
python:
|
python:
|
||||||
- 2.5
|
|
||||||
- 2.6
|
- 2.6
|
||||||
- 2.7
|
- 2.7
|
||||||
|
- 3.3
|
||||||
install:
|
install:
|
||||||
- pip install -q -e . --use-mirrors
|
- pip install -q -e ".[test]" --use-mirrors
|
||||||
script:
|
script:
|
||||||
- python setup.py test
|
- python setup.py test
|
||||||
|
@@ -1,6 +0,0 @@
|
|||||||
-r requirements.txt
|
|
||||||
pytest==2.2.3
|
|
||||||
Pygments==1.2
|
|
||||||
Jinja2==2.3
|
|
||||||
docutils>=0.10
|
|
||||||
flexmock>=0.9.7
|
|
@@ -1,3 +0,0 @@
|
|||||||
SQLAlchemy>=0.8.0
|
|
||||||
phonenumbers>=5.4b1
|
|
||||||
colour==0.0.2
|
|
25
setup.py
25
setup.py
@@ -4,7 +4,6 @@ SQLAlchemy-Utils
|
|||||||
|
|
||||||
Various utility functions and custom data types for SQLAlchemy.
|
Various utility functions and custom data types for SQLAlchemy.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from setuptools import setup, Command
|
from setuptools import setup, Command
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
@@ -22,6 +21,7 @@ class PyTest(Command):
|
|||||||
errno = subprocess.call(['py.test'])
|
errno = subprocess.call(['py.test'])
|
||||||
raise SystemExit(errno)
|
raise SystemExit(errno)
|
||||||
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='SQLAlchemy-Utils',
|
name='SQLAlchemy-Utils',
|
||||||
version='0.13.3',
|
version='0.13.3',
|
||||||
@@ -37,11 +37,26 @@ setup(
|
|||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
platforms='any',
|
platforms='any',
|
||||||
install_requires=[
|
dependency_links=[
|
||||||
'SQLAlchemy>=0.8.0',
|
# 5.6 supports python 3.x / pending release
|
||||||
'phonenumbers>=5.4b1',
|
'git+git://github.com/daviddrysdale/python-phonenumbers.git@python3'
|
||||||
'colour==0.0.2'
|
'#egg=phonenumbers3k-5.6b1',
|
||||||
],
|
],
|
||||||
|
install_requires=[
|
||||||
|
'six',
|
||||||
|
'SQLAlchemy>=0.8.0',
|
||||||
|
'phonenumbers3k==5.6b1',
|
||||||
|
'colour>=0.0.3'
|
||||||
|
],
|
||||||
|
extras_require={
|
||||||
|
'test': [
|
||||||
|
'pytest==2.2.3',
|
||||||
|
'Pygments>=1.2',
|
||||||
|
'Jinja2>=2.3',
|
||||||
|
'docutils>=0.10',
|
||||||
|
'flexmock>=0.9.7',
|
||||||
|
]
|
||||||
|
},
|
||||||
cmdclass={'test': PyTest},
|
cmdclass={'test': PyTest},
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Environment :: Web Environment',
|
'Environment :: Web Environment',
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import six
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from sqlalchemy.engine import reflection
|
from sqlalchemy.engine import reflection
|
||||||
from sqlalchemy.orm import object_session, mapperlib
|
from sqlalchemy.orm import object_session, mapperlib
|
||||||
@@ -51,7 +52,7 @@ class Merger(object):
|
|||||||
|
|
||||||
def raw_merge(self, session, table, old_values, new_values):
|
def raw_merge(self, session, table, old_values, new_values):
|
||||||
conditions = []
|
conditions = []
|
||||||
for key, value in old_values.items():
|
for key, value in six.iteritems(old_values):
|
||||||
conditions.append(getattr(table.c, key) == value)
|
conditions.append(getattr(table.c, key) == value)
|
||||||
sql = (
|
sql = (
|
||||||
table
|
table
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import six
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import six
|
||||||
import phonenumbers
|
import phonenumbers
|
||||||
from colour import Color
|
from colour import Color
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
@@ -56,7 +57,7 @@ class PhoneNumber(phonenumbers.phonenumber.PhoneNumber):
|
|||||||
return self.national
|
return self.national
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return unicode(self).encode('utf-8')
|
return six.text_type(self.national).encode('utf-8')
|
||||||
|
|
||||||
|
|
||||||
class PhoneNumberType(types.TypeDecorator):
|
class PhoneNumberType(types.TypeDecorator):
|
||||||
@@ -95,7 +96,7 @@ class ColorType(types.TypeDecorator):
|
|||||||
Changes Color objects to a string representation on the way in and
|
Changes Color objects to a string representation on the way in and
|
||||||
changes them back to Color objects on the way out.
|
changes them back to Color objects on the way out.
|
||||||
"""
|
"""
|
||||||
STORE_FORMAT = 'hex'
|
STORE_FORMAT = u'hex'
|
||||||
impl = types.Unicode(20)
|
impl = types.Unicode(20)
|
||||||
|
|
||||||
def __init__(self, max_length=20, *args, **kwargs):
|
def __init__(self, max_length=20, *args, **kwargs):
|
||||||
@@ -104,7 +105,7 @@ class ColorType(types.TypeDecorator):
|
|||||||
|
|
||||||
def process_bind_param(self, value, dialect):
|
def process_bind_param(self, value, dialect):
|
||||||
if value:
|
if value:
|
||||||
return getattr(value, self.STORE_FORMAT)
|
return six.text_type(getattr(value, self.STORE_FORMAT))
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def process_result_value(self, value, dialect):
|
def process_result_value(self, value, dialect):
|
||||||
@@ -125,22 +126,22 @@ class ScalarListException(Exception):
|
|||||||
class ScalarListType(types.TypeDecorator):
|
class ScalarListType(types.TypeDecorator):
|
||||||
impl = sa.UnicodeText()
|
impl = sa.UnicodeText()
|
||||||
|
|
||||||
def __init__(self, coerce_func=unicode, separator=u','):
|
def __init__(self, coerce_func=six.text_type, separator=u','):
|
||||||
self.separator = unicode(separator)
|
self.separator = six.text_type(separator)
|
||||||
self.coerce_func = coerce_func
|
self.coerce_func = coerce_func
|
||||||
|
|
||||||
def process_bind_param(self, value, dialect):
|
def process_bind_param(self, value, dialect):
|
||||||
# Convert list of values to unicode separator-separated list
|
# Convert list of values to unicode separator-separated list
|
||||||
# Example: [1, 2, 3, 4] -> u'1, 2, 3, 4'
|
# Example: [1, 2, 3, 4] -> u'1, 2, 3, 4'
|
||||||
if value is not None:
|
if value is not None:
|
||||||
if any(self.separator in unicode(item) for item in value):
|
if any(self.separator in six.text_type(item) for item in value):
|
||||||
raise ScalarListException(
|
raise ScalarListException(
|
||||||
"List values can't contain string '%s' (its being used as "
|
"List values can't contain string '%s' (its being used as "
|
||||||
"separator. If you wish for scalar list values to contain "
|
"separator. If you wish for scalar list values to contain "
|
||||||
"these strings, use a different separator string."
|
"these strings, use a different separator string."
|
||||||
)
|
)
|
||||||
return self.separator.join(
|
return self.separator.join(
|
||||||
map(unicode, value)
|
map(six.text_type, value)
|
||||||
)
|
)
|
||||||
|
|
||||||
def process_result_value(self, value, dialect):
|
def process_result_value(self, value, dialect):
|
||||||
@@ -148,9 +149,9 @@ class ScalarListType(types.TypeDecorator):
|
|||||||
if value == u'':
|
if value == u'':
|
||||||
return []
|
return []
|
||||||
# coerce each value
|
# coerce each value
|
||||||
return map(
|
return list(map(
|
||||||
self.coerce_func, value.split(self.separator)
|
self.coerce_func, value.split(self.separator)
|
||||||
)
|
))
|
||||||
|
|
||||||
|
|
||||||
class EmailType(sa.types.TypeDecorator):
|
class EmailType(sa.types.TypeDecorator):
|
||||||
@@ -181,7 +182,7 @@ class NumberRangeType(types.TypeDecorator):
|
|||||||
|
|
||||||
def process_result_value(self, value, dialect):
|
def process_result_value(self, value, dialect):
|
||||||
if value:
|
if value:
|
||||||
if not isinstance(value, basestring):
|
if not isinstance(value, six.string_types):
|
||||||
value = NumberRange.from_range_object(value)
|
value = NumberRange.from_range_object(value)
|
||||||
else:
|
else:
|
||||||
return NumberRange.from_normalized_str(value)
|
return NumberRange.from_normalized_str(value)
|
||||||
@@ -189,7 +190,7 @@ class NumberRangeType(types.TypeDecorator):
|
|||||||
|
|
||||||
def coercion_listener(self, target, value, oldvalue, initiator):
|
def coercion_listener(self, target, value, oldvalue, initiator):
|
||||||
if value is not None and not isinstance(value, NumberRange):
|
if value is not None and not isinstance(value, NumberRange):
|
||||||
if isinstance(value, basestring):
|
if isinstance(value, six.string_types):
|
||||||
value = NumberRange.from_normalized_str(value)
|
value = NumberRange.from_normalized_str(value)
|
||||||
else:
|
else:
|
||||||
raise TypeError
|
raise TypeError
|
||||||
@@ -252,7 +253,7 @@ class NumberRange(object):
|
|||||||
min_value, max_value = map(
|
min_value, max_value = map(
|
||||||
lambda a: int(a.strip()), values
|
lambda a: int(a.strip()), values
|
||||||
)
|
)
|
||||||
except ValueError, e:
|
except ValueError as e:
|
||||||
raise NumberRangeException(e.message)
|
raise NumberRangeException(e.message)
|
||||||
|
|
||||||
if value[0] == '(':
|
if value[0] == '(':
|
||||||
@@ -274,8 +275,8 @@ class NumberRange(object):
|
|||||||
min_value, max_value = map(
|
min_value, max_value = map(
|
||||||
lambda a: int(a.strip()), values
|
lambda a: int(a.strip()), values
|
||||||
)
|
)
|
||||||
except ValueError, e:
|
except ValueError as e:
|
||||||
raise NumberRangeException(e.message)
|
raise NumberRangeException(str(e))
|
||||||
return cls(min_value, max_value)
|
return cls(min_value, max_value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@@ -20,9 +20,7 @@ def count_sql_calls(conn, cursor, statement, parameters, context, executemany):
|
|||||||
|
|
||||||
class TestCase(object):
|
class TestCase(object):
|
||||||
def setup_method(self, method):
|
def setup_method(self, method):
|
||||||
self.engine = create_engine(
|
self.engine = create_engine('sqlite:///:memory:')
|
||||||
'postgres://postgres@localhost/sqlalchemy_utils_test'
|
|
||||||
)
|
|
||||||
self.connection = self.engine.connect()
|
self.connection = self.engine.connect()
|
||||||
self.Base = declarative_base()
|
self.Base = declarative_base()
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
import six
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from sqlalchemy_utils import ScalarListType
|
from sqlalchemy_utils import ScalarListType
|
||||||
from pytest import raises
|
from pytest import raises
|
||||||
@@ -33,7 +34,7 @@ class TestScalarUnicodeList(TestCase):
|
|||||||
class User(self.Base):
|
class User(self.Base):
|
||||||
__tablename__ = 'user'
|
__tablename__ = 'user'
|
||||||
id = sa.Column(sa.Integer, primary_key=True)
|
id = sa.Column(sa.Integer, primary_key=True)
|
||||||
some_list = sa.Column(ScalarListType(unicode))
|
some_list = sa.Column(ScalarListType(six.text_type))
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'User(%r)' % self.id
|
return 'User(%r)' % self.id
|
||||||
|
Reference in New Issue
Block a user