Make CI comparator smarter

This commit is contained in:
Konsta Vesterinen
2015-01-31 12:43:59 +02:00
parent 64e7ea4c62
commit a55544dafc
3 changed files with 41 additions and 6 deletions

View File

@@ -4,6 +4,12 @@ Changelog
Here you can see the full list of changes between each SQLAlchemy-Utils release. Here you can see the full list of changes between each SQLAlchemy-Utils release.
0.29.4 (2015-01-31)
^^^^^^^^^^^^^^^^^^^
- Made CaseInsensitiveComparator not cast already lowercased types to lowercase
0.29.3 (2015-01-24) 0.29.3 (2015-01-24)
^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^

View File

@@ -1,17 +1,41 @@
import sqlalchemy as sa import sqlalchemy as sa
def inspect_type(mixed):
if isinstance(mixed, sa.orm.attributes.InstrumentedAttribute):
return mixed.property.columns[0].type
elif isinstance(mixed, sa.orm.ColumnProperty):
return mixed.columns[0].type
elif isinstance(mixed, sa.Column):
return mixed.type
def is_case_insensitive(mixed):
try:
return isinstance(
inspect_type(mixed).comparator,
CaseInsensitiveComparator
)
except AttributeError:
try:
return issubclass(
inspect_type(mixed).comparator_factory,
CaseInsensitiveComparator
)
except AttributeError:
return False
class CaseInsensitiveComparator(sa.Unicode.Comparator): class CaseInsensitiveComparator(sa.Unicode.Comparator):
@classmethod @classmethod
def lowercase_arg(cls, func): def lowercase_arg(cls, func):
def operation(self, other, **kwargs): def operation(self, other, **kwargs):
operator = getattr(sa.Unicode.Comparator, func)
if other is None: if other is None:
return getattr(sa.Unicode.Comparator, func)( return operator(self, other, **kwargs)
self, other, **kwargs if not is_case_insensitive(other):
) other = sa.func.lower(other)
return getattr(sa.Unicode.Comparator, func)( return operator(self, other, **kwargs)
self, sa.func.lower(other), **kwargs
)
return operation return operation
def in_(self, other): def in_(self, other):

View File

@@ -42,3 +42,8 @@ class TestCaseInsensitiveComparator(TestCase):
'"user".email NOT IN (lower(:lower_1), lower(:lower_2))' '"user".email NOT IN (lower(:lower_1), lower(:lower_2))'
in str(query) in str(query)
) )
def test_does_not_apply_lower_to_types_that_are_already_lowercased(self):
assert str(self.User.email == self.User.email) == (
'"user".email = "user".email'
)