forked from Raiza.dev/EliteBot
110 lines
2.7 KiB
Python
110 lines
2.7 KiB
Python
from functools import total_ordering
|
|
|
|
from .. import i18n
|
|
from ..utils import str_coercible
|
|
|
|
|
|
@total_ordering
|
|
@str_coercible
|
|
class Country:
|
|
"""
|
|
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, str):
|
|
self.validate(code_or_country)
|
|
self.code = code_or_country
|
|
else:
|
|
raise TypeError(
|
|
"Country() argument must be a string or a country, not '{}'"
|
|
.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(
|
|
f'Could not convert string to country code: {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, str):
|
|
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, str):
|
|
return self.code < other
|
|
return NotImplemented
|
|
|
|
def __repr__(self):
|
|
return f'{self.__class__.__name__}({self.code!r})'
|
|
|
|
def __unicode__(self):
|
|
return self.name
|