Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/sqlalchemy_utils/primitives/currency.py: 39%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

41 statements  

1from .. import i18n, ImproperlyConfigured 

2from ..utils import str_coercible 

3 

4 

5@str_coercible 

6class Currency: 

7 """ 

8 Currency class wraps a 3-letter currency code. It provides various 

9 convenience properties and methods. 

10 

11 :: 

12 

13 from babel import Locale 

14 from sqlalchemy_utils import Currency, i18n 

15 

16 

17 # First lets add a locale getter for testing purposes 

18 i18n.get_locale = lambda: Locale('en') 

19 

20 

21 Currency('USD').name # US Dollar 

22 Currency('USD').symbol # $ 

23 

24 Currency(Currency('USD')).code # 'USD' 

25 

26 Currency always validates the given code if you use at least the optional 

27 dependency list 'babel', otherwise no validation are performed. 

28 

29 :: 

30 

31 Currency(None) # raises TypeError 

32 

33 Currency('UnknownCode') # raises ValueError 

34 

35 

36 Currency supports equality operators. 

37 

38 :: 

39 

40 Currency('USD') == Currency('USD') 

41 Currency('USD') != Currency('EUR') 

42 

43 

44 Currencies are hashable. 

45 

46 

47 :: 

48 

49 len(set([Currency('USD'), Currency('USD')])) # 1 

50 

51 

52 """ 

53 

54 def __init__(self, code): 

55 if i18n.babel is None: 

56 raise ImproperlyConfigured( 

57 "'babel' package is required in order to use Currency class." 

58 ) 

59 if isinstance(code, Currency): 

60 self.code = code 

61 elif isinstance(code, str): 

62 self.validate(code) 

63 self.code = code 

64 else: 

65 raise TypeError( 

66 'First argument given to Currency constructor should be ' 

67 'either an instance of Currency or valid three letter ' 

68 'currency code.' 

69 ) 

70 

71 @classmethod 

72 def validate(self, code): 

73 try: 

74 i18n.babel.Locale('en').currencies[code] 

75 except KeyError: 

76 raise ValueError(f"'{code}' is not valid currency code.") 

77 except AttributeError: 

78 # As babel is optional, we may raise an AttributeError accessing it 

79 pass 

80 

81 @property 

82 def symbol(self): 

83 return i18n.babel.numbers.get_currency_symbol(self.code, i18n.get_locale()) 

84 

85 @property 

86 def name(self): 

87 return i18n.get_locale().currencies[self.code] 

88 

89 def __eq__(self, other): 

90 if isinstance(other, Currency): 

91 return self.code == other.code 

92 elif isinstance(other, str): 

93 return self.code == other 

94 else: 

95 return NotImplemented 

96 

97 def __ne__(self, other): 

98 return not (self == other) 

99 

100 def __hash__(self): 

101 return hash(self.code) 

102 

103 def __repr__(self): 

104 return f'{self.__class__.__name__}({self.code!r})' 

105 

106 def __unicode__(self): 

107 return self.code