Commit b41ebcf1 authored by Ramiro Morales's avatar Ramiro Morales
Browse files

Fixed #18040 -- Removed so-called project-level locale trees from the list of...

Fixed #18040 -- Removed so-called project-level locale trees from the list of paths the translation loading process takes in account.

Deprecated in Django 1.3. Removed completely for Django 1.5.

Thanks Claude for the review.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@17861 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent f38cf60c
Loading
Loading
Loading
Loading
+0 −18
Original line number Diff line number Diff line
"""
Internationalization support.
"""
import warnings
from os import path

from django.utils.encoding import force_unicode
from django.utils.functional import lazy
from django.utils.importlib import import_module


__all__ = [
@@ -47,20 +43,6 @@ class Trans(object):
        from django.conf import settings
        if settings.USE_I18N:
            from django.utils.translation import trans_real as trans
            # Make sure the project's locale dir isn't in LOCALE_PATHS
            if settings.SETTINGS_MODULE is not None:
                parts = settings.SETTINGS_MODULE.split('.')
                project = import_module(parts[0])
                project_locale_path = path.normpath(
                    path.join(path.dirname(project.__file__), 'locale'))
                normalized_locale_paths = [path.normpath(locale_path)
                    for locale_path in settings.LOCALE_PATHS]
                if (path.isdir(project_locale_path) and
                        not project_locale_path in normalized_locale_paths):
                    warnings.warn("Translations in the project directory "
                                  "aren't supported anymore. Use the "
                                  "LOCALE_PATHS setting instead.",
                                  DeprecationWarning)
        else:
            from django.utils.translation import trans_null as trans
        setattr(self, real_name, getattr(trans, real_name))
+0 −12
Original line number Diff line number Diff line
@@ -111,13 +111,6 @@ def translation(language):

    globalpath = os.path.join(os.path.dirname(sys.modules[settings.__module__].__file__), 'locale')

    if settings.SETTINGS_MODULE is not None:
        parts = settings.SETTINGS_MODULE.split('.')
        project = import_module(parts[0])
        projectpath = os.path.join(os.path.dirname(project.__file__), 'locale')
    else:
        projectpath = None

    def _fetch(lang, fallback=None):

        global _translations
@@ -163,11 +156,6 @@ def translation(language):
            if os.path.isdir(apppath):
                res = _merge(apppath)

        localepaths = [os.path.normpath(path) for path in settings.LOCALE_PATHS]
        if (projectpath and os.path.isdir(projectpath) and
                os.path.normpath(projectpath) not in localepaths):
            res = _merge(projectpath)

        for localepath in reversed(settings.LOCALE_PATHS):
            if os.path.isdir(localepath):
                res = _merge(localepath)
+2 −22
Original line number Diff line number Diff line
@@ -1503,18 +1503,9 @@ translations for the same literal:
2. Then, it looks for and uses if it exists a ``locale`` directory in each
   of the installed apps listed in :setting:`INSTALLED_APPS`.  The ones
   appearing first have higher precedence than the ones appearing later.
3. Then, it looks for a ``locale`` directory in the project directory, or
   more accurately, in the directory containing your settings file.
4. Finally, the Django-provided base translation in ``django/conf/locale``
3. Finally, the Django-provided base translation in ``django/conf/locale``
   is used as a fallback.

.. deprecated:: 1.3
    Lookup in the ``locale`` subdirectory of the directory containing your
    settings file (item 3 above) is deprecated since the 1.3 release and will be
    removed in Django 1.5. You can use the :setting:`LOCALE_PATHS` setting
    instead, by listing the absolute filesystem path of such ``locale``
    directory in the setting value.

.. seealso::

    The translations for literals included in JavaScript assets are looked up
@@ -1527,25 +1518,14 @@ be named using :term:`locale name` notation. E.g. ``de``, ``pt_BR``, ``es_AR``,
etc.

This way, you can write applications that include their own translations, and
you can override base translations in your project path. Or, you can just build
you can override base translations in your project. Or, you can just build
a big project out of several apps and put all translations into one big common
message file specific to the project you are composing. The choice is yours.

.. note::

    If you're using manually configured settings, as described in
    :ref:`settings-without-django-settings-module`, the ``locale`` directory in
    the project directory will not be examined, since Django loses the ability
    to work out the location of the project directory. (Django normally uses the
    location of the settings file to determine this, and a settings file doesn't
    exist if you're manually configuring your settings.)

All message file repositories are structured the same way. They are:

* All paths listed in :setting:`LOCALE_PATHS` in your settings file are
  searched for ``<language>/LC_MESSAGES/django.(po|mo)``
* ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` --
  deprecated, see above.
* ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
* ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``

+0 −10
Original line number Diff line number Diff line
@@ -157,16 +157,6 @@ class AdminScriptTestCase(unittest.TestCase):

    def assertNoOutput(self, stream):
        "Utility assertion: assert that the given stream is empty"
        # HACK: Under Windows, ignore warnings of the form:
        # 'warning: Not loading directory '...\tests\regressiontests\locale': missing __init__.py'
        # It has been impossible to filter them out using other means like:
        # * Using warning.filterwarnings() (for the Python interpreter running the
        #   tests) and/or
        # * Using -Wignore:... (for the python interpreter spawned in self.run_test())
        # Instead use a strategy copied from Mercurial's setup.py
        if sys.platform == 'win32':
            stream = [e for e in stream.splitlines()
                if not e.startswith('warning: Not importing directory')]
        self.assertEqual(len(stream), 0, "Stream should be empty: actually contains '%s'" % stream)

    def assertOutput(self, stream, msg):
+0 −24
Original line number Diff line number Diff line
@@ -40,7 +40,6 @@ from .patterns.tests import (URLRedirectWithoutTrailingSlashTests,
    URLTranslationTests, URLDisabledTests, URLTagTests, URLTestCaseBase,
    URLRedirectWithoutTrailingSlashSettingTests, URLNamespaceTests,
    URLPrefixTests, URLResponseTests, URLRedirectTests, PathUnusedTests)
from .test_warnings import DeprecationWarningTests


here = os.path.dirname(os.path.abspath(__file__))
@@ -869,29 +868,6 @@ class LocalePathsResolutionOrderI18NTests(ResolutionOrderI18NTests):
        with self.settings(INSTALLED_APPS=extended_apps):
            self.assertUgettext('Time', 'LOCALE_PATHS')

    def test_locale_paths_override_project_translation(self):
        with self.settings(SETTINGS_MODULE='regressiontests'):
            self.assertUgettext('Date/time', 'LOCALE_PATHS')

class ProjectResolutionOrderI18NTests(ResolutionOrderI18NTests):

    def setUp(self):
        self.old_settings_module = settings.SETTINGS_MODULE
        settings.SETTINGS_MODULE = 'regressiontests'
        super(ProjectResolutionOrderI18NTests, self).setUp()

    def tearDown(self):
        settings.SETTINGS_MODULE = self.old_settings_module
        super(ProjectResolutionOrderI18NTests, self).tearDown()

    def test_project_translation(self):
        self.assertUgettext('Date/time', 'PROJECT')

    def test_project_override_app_translation(self):
        extended_apps = list(settings.INSTALLED_APPS) + ['regressiontests.i18n.resolution']
        with self.settings(INSTALLED_APPS=extended_apps):
            self.assertUgettext('Date/time', 'PROJECT')

class DjangoFallbackResolutionOrderI18NTests(ResolutionOrderI18NTests):

    def test_django_fallback(self):
Loading