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