Added i18n module, bumped version
This commit is contained in:
@@ -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.16.13 (2013-09-17)
|
||||||
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
- Added global i18n module for configuration of locale dependant types
|
||||||
|
|
||||||
|
|
||||||
0.16.12 (2013-09-17)
|
0.16.12 (2013-09-17)
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -56,7 +56,7 @@ for name, requirements in extras_require.items():
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='SQLAlchemy-Utils',
|
name='SQLAlchemy-Utils',
|
||||||
version='0.16.12',
|
version='0.16.13',
|
||||||
url='https://github.com/kvesteri/sqlalchemy-utils',
|
url='https://github.com/kvesteri/sqlalchemy-utils',
|
||||||
license='BSD',
|
license='BSD',
|
||||||
author='Konsta Vesterinen, Ryan Leckey, Janne Vanhala, Vesa Uimonen',
|
author='Konsta Vesterinen, Ryan Leckey, Janne Vanhala, Vesa Uimonen',
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ from .types import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
__version__ = '0.16.12'
|
__version__ = '0.16.13'
|
||||||
|
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
|
|||||||
23
sqlalchemy_utils/i18n.py
Normal file
23
sqlalchemy_utils/i18n.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
from exceptions import ImproperlyConfigured
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
from babel.dates import get_day_names
|
||||||
|
except ImportError:
|
||||||
|
def get_day_names():
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
'Could not load get_day_names function from babel. Either install '
|
||||||
|
' babel or make a similar function and override it in this '
|
||||||
|
'module.'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
from flask.ext.babel import get_locale
|
||||||
|
except ImportError:
|
||||||
|
def get_locale():
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
'Could not load get_locale function from Flask-Babel. Either '
|
||||||
|
'install babel or make a similar function and override it '
|
||||||
|
'in this module.'
|
||||||
|
)
|
||||||
@@ -1,27 +1,16 @@
|
|||||||
from sqlalchemy import types
|
from sqlalchemy import types
|
||||||
import six
|
import six
|
||||||
from .scalar_coercible import ScalarCoercible
|
from .scalar_coercible import ScalarCoercible
|
||||||
from ..exceptions import ImproperlyConfigured
|
from sqlalchemy_utils import i18n
|
||||||
|
|
||||||
|
|
||||||
class Country(object):
|
class Country(object):
|
||||||
get_locale = None
|
def __init__(self, code):
|
||||||
|
|
||||||
def __init__(self, code, get_locale=None):
|
|
||||||
self.code = code
|
self.code = code
|
||||||
if get_locale is not None:
|
|
||||||
self.get_locale = get_locale
|
|
||||||
|
|
||||||
if self.get_locale is None:
|
|
||||||
raise ImproperlyConfigured(
|
|
||||||
"Country class needs to define get_locale."
|
|
||||||
)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
return six.get_method_function(
|
return i18n.get_locale().territories[self.code]
|
||||||
self.get_locale
|
|
||||||
)().territories[self.code]
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if isinstance(other, Country):
|
if isinstance(other, Country):
|
||||||
@@ -43,12 +32,6 @@ class CountryType(types.TypeDecorator, ScalarCoercible):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
impl = types.String(2)
|
impl = types.String(2)
|
||||||
get_locale = None
|
|
||||||
|
|
||||||
def __init__(self, get_locale=None, *args, **kwargs):
|
|
||||||
if get_locale is not None:
|
|
||||||
self.get_locale = get_locale
|
|
||||||
types.TypeDecorator.__init__(self, *args, **kwargs)
|
|
||||||
|
|
||||||
def process_bind_param(self, value, dialect):
|
def process_bind_param(self, value, dialect):
|
||||||
if isinstance(value, Country):
|
if isinstance(value, Country):
|
||||||
@@ -59,7 +42,7 @@ class CountryType(types.TypeDecorator, ScalarCoercible):
|
|||||||
|
|
||||||
def process_result_value(self, value, dialect):
|
def process_result_value(self, value, dialect):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
return Country(value, get_locale=self.get_locale)
|
return Country(value)
|
||||||
|
|
||||||
def _coerce(self, value):
|
def _coerce(self, value):
|
||||||
if value is not None and not isinstance(value, Country):
|
if value is not None and not isinstance(value, Country):
|
||||||
|
|||||||
@@ -3,43 +3,22 @@ import sys
|
|||||||
from sqlalchemy import types
|
from sqlalchemy import types
|
||||||
from sqlalchemy.dialects.postgresql import BIT
|
from sqlalchemy.dialects.postgresql import BIT
|
||||||
import six
|
import six
|
||||||
get_day_names = None
|
|
||||||
try:
|
|
||||||
from babel.dates import get_day_names
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
from ..compat import total_ordering
|
from ..compat import total_ordering
|
||||||
from ..exceptions import ImproperlyConfigured
|
from sqlalchemy_utils import i18n
|
||||||
|
|
||||||
|
|
||||||
def call_unbound(func, *args, **kwargs):
|
|
||||||
try:
|
|
||||||
return six.get_unbound_function(func)(*args, **kwargs)
|
|
||||||
except AttributeError:
|
|
||||||
return func(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
@total_ordering
|
@total_ordering
|
||||||
class WeekDay(object):
|
class WeekDay(object):
|
||||||
NUM_WEEK_DAYS = 7
|
NUM_WEEK_DAYS = 7
|
||||||
get_locale = None
|
|
||||||
|
|
||||||
def __init__(self, index, get_locale=None):
|
def __init__(self, index):
|
||||||
if not (0 <= index < self.NUM_WEEK_DAYS):
|
if not (0 <= index < self.NUM_WEEK_DAYS):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"index must be between 0 and %d" % self.NUM_WEEK_DAYS
|
"index must be between 0 and %d" % self.NUM_WEEK_DAYS
|
||||||
)
|
)
|
||||||
self.index = index
|
self.index = index
|
||||||
|
|
||||||
if get_locale is not None:
|
|
||||||
self.get_locale = get_locale
|
|
||||||
|
|
||||||
if self.get_locale is None:
|
|
||||||
raise ImproperlyConfigured(
|
|
||||||
"Weekday class needs to define get_locale."
|
|
||||||
)
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
if isinstance(other, WeekDay):
|
if isinstance(other, WeekDay):
|
||||||
return self.index == other.index
|
return self.index == other.index
|
||||||
@@ -62,10 +41,10 @@ class WeekDay(object):
|
|||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def get_name(self, width='wide', context='format'):
|
def get_name(self, width='wide', context='format'):
|
||||||
names = get_day_names(
|
names = i18n.get_day_names(
|
||||||
width,
|
width,
|
||||||
context,
|
context,
|
||||||
call_unbound(self.get_locale)
|
i18n.get_locale()
|
||||||
)
|
)
|
||||||
return names[self.index]
|
return names[self.index]
|
||||||
|
|
||||||
@@ -77,7 +56,7 @@ class WeekDay(object):
|
|||||||
def position(self):
|
def position(self):
|
||||||
return (
|
return (
|
||||||
self.index -
|
self.index -
|
||||||
call_unbound(self.get_locale).first_week_day
|
i18n.get_locale().first_week_day
|
||||||
) % self.NUM_WEEK_DAYS
|
) % self.NUM_WEEK_DAYS
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from sqlalchemy_utils import CountryType, Country
|
from sqlalchemy_utils import CountryType, Country, i18n
|
||||||
from tests import TestCase
|
from tests import TestCase
|
||||||
|
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ def get_locale():
|
|||||||
return Locale()
|
return Locale()
|
||||||
|
|
||||||
|
|
||||||
Country.get_locale = get_locale
|
i18n.get_locale = get_locale
|
||||||
|
|
||||||
|
|
||||||
class TestCountryType(TestCase):
|
class TestCountryType(TestCase):
|
||||||
|
|||||||
@@ -8,12 +8,13 @@ import pytest
|
|||||||
|
|
||||||
import six
|
import six
|
||||||
from sqlalchemy_utils.types import WeekDay, WeekDays
|
from sqlalchemy_utils.types import WeekDay, WeekDays
|
||||||
|
from sqlalchemy_utils import i18n
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif('Locale is None')
|
@pytest.mark.skipif('Locale is None')
|
||||||
class TestWeekDay(object):
|
class TestWeekDay(object):
|
||||||
def setup_method(self, method):
|
def setup_method(self, method):
|
||||||
WeekDay.get_locale = lambda: Locale('fi')
|
i18n.get_locale = lambda: Locale('fi')
|
||||||
|
|
||||||
def test_constructor_with_valid_index(self):
|
def test_constructor_with_valid_index(self):
|
||||||
day = WeekDay(1)
|
day = WeekDay(1)
|
||||||
@@ -58,17 +59,15 @@ class TestWeekDay(object):
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
def test_position(self, index, first_week_day, position):
|
def test_position(self, index, first_week_day, position):
|
||||||
fake_locale = flexmock(first_week_day=first_week_day)
|
i18n.get_locale = flexmock(first_week_day=first_week_day)
|
||||||
day = WeekDay(index, get_locale=lambda: fake_locale)
|
day = WeekDay(index)
|
||||||
assert day.position == position
|
assert day.position == position
|
||||||
|
|
||||||
def test_get_name_returns_localized_week_day_name(self):
|
def test_get_name_returns_localized_week_day_name(self):
|
||||||
locale = Locale('fi')
|
day = WeekDay(0)
|
||||||
day = WeekDay(0, get_locale=lambda: locale)
|
|
||||||
assert day.get_name() == u'maanantaina'
|
assert day.get_name() == u'maanantaina'
|
||||||
|
|
||||||
def test_override_get_locale_as_class_method(self):
|
def test_override_get_locale_as_class_method(self):
|
||||||
WeekDay.get_locale = lambda: Locale('fi')
|
|
||||||
day = WeekDay(0)
|
day = WeekDay(0)
|
||||||
assert day.get_name() == u'maanantaina'
|
assert day.get_name() == u'maanantaina'
|
||||||
|
|
||||||
@@ -150,13 +149,12 @@ class TestWeekDays(object):
|
|||||||
assert days != 0
|
assert days != 0
|
||||||
|
|
||||||
def test_iterator_starts_from_locales_first_week_day(self):
|
def test_iterator_starts_from_locales_first_week_day(self):
|
||||||
fake_locale = flexmock(first_week_day=1)
|
i18n.get_locale = lambda: flexmock(first_week_day=1)
|
||||||
WeekDay.get_locale = lambda: fake_locale
|
|
||||||
days = WeekDays('1111111')
|
days = WeekDays('1111111')
|
||||||
indices = list(day.index for day in days)
|
indices = list(day.index for day in days)
|
||||||
assert indices == [1, 2, 3, 4, 5, 6, 0]
|
assert indices == [1, 2, 3, 4, 5, 6, 0]
|
||||||
|
|
||||||
def test_unicode(self):
|
def test_unicode(self):
|
||||||
WeekDay.get_locale = lambda: Locale('fi')
|
i18n.get_locale = lambda: Locale('fi')
|
||||||
days = WeekDays('1000100')
|
days = WeekDays('1000100')
|
||||||
assert six.text_type(days) == u'maanantaina, perjantaina'
|
assert six.text_type(days) == u'maanantaina, perjantaina'
|
||||||
|
|||||||
Reference in New Issue
Block a user