Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pendulum/locales/locale.py: 55%

69 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:35 +0000

1# -*- coding: utf-8 -*- 

2from __future__ import unicode_literals 

3 

4import os 

5import re 

6 

7from importlib import import_module 

8from typing import Any 

9from typing import Optional 

10from typing import Union 

11 

12from pendulum.utils._compat import basestring 

13from pendulum.utils._compat import decode 

14 

15 

16class Locale: 

17 """ 

18 Represent a specific locale. 

19 """ 

20 

21 _cache = {} 

22 

23 def __init__(self, locale, data): # type: (str, Any) -> None 

24 self._locale = locale 

25 self._data = data 

26 self._key_cache = {} 

27 

28 @classmethod 

29 def load(cls, locale): # type: (Union[str, Locale]) -> Locale 

30 if isinstance(locale, Locale): 

31 return locale 

32 

33 locale = cls.normalize_locale(locale) 

34 if locale in cls._cache: 

35 return cls._cache[locale] 

36 

37 # Checking locale existence 

38 actual_locale = locale 

39 locale_path = os.path.join(os.path.dirname(__file__), actual_locale) 

40 while not os.path.exists(locale_path): 

41 if actual_locale == locale: 

42 raise ValueError("Locale [{}] does not exist.".format(locale)) 

43 

44 actual_locale = actual_locale.split("_")[0] 

45 

46 m = import_module("pendulum.locales.{}.locale".format(actual_locale)) 

47 

48 cls._cache[locale] = cls(locale, m.locale) 

49 

50 return cls._cache[locale] 

51 

52 @classmethod 

53 def normalize_locale(cls, locale): # type: (str) -> str 

54 m = re.match("([a-z]{2})[-_]([a-z]{2})", locale, re.I) 

55 if m: 

56 return "{}_{}".format(m.group(1).lower(), m.group(2).lower()) 

57 else: 

58 return locale.lower() 

59 

60 def get(self, key, default=None): # type: (str, Optional[Any]) -> Any 

61 if key in self._key_cache: 

62 return self._key_cache[key] 

63 

64 parts = key.split(".") 

65 try: 

66 result = self._data[parts[0]] 

67 for part in parts[1:]: 

68 result = result[part] 

69 except KeyError: 

70 result = default 

71 

72 if isinstance(result, basestring): 

73 result = decode(result) 

74 

75 self._key_cache[key] = result 

76 

77 return self._key_cache[key] 

78 

79 def translation(self, key): # type: (str) -> Any 

80 return self.get("translations.{}".format(key)) 

81 

82 def plural(self, number): # type: (int) -> str 

83 return decode(self._data["plural"](number)) 

84 

85 def ordinal(self, number): # type: (int) -> str 

86 return decode(self._data["ordinal"](number)) 

87 

88 def ordinalize(self, number): # type: (int) -> str 

89 ordinal = self.get("custom.ordinal.{}".format(self.ordinal(number))) 

90 

91 if not ordinal: 

92 return decode("{}".format(number)) 

93 

94 return decode("{}{}".format(number, ordinal)) 

95 

96 def match_translation(self, key, value): 

97 translations = self.translation(key) 

98 if value not in translations.values(): 

99 return None 

100 

101 return {v: k for k, v in translations.items()}[value] 

102 

103 def __repr__(self): 

104 return "{}('{}')".format(self.__class__.__name__, self._locale)