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
This commit is contained in:
parent
f38cf60c35
commit
b41ebcf1b9
|
@ -1,12 +1,8 @@
|
||||||
"""
|
"""
|
||||||
Internationalization support.
|
Internationalization support.
|
||||||
"""
|
"""
|
||||||
import warnings
|
|
||||||
from os import path
|
|
||||||
|
|
||||||
from django.utils.encoding import force_unicode
|
from django.utils.encoding import force_unicode
|
||||||
from django.utils.functional import lazy
|
from django.utils.functional import lazy
|
||||||
from django.utils.importlib import import_module
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
@ -47,20 +43,6 @@ class Trans(object):
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
if settings.USE_I18N:
|
if settings.USE_I18N:
|
||||||
from django.utils.translation import trans_real as trans
|
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:
|
else:
|
||||||
from django.utils.translation import trans_null as trans
|
from django.utils.translation import trans_null as trans
|
||||||
setattr(self, real_name, getattr(trans, real_name))
|
setattr(self, real_name, getattr(trans, real_name))
|
||||||
|
|
|
@ -111,13 +111,6 @@ def translation(language):
|
||||||
|
|
||||||
globalpath = os.path.join(os.path.dirname(sys.modules[settings.__module__].__file__), 'locale')
|
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):
|
def _fetch(lang, fallback=None):
|
||||||
|
|
||||||
global _translations
|
global _translations
|
||||||
|
@ -163,11 +156,6 @@ def translation(language):
|
||||||
if os.path.isdir(apppath):
|
if os.path.isdir(apppath):
|
||||||
res = _merge(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):
|
for localepath in reversed(settings.LOCALE_PATHS):
|
||||||
if os.path.isdir(localepath):
|
if os.path.isdir(localepath):
|
||||||
res = _merge(localepath)
|
res = _merge(localepath)
|
||||||
|
|
|
@ -1503,18 +1503,9 @@ translations for the same literal:
|
||||||
2. Then, it looks for and uses if it exists a ``locale`` directory in each
|
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
|
of the installed apps listed in :setting:`INSTALLED_APPS`. The ones
|
||||||
appearing first have higher precedence than the ones appearing later.
|
appearing first have higher precedence than the ones appearing later.
|
||||||
3. Then, it looks for a ``locale`` directory in the project directory, or
|
3. Finally, the Django-provided base translation in ``django/conf/locale``
|
||||||
more accurately, in the directory containing your settings file.
|
|
||||||
4. Finally, the Django-provided base translation in ``django/conf/locale``
|
|
||||||
is used as a fallback.
|
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::
|
.. seealso::
|
||||||
|
|
||||||
The translations for literals included in JavaScript assets are looked up
|
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.
|
etc.
|
||||||
|
|
||||||
This way, you can write applications that include their own translations, and
|
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
|
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.
|
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 message file repositories are structured the same way. They are:
|
||||||
|
|
||||||
* All paths listed in :setting:`LOCALE_PATHS` in your settings file are
|
* All paths listed in :setting:`LOCALE_PATHS` in your settings file are
|
||||||
searched for ``<language>/LC_MESSAGES/django.(po|mo)``
|
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)``
|
* ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
|
||||||
* ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
|
* ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
|
||||||
|
|
||||||
|
|
|
@ -157,16 +157,6 @@ class AdminScriptTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def assertNoOutput(self, stream):
|
def assertNoOutput(self, stream):
|
||||||
"Utility assertion: assert that the given stream is empty"
|
"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)
|
self.assertEqual(len(stream), 0, "Stream should be empty: actually contains '%s'" % stream)
|
||||||
|
|
||||||
def assertOutput(self, stream, msg):
|
def assertOutput(self, stream, msg):
|
||||||
|
|
|
@ -40,7 +40,6 @@ from .patterns.tests import (URLRedirectWithoutTrailingSlashTests,
|
||||||
URLTranslationTests, URLDisabledTests, URLTagTests, URLTestCaseBase,
|
URLTranslationTests, URLDisabledTests, URLTagTests, URLTestCaseBase,
|
||||||
URLRedirectWithoutTrailingSlashSettingTests, URLNamespaceTests,
|
URLRedirectWithoutTrailingSlashSettingTests, URLNamespaceTests,
|
||||||
URLPrefixTests, URLResponseTests, URLRedirectTests, PathUnusedTests)
|
URLPrefixTests, URLResponseTests, URLRedirectTests, PathUnusedTests)
|
||||||
from .test_warnings import DeprecationWarningTests
|
|
||||||
|
|
||||||
|
|
||||||
here = os.path.dirname(os.path.abspath(__file__))
|
here = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
@ -869,29 +868,6 @@ class LocalePathsResolutionOrderI18NTests(ResolutionOrderI18NTests):
|
||||||
with self.settings(INSTALLED_APPS=extended_apps):
|
with self.settings(INSTALLED_APPS=extended_apps):
|
||||||
self.assertUgettext('Time', 'LOCALE_PATHS')
|
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):
|
class DjangoFallbackResolutionOrderI18NTests(ResolutionOrderI18NTests):
|
||||||
|
|
||||||
def test_django_fallback(self):
|
def test_django_fallback(self):
|
||||||
|
|
Binary file not shown.
|
@ -1,25 +0,0 @@
|
||||||
# SOME DESCRIPTIVE TITLE.
|
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
|
||||||
#
|
|
||||||
msgid ""
|
|
||||||
msgstr ""
|
|
||||||
"Project-Id-Version: django tests\n"
|
|
||||||
"Report-Msgid-Bugs-To: \n"
|
|
||||||
"POT-Creation-Date: 2010-02-14 17:33+0100\n"
|
|
||||||
"PO-Revision-Date: 2011-02-07 13:13-0300\n"
|
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
|
||||||
"MIME-Version: 1.0\n"
|
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
|
|
||||||
|
|
||||||
#: models.py:3
|
|
||||||
msgid "Time"
|
|
||||||
msgstr "Zeit (PROJECT)"
|
|
||||||
|
|
||||||
#: models.py:5
|
|
||||||
msgid "Date/time"
|
|
||||||
msgstr "Datum/Zeit (PROJECT)"
|
|
|
@ -25,7 +25,7 @@ REGRESSION_TEST_DIR = os.path.join(RUNTESTS_DIR, REGRESSION_TESTS_DIR_NAME)
|
||||||
TEMP_DIR = tempfile.mkdtemp(prefix='django_')
|
TEMP_DIR = tempfile.mkdtemp(prefix='django_')
|
||||||
os.environ['DJANGO_TEST_TEMP_DIR'] = TEMP_DIR
|
os.environ['DJANGO_TEST_TEMP_DIR'] = TEMP_DIR
|
||||||
|
|
||||||
REGRESSION_SUBDIRS_TO_SKIP = ['locale']
|
REGRESSION_SUBDIRS_TO_SKIP = []
|
||||||
|
|
||||||
ALWAYS_INSTALLED_APPS = [
|
ALWAYS_INSTALLED_APPS = [
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
|
|
Loading…
Reference in New Issue