Remove explicit dependencies.

This commit is contained in:
Ryan Leckey
2013-07-10 01:32:57 -07:00
parent cb2d751cea
commit 08c38fd58b
10 changed files with 91 additions and 56 deletions

View File

@@ -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

View File

@@ -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=[

View File

@@ -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)

View File

@@ -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)

View File

@@ -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'

View File

@@ -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)

View File

@@ -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)

View File

@@ -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):

View File

@@ -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)

View File

@@ -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):