Remove explicit dependencies.
This commit is contained in:
@@ -4,6 +4,6 @@ python:
|
||||
- 2.7
|
||||
- 3.3
|
||||
install:
|
||||
- pip install -q -e ".[test]" --use-mirrors
|
||||
- pip install -q -e ".[test,color,phone]" --use-mirrors
|
||||
script:
|
||||
- python setup.py test
|
||||
|
6
setup.py
6
setup.py
@@ -45,8 +45,6 @@ setup(
|
||||
install_requires=[
|
||||
'six',
|
||||
'SQLAlchemy>=0.8.0',
|
||||
'phonenumbers3k==5.6b1',
|
||||
'colour>=0.0.3'
|
||||
],
|
||||
extras_require={
|
||||
'test': [
|
||||
@@ -55,7 +53,9 @@ setup(
|
||||
'Jinja2>=2.3',
|
||||
'docutils>=0.10',
|
||||
'flexmock>=0.9.7',
|
||||
]
|
||||
],
|
||||
'phone': ['phonenumbers3k==5.6b1'],
|
||||
'color': ['colour>=0.0.3']
|
||||
},
|
||||
cmdclass={'test': PyTest},
|
||||
classifiers=[
|
||||
|
@@ -1,6 +1,15 @@
|
||||
import six
|
||||
from colour import Color
|
||||
from sqlalchemy import types
|
||||
from sqlalchemy_utils import ImproperlyConfigured
|
||||
|
||||
|
||||
try:
|
||||
import colour
|
||||
from colour import Color
|
||||
|
||||
except ImportError:
|
||||
colour = None
|
||||
Color = None
|
||||
|
||||
|
||||
class ColorType(types.TypeDecorator):
|
||||
@@ -12,6 +21,11 @@ class ColorType(types.TypeDecorator):
|
||||
impl = types.Unicode(20)
|
||||
|
||||
def __init__(self, max_length=20, *args, **kwargs):
|
||||
# Bail if colour is not found.
|
||||
if colour is None:
|
||||
raise ImproperlyConfigured(
|
||||
"'colour' is required to use 'ColorType'")
|
||||
|
||||
super(ColorType, self).__init__(*args, **kwargs)
|
||||
self.impl = types.Unicode(max_length)
|
||||
|
||||
|
@@ -1,9 +1,18 @@
|
||||
import six
|
||||
import phonenumbers
|
||||
from sqlalchemy import types
|
||||
from sqlalchemy_utils import ImproperlyConfigured
|
||||
|
||||
|
||||
class PhoneNumber(phonenumbers.phonenumber.PhoneNumber):
|
||||
try:
|
||||
import phonenumbers
|
||||
from phonenumbers.phonenumber import PhoneNumber as BasePhoneNumber
|
||||
|
||||
except ImportError:
|
||||
phonenumbers = None
|
||||
BasePhoneNumber = object
|
||||
|
||||
|
||||
class PhoneNumber(BasePhoneNumber):
|
||||
'''
|
||||
Extends a PhoneNumber class from `Python phonenumbers library`_. Adds
|
||||
different phone number formats to attributes, so they can be easily used
|
||||
@@ -21,6 +30,11 @@ class PhoneNumber(phonenumbers.phonenumber.PhoneNumber):
|
||||
Country code of the phone number.
|
||||
'''
|
||||
def __init__(self, raw_number, country_code=None):
|
||||
# Bail if phonenumbers is not found.
|
||||
if phonenumbers is None:
|
||||
raise ImproperlyConfigured(
|
||||
"'phonenumbers' is required to use 'PhoneNumber'")
|
||||
|
||||
self._phone_number = phonenumbers.parse(raw_number, country_code)
|
||||
super(PhoneNumber, self).__init__(
|
||||
country_code=self._phone_number.country_code,
|
||||
@@ -66,6 +80,11 @@ class PhoneNumberType(types.TypeDecorator):
|
||||
impl = types.Unicode(20)
|
||||
|
||||
def __init__(self, country_code='US', max_length=20, *args, **kwargs):
|
||||
# Bail if phonenumbers is not found.
|
||||
if phonenumbers is None:
|
||||
raise ImproperlyConfigured(
|
||||
"'phonenumbers' is required to use 'PhoneNumberType'")
|
||||
|
||||
super(PhoneNumberType, self).__init__(*args, **kwargs)
|
||||
self.country_code = country_code
|
||||
self.impl = types.Unicode(max_length)
|
||||
|
@@ -5,10 +5,7 @@ from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
|
||||
from sqlalchemy_utils import (
|
||||
InstrumentedList,
|
||||
PhoneNumberType,
|
||||
)
|
||||
from sqlalchemy_utils import InstrumentedList
|
||||
|
||||
|
||||
@sa.event.listens_for(sa.engine.Engine, 'before_cursor_execute')
|
||||
@@ -47,7 +44,6 @@ class TestCase(object):
|
||||
__tablename__ = 'user'
|
||||
id = sa.Column(sa.Integer, autoincrement=True, primary_key=True)
|
||||
name = sa.Column(sa.Unicode(255))
|
||||
phone_number = sa.Column(PhoneNumberType())
|
||||
|
||||
class Category(self.Base):
|
||||
__tablename__ = 'category'
|
||||
|
@@ -1,39 +0,0 @@
|
||||
from colour import Color
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy_utils import (
|
||||
ColorType,
|
||||
NumberRangeType,
|
||||
NumberRange,
|
||||
PhoneNumberType,
|
||||
PhoneNumber,
|
||||
coercion_listener
|
||||
)
|
||||
from tests import TestCase
|
||||
|
||||
|
||||
class TestCoercionListener(TestCase):
|
||||
def create_models(self):
|
||||
class User(self.Base):
|
||||
__tablename__ = 'user'
|
||||
id = sa.Column(sa.Integer, primary_key=True)
|
||||
fav_color = sa.Column(ColorType)
|
||||
phone_number = sa.Column(PhoneNumberType(country_code='FI'))
|
||||
number_of_friends = sa.Column(NumberRangeType)
|
||||
|
||||
def __repr__(self):
|
||||
return 'User(%r)' % self.id
|
||||
|
||||
self.User = User
|
||||
sa.event.listen(
|
||||
sa.orm.mapper, 'mapper_configured', coercion_listener
|
||||
)
|
||||
|
||||
def test_scalar_attributes_get_coerced_to_objects(self):
|
||||
user = self.User(
|
||||
fav_color='white',
|
||||
phone_number='050111222',
|
||||
number_of_friends='[12, 18]'
|
||||
)
|
||||
assert isinstance(user.fav_color, Color)
|
||||
assert isinstance(user.phone_number, PhoneNumber)
|
||||
assert isinstance(user.number_of_friends, NumberRange)
|
@@ -1,9 +1,11 @@
|
||||
from colour import Color
|
||||
from pytest import mark
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy_utils import ColorType
|
||||
from sqlalchemy_utils import ColorType, coercion_listener
|
||||
from sqlalchemy_utils.types import color
|
||||
from tests import TestCase
|
||||
|
||||
|
||||
@mark.xfail('color.colour is None')
|
||||
class TestColorType(TestCase):
|
||||
def create_models(self):
|
||||
class Document(self.Base):
|
||||
@@ -15,8 +17,12 @@ class TestColorType(TestCase):
|
||||
return 'Document(%r)' % self.id
|
||||
|
||||
self.Document = Document
|
||||
sa.event.listen(sa.orm.mapper, 'mapper_configured', coercion_listener)
|
||||
|
||||
|
||||
def test_color_parameter_processing(self):
|
||||
from colour import Color
|
||||
|
||||
document = self.Document(
|
||||
bg_color=Color(u'white')
|
||||
)
|
||||
@@ -26,3 +32,10 @@ class TestColorType(TestCase):
|
||||
|
||||
document = self.session.query(self.Document).first()
|
||||
assert document.bg_color.hex == Color(u'white').hex
|
||||
|
||||
def test_scalar_attributes_get_coerced_to_objects(self):
|
||||
from colour import Color
|
||||
|
||||
document = self.Document(bg_color='white')
|
||||
|
||||
assert isinstance(document.bg_color, Color)
|
||||
|
@@ -1,7 +1,12 @@
|
||||
import sqlalchemy as sa
|
||||
from pytest import raises
|
||||
from sqlalchemy_utils import NumberRangeType, NumberRange, NumberRangeException
|
||||
from tests import TestCase
|
||||
from sqlalchemy_utils import (
|
||||
NumberRangeType,
|
||||
NumberRange,
|
||||
NumberRangeException,
|
||||
coercion_listener
|
||||
)
|
||||
|
||||
|
||||
class TestNumberRangeType(TestCase):
|
||||
@@ -15,6 +20,7 @@ class TestNumberRangeType(TestCase):
|
||||
return 'Building(%r)' % self.id
|
||||
|
||||
self.Building = Building
|
||||
sa.event.listen(sa.orm.mapper, 'mapper_configured', coercion_listener)
|
||||
|
||||
def test_save_number_range(self):
|
||||
building = self.Building(
|
||||
@@ -42,6 +48,11 @@ class TestNumberRangeType(TestCase):
|
||||
building = self.session.query(self.Building).first()
|
||||
assert building.persons_at_night is None
|
||||
|
||||
def test_scalar_attributes_get_coerced_to_objects(self):
|
||||
building = self.Building(persons_at_night='[12, 18]')
|
||||
|
||||
assert isinstance(building.persons_at_night, NumberRange)
|
||||
|
||||
|
||||
class TestNumberRange(object):
|
||||
def test_equality_operator(self):
|
||||
|
@@ -1,7 +1,11 @@
|
||||
from pytest import mark
|
||||
from tests import TestCase
|
||||
from sqlalchemy_utils import PhoneNumber
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy_utils import PhoneNumberType, PhoneNumber, coercion_listener
|
||||
from sqlalchemy_utils.types import phone_number
|
||||
|
||||
|
||||
@mark.xfail('phone_number.phonenumbers is None')
|
||||
class TestPhoneNumber(object):
|
||||
def setup_method(self, method):
|
||||
self.valid_phone_numbers = [
|
||||
@@ -45,7 +49,19 @@ class TestPhoneNumber(object):
|
||||
assert phone_number.__str__() == phone_number.national.encode('utf-8')
|
||||
|
||||
|
||||
@mark.xfail('phone_number.phonenumbers is None')
|
||||
class TestPhoneNumberType(TestCase):
|
||||
|
||||
def create_models(self):
|
||||
class User(self.Base):
|
||||
__tablename__ = 'user'
|
||||
id = sa.Column(sa.Integer, autoincrement=True, primary_key=True)
|
||||
name = sa.Column(sa.Unicode(255))
|
||||
phone_number = sa.Column(PhoneNumberType())
|
||||
|
||||
self.User = User
|
||||
sa.event.listen(sa.orm.mapper, 'mapper_configured', coercion_listener)
|
||||
|
||||
def setup_method(self, method):
|
||||
super(TestPhoneNumberType, self).setup_method(method)
|
||||
self.phone_number = PhoneNumber(
|
||||
@@ -83,3 +99,8 @@ class TestPhoneNumberType(TestCase):
|
||||
{'param': user.id}
|
||||
)
|
||||
assert result.first()[0] is None
|
||||
|
||||
def test_scalar_attributes_get_coerced_to_objects(self):
|
||||
user = self.User(phone_number='050111222')
|
||||
|
||||
assert isinstance(user.phone_number, PhoneNumber)
|
||||
|
@@ -17,7 +17,7 @@ class TestDeferExcept(TestCase):
|
||||
|
||||
|
||||
class TestFindNonIndexedForeignKeys(TestCase):
|
||||
dns = 'postgres://postgres@localhost/sqlalchemy_utils_test'
|
||||
# dns = 'postgres://postgres@localhost/sqlalchemy_utils_test'
|
||||
|
||||
def create_models(self):
|
||||
class User(self.Base):
|
||||
|
Reference in New Issue
Block a user