123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- from functools import total_ordering
- import six
- from .. import i18n
- from ..utils import str_coercible
- @total_ordering
- @str_coercible
- class Country(object):
- """
- Country class wraps a 2 to 3 letter country code. It provides various
- convenience properties and methods.
- ::
- from babel import Locale
- from sqlalchemy_utils import Country, i18n
- # First lets add a locale getter for testing purposes
- i18n.get_locale = lambda: Locale('en')
- Country('FI').name # Finland
- Country('FI').code # FI
- Country(Country('FI')).code # 'FI'
- Country always validates the given code if you use at least the optional
- dependency list 'babel', otherwise no validation are performed.
- ::
- Country(None) # raises TypeError
- Country('UnknownCode') # raises ValueError
- Country supports equality operators.
- ::
- Country('FI') == Country('FI')
- Country('FI') != Country('US')
- Country objects are hashable.
- ::
- assert hash(Country('FI')) == hash('FI')
- """
- def __init__(self, code_or_country):
- if isinstance(code_or_country, Country):
- self.code = code_or_country.code
- elif isinstance(code_or_country, six.string_types):
- self.validate(code_or_country)
- self.code = code_or_country
- else:
- raise TypeError(
- "Country() argument must be a string or a country, not '{0}'"
- .format(
- type(code_or_country).__name__
- )
- )
- @property
- def name(self):
- return i18n.get_locale().territories[self.code]
- @classmethod
- def validate(self, code):
- try:
- i18n.babel.Locale('en').territories[code]
- except KeyError:
- raise ValueError(
- 'Could not convert string to country code: {0}'.format(code)
- )
- except AttributeError:
- # As babel is optional, we may raise an AttributeError accessing it
- pass
- def __eq__(self, other):
- if isinstance(other, Country):
- return self.code == other.code
- elif isinstance(other, six.string_types):
- return self.code == other
- else:
- return NotImplemented
- def __hash__(self):
- return hash(self.code)
- def __ne__(self, other):
- return not (self == other)
- def __lt__(self, other):
- if isinstance(other, Country):
- return self.code < other.code
- elif isinstance(other, six.string_types):
- return self.code < other
- return NotImplemented
- def __repr__(self):
- return '%s(%r)' % (self.__class__.__name__, self.code)
- def __unicode__(self):
- return self.name
|