Added i18n module, bumped version

This commit is contained in:
Konsta Vesterinen
2013-09-17 14:00:37 +03:00
parent 509ea0740e
commit 948d991932
8 changed files with 49 additions and 60 deletions

View File

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

View File

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

View File

@@ -38,7 +38,7 @@ from .types import (
)
__version__ = '0.16.12'
__version__ = '0.16.13'
__all__ = (

23
sqlalchemy_utils/i18n.py Normal file
View 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.'
)

View File

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

View File

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

View File

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

View File

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