__init__.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. """
  2. Internationalization support.
  3. """
  4. from __future__ import unicode_literals
  5. from django.utils.encoding import force_text
  6. from django.utils.functional import lazy
  7. from django.utils import six
  8. __all__ = [
  9. 'activate', 'deactivate', 'override', 'deactivate_all',
  10. 'get_language', 'get_language_from_request',
  11. 'get_language_info', 'get_language_bidi',
  12. 'check_for_language', 'to_locale', 'templatize', 'string_concat',
  13. 'gettext', 'gettext_lazy', 'gettext_noop',
  14. 'ugettext', 'ugettext_lazy', 'ugettext_noop',
  15. 'ngettext', 'ngettext_lazy',
  16. 'ungettext', 'ungettext_lazy',
  17. 'pgettext', 'pgettext_lazy',
  18. 'npgettext', 'npgettext_lazy',
  19. ]
  20. class TranslatorCommentWarning(SyntaxWarning):
  21. pass
  22. # Here be dragons, so a short explanation of the logic won't hurt:
  23. # We are trying to solve two problems: (1) access settings, in particular
  24. # settings.USE_I18N, as late as possible, so that modules can be imported
  25. # without having to first configure Django, and (2) if some other code creates
  26. # a reference to one of these functions, don't break that reference when we
  27. # replace the functions with their real counterparts (once we do access the
  28. # settings).
  29. class Trans(object):
  30. """
  31. The purpose of this class is to store the actual translation function upon
  32. receiving the first call to that function. After this is done, changes to
  33. USE_I18N will have no effect to which function is served upon request. If
  34. your tests rely on changing USE_I18N, you can delete all the functions
  35. from _trans.__dict__.
  36. Note that storing the function with setattr will have a noticeable
  37. performance effect, as access to the function goes the normal path,
  38. instead of using __getattr__.
  39. """
  40. def __getattr__(self, real_name):
  41. from django.conf import settings
  42. if settings.USE_I18N:
  43. from django.utils.translation import trans_real as trans
  44. else:
  45. from django.utils.translation import trans_null as trans
  46. setattr(self, real_name, getattr(trans, real_name))
  47. return getattr(trans, real_name)
  48. _trans = Trans()
  49. # The Trans class is no more needed, so remove it from the namespace.
  50. del Trans
  51. def gettext_noop(message):
  52. return _trans.gettext_noop(message)
  53. ugettext_noop = gettext_noop
  54. def gettext(message):
  55. return _trans.gettext(message)
  56. def ngettext(singular, plural, number):
  57. return _trans.ngettext(singular, plural, number)
  58. def ugettext(message):
  59. return _trans.ugettext(message)
  60. def ungettext(singular, plural, number):
  61. return _trans.ungettext(singular, plural, number)
  62. def pgettext(context, message):
  63. return _trans.pgettext(context, message)
  64. def npgettext(context, singular, plural, number):
  65. return _trans.npgettext(context, singular, plural, number)
  66. gettext_lazy = lazy(gettext, str)
  67. ngettext_lazy = lazy(ngettext, str)
  68. ugettext_lazy = lazy(ugettext, six.text_type)
  69. ungettext_lazy = lazy(ungettext, six.text_type)
  70. pgettext_lazy = lazy(pgettext, six.text_type)
  71. npgettext_lazy = lazy(npgettext, six.text_type)
  72. def activate(language):
  73. return _trans.activate(language)
  74. def deactivate():
  75. return _trans.deactivate()
  76. class override(object):
  77. def __init__(self, language, deactivate=False):
  78. self.language = language
  79. self.deactivate = deactivate
  80. self.old_language = get_language()
  81. def __enter__(self):
  82. if self.language is not None:
  83. activate(self.language)
  84. else:
  85. deactivate_all()
  86. def __exit__(self, exc_type, exc_value, traceback):
  87. if self.deactivate:
  88. deactivate()
  89. else:
  90. activate(self.old_language)
  91. def get_language():
  92. return _trans.get_language()
  93. def get_language_bidi():
  94. return _trans.get_language_bidi()
  95. def check_for_language(lang_code):
  96. return _trans.check_for_language(lang_code)
  97. def to_locale(language):
  98. return _trans.to_locale(language)
  99. def get_language_from_request(request, check_path=False):
  100. return _trans.get_language_from_request(request, check_path)
  101. def get_language_from_path(path):
  102. return _trans.get_language_from_path(path)
  103. def templatize(src, origin=None):
  104. return _trans.templatize(src, origin)
  105. def deactivate_all():
  106. return _trans.deactivate_all()
  107. def _string_concat(*strings):
  108. """
  109. Lazy variant of string concatenation, needed for translations that are
  110. constructed from multiple parts.
  111. """
  112. return ''.join([force_text(s) for s in strings])
  113. string_concat = lazy(_string_concat, six.text_type)
  114. def get_language_info(lang_code):
  115. from django.conf.locale import LANG_INFO
  116. try:
  117. return LANG_INFO[lang_code]
  118. except KeyError:
  119. raise KeyError("Unknown language code %r." % lang_code)