Merge branch 'choice_fixes' of https://github.com/dset0x/sqlalchemy-utils into dset0x-choice_fixes
This commit is contained in:
@@ -7,6 +7,7 @@ Here you can see the full list of changes between each SQLAlchemy-Utils release.
|
|||||||
0.30.11 (2015-06-18)
|
0.30.11 (2015-06-18)
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
- Fix None type handling of ChoiceType
|
||||||
- Make locale casting for translation hybrid expressions cast locales on compilation phase. This extra lazy locale casting is needed in some cases where translation hybrid expressions are used before get_locale
|
- Make locale casting for translation hybrid expressions cast locales on compilation phase. This extra lazy locale casting is needed in some cases where translation hybrid expressions are used before get_locale
|
||||||
function is available.
|
function is available.
|
||||||
|
|
||||||
|
@@ -92,4 +92,4 @@ from .types import ( # noqa
|
|||||||
WeekDaysType
|
WeekDaysType
|
||||||
)
|
)
|
||||||
|
|
||||||
__version__ = '0.30.10'
|
__version__ = '0.30.11'
|
||||||
|
@@ -214,10 +214,14 @@ class EnumTypeImpl(object):
|
|||||||
self.enum_class = enum_class
|
self.enum_class = enum_class
|
||||||
|
|
||||||
def _coerce(self, value):
|
def _coerce(self, value):
|
||||||
return self.enum_class(value) if value else None
|
if value is None:
|
||||||
|
return None
|
||||||
|
return self.enum_class(value)
|
||||||
|
|
||||||
def process_bind_param(self, value, dialect):
|
def process_bind_param(self, value, dialect):
|
||||||
return self.enum_class(value).value if value else None
|
if value is None:
|
||||||
|
return None
|
||||||
|
return self.enum_class(value).value
|
||||||
|
|
||||||
def process_result_value(self, value, dialect):
|
def process_result_value(self, value, dialect):
|
||||||
return self.enum_class(value) if value else None
|
return self._coerce(value)
|
||||||
|
@@ -84,27 +84,33 @@ class TestChoiceTypeWithCustomUnderlyingType(TestCase):
|
|||||||
class TestEnumType(TestCase):
|
class TestEnumType(TestCase):
|
||||||
def create_models(self):
|
def create_models(self):
|
||||||
class OrderStatus(Enum):
|
class OrderStatus(Enum):
|
||||||
unpaid = 1
|
unpaid = 0
|
||||||
paid = 2
|
paid = 1
|
||||||
|
|
||||||
class Order(self.Base):
|
class Order(self.Base):
|
||||||
__tablename__ = 'order'
|
__tablename__ = 'order'
|
||||||
id_ = sa.Column(sa.Integer, primary_key=True)
|
id_ = sa.Column(sa.Integer, primary_key=True)
|
||||||
status = sa.Column(
|
status = sa.Column(
|
||||||
ChoiceType(OrderStatus, impl=sa.Integer()),
|
ChoiceType(OrderStatus, impl=sa.Integer()),
|
||||||
default=OrderStatus.unpaid
|
default=OrderStatus.unpaid,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return 'Order(%r, %r)' % (self.id_, self.status)
|
return 'Order(%r, %r)' % (self.id_, self.status)
|
||||||
|
|
||||||
def pay(self):
|
class OrderNullable(self.Base):
|
||||||
self.status = OrderStatus.paid
|
__tablename__ = 'order_nullable'
|
||||||
|
id_ = sa.Column(sa.Integer, primary_key=True)
|
||||||
|
status = sa.Column(
|
||||||
|
ChoiceType(OrderStatus, impl=sa.Integer()),
|
||||||
|
nullable=True,
|
||||||
|
)
|
||||||
|
|
||||||
self.OrderStatus = OrderStatus
|
self.OrderStatus = OrderStatus
|
||||||
self.Order = Order
|
self.Order = Order
|
||||||
|
self.OrderNullable = OrderNullable
|
||||||
|
|
||||||
def test_parameter_processing(self):
|
def test_parameter_initialization(self):
|
||||||
order = self.Order()
|
order = self.Order()
|
||||||
|
|
||||||
self.session.add(order)
|
self.session.add(order)
|
||||||
@@ -112,20 +118,64 @@ class TestEnumType(TestCase):
|
|||||||
|
|
||||||
order = self.session.query(self.Order).first()
|
order = self.session.query(self.Order).first()
|
||||||
assert order.status is self.OrderStatus.unpaid
|
assert order.status is self.OrderStatus.unpaid
|
||||||
assert order.status.value == 1
|
assert order.status.value == 0
|
||||||
|
|
||||||
order.pay()
|
def test_setting_by_value(self):
|
||||||
self.session.commit()
|
|
||||||
|
|
||||||
order = self.session.query(self.Order).first()
|
|
||||||
assert order.status is self.OrderStatus.paid
|
|
||||||
assert order.status.value == 2
|
|
||||||
|
|
||||||
def test_parameter_coercing(self):
|
|
||||||
order = self.Order()
|
order = self.Order()
|
||||||
order.status = 2
|
order.status = 1
|
||||||
|
|
||||||
self.session.add(order)
|
self.session.add(order)
|
||||||
self.session.commit()
|
self.session.commit()
|
||||||
|
|
||||||
|
order = self.session.query(self.Order).first()
|
||||||
assert order.status is self.OrderStatus.paid
|
assert order.status is self.OrderStatus.paid
|
||||||
|
|
||||||
|
def test_setting_by_enum(self):
|
||||||
|
order = self.Order()
|
||||||
|
order.status = self.OrderStatus.paid
|
||||||
|
|
||||||
|
self.session.add(order)
|
||||||
|
self.session.commit()
|
||||||
|
|
||||||
|
order = self.session.query(self.Order).first()
|
||||||
|
assert order.status is self.OrderStatus.paid
|
||||||
|
|
||||||
|
def test_setting_value_that_resolves_to_none(self):
|
||||||
|
order = self.Order()
|
||||||
|
order.status = 0
|
||||||
|
|
||||||
|
self.session.add(order)
|
||||||
|
self.session.commit()
|
||||||
|
|
||||||
|
order = self.session.query(self.Order).first()
|
||||||
|
assert order.status is self.OrderStatus.unpaid
|
||||||
|
|
||||||
|
def test_setting_to_wrong_enum_raises_valueerror(self):
|
||||||
|
class WrongEnum(Enum):
|
||||||
|
foo = 0
|
||||||
|
bar = 1
|
||||||
|
|
||||||
|
order = self.Order()
|
||||||
|
|
||||||
|
with raises(ValueError):
|
||||||
|
order.status = WrongEnum.foo
|
||||||
|
|
||||||
|
def test_setting_to_uncoerceable_type_raises_valueerror(self):
|
||||||
|
order = self.Order()
|
||||||
|
with raises(ValueError):
|
||||||
|
order.status = 'Bad value'
|
||||||
|
|
||||||
|
def test_order_nullable_stores_none(self):
|
||||||
|
# With nullable=False as in `Order`, a `None` value is always
|
||||||
|
# converted to the default value, unless we explicitly set it to
|
||||||
|
# sqlalchemy.sql.null(), so we use this class to test our ability
|
||||||
|
# to set and retrive `None`.
|
||||||
|
order_nullable = self.OrderNullable()
|
||||||
|
assert order_nullable.status is None
|
||||||
|
|
||||||
|
order_nullable.status = None
|
||||||
|
|
||||||
|
self.session.add(order_nullable)
|
||||||
|
self.session.commit()
|
||||||
|
|
||||||
|
assert order_nullable.status is None
|
||||||
|
Reference in New Issue
Block a user