Kaydet (Commit) 0cd465b6 authored tarafından Jon Dufresne's avatar Jon Dufresne Kaydeden (comit) Tim Graham

Fixed #29817 -- Deprecated settings.FILE_CHARSET.

üst 99d4fc18
......@@ -16,12 +16,18 @@ from pathlib import Path
import django
from django.conf import global_settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.deprecation import RemovedInDjango30Warning
from django.utils.deprecation import (
RemovedInDjango30Warning, RemovedInDjango31Warning,
)
from django.utils.functional import LazyObject, empty
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
DEFAULT_CONTENT_TYPE_DEPRECATED_MSG = 'The DEFAULT_CONTENT_TYPE setting is deprecated.'
FILE_CHARSET_DEPRECATED_MSG = (
'The FILE_CHARSET setting is deprecated. Starting with Django 3.1, all '
'files read from disk must be UTF-8 encoded.'
)
class LazySettings(LazyObject):
......@@ -111,6 +117,20 @@ class LazySettings(LazyObject):
)
return self.__getattr__('DEFAULT_CONTENT_TYPE')
@property
def FILE_CHARSET(self):
stack = traceback.extract_stack()
# Show a warning if the setting is used outside of Django.
# Stack index: -1 this line, -2 the caller.
filename, _line_number, _function_name, _text = stack[-2]
if not filename.startswith(os.path.dirname(django.__file__)):
warnings.warn(
FILE_CHARSET_DEPRECATED_MSG,
RemovedInDjango31Warning,
stacklevel=2,
)
return self.__getattr__('FILE_CHARSET')
class Settings:
def __init__(self, settings_module):
......@@ -145,6 +165,8 @@ class Settings:
if self.is_overridden('DEFAULT_CONTENT_TYPE'):
warnings.warn(DEFAULT_CONTENT_TYPE_DEPRECATED_MSG, RemovedInDjango30Warning)
if self.is_overridden('FILE_CHARSET'):
warnings.warn(FILE_CHARSET_DEPRECATED_MSG, RemovedInDjango31Warning)
if hasattr(time, 'tzset') and self.TIME_ZONE:
# When we can, attempt to validate the timezone. If we can't find
......@@ -191,6 +213,8 @@ class UserSettingsHolder:
self._deleted.discard(name)
if name == 'DEFAULT_CONTENT_TYPE':
warnings.warn(DEFAULT_CONTENT_TYPE_DEPRECATED_MSG, RemovedInDjango30Warning)
elif name == 'FILE_CHARSET':
warnings.warn(FILE_CHARSET_DEPRECATED_MSG, RemovedInDjango31Warning)
super().__setattr__(name, value)
def __delattr__(self, name):
......
......@@ -24,6 +24,8 @@ details on these changes.
* ``django.contrib.postgres.fields.FloatRangeField`` and
``django.contrib.postgres.forms.FloatRangeField`` will be removed.
* The ``FILE_CHARSET`` setting will be removed.
.. _deprecation-removed-in-3.0:
3.0
......
......@@ -613,8 +613,7 @@ the :ref:`i18n documentation <how-to-create-language-files>` for details.
This command doesn't require configured settings. However, when settings aren't
configured, the command can't ignore the :setting:`MEDIA_ROOT` and
:setting:`STATIC_ROOT` directories or include :setting:`LOCALE_PATHS`. It will
also write files in UTF-8 rather than in :setting:`FILE_CHARSET`.
:setting:`STATIC_ROOT` directories or include :setting:`LOCALE_PATHS`.
.. django-admin-option:: --all, -a
......
......@@ -1424,7 +1424,12 @@ attempt.
Default: ``'utf-8'``
The character encoding used to decode any files read from disk. This includes
template files and initial SQL data files.
template files, static files, and translation catalogs.
.. deprecated:: 2.2
This setting is deprecated. Starting with Django 3.1, files read from disk
must be UTF-8 encoded.
.. setting:: FILE_UPLOAD_HANDLERS
......@@ -3374,7 +3379,6 @@ Error reporting
File uploads
------------
* :setting:`DEFAULT_FILE_STORAGE`
* :setting:`FILE_CHARSET`
* :setting:`FILE_UPLOAD_HANDLERS`
* :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE`
* :setting:`FILE_UPLOAD_PERMISSIONS`
......
......@@ -265,12 +265,11 @@ Use strings when creating templates manually::
from django.template import Template
t2 = Template('This is a string template.')
But the common case is to read templates from the filesystem, and this creates
a slight complication: not all filesystems store their data encoded as UTF-8.
If your template files are not stored with a UTF-8 encoding, set the :setting:`FILE_CHARSET`
setting to the encoding of the files on disk. When Django reads in a template
file, it will convert the data from this encoding to Unicode. (:setting:`FILE_CHARSET`
is set to ``'utf-8'`` by default.)
But the common case is to read templates from the filesystem. If your template
files are not stored with a UTF-8 encoding, adjust the :setting:`TEMPLATES`
setting. The built-in :py:mod:`~django.template.backends.django` backend
provides the ``'file_charset'`` option to change the encoding used to read
files from disk.
The :setting:`DEFAULT_CHARSET` setting controls the encoding of rendered templates.
This is set to UTF-8 by default.
......
......@@ -332,3 +332,6 @@ Miscellaneous
* The ``FloatRangeField`` model and form fields in ``django.contrib.postgres``
are deprecated in favor of a new name, ``DecimalRangeField``, to match the
underlying ``numrange`` data type used in the database.
* The ``FILE_CHARSET`` setting is deprecated. Starting with Django 3.1, files
read from disk must be UTF-8 encoded.
......@@ -351,7 +351,7 @@ applications. This generic name was kept for backwards-compatibility.
* ``'file_charset'``: the charset used to read template files on disk.
It defaults to the value of :setting:`FILE_CHARSET`.
It defaults to ``'utf-8'``.
* ``'libraries'``: A dictionary of labels and dotted Python paths of template
tag modules to register with the template engine. This can be used to add
......
import sys
from types import ModuleType
from django.conf import FILE_CHARSET_DEPRECATED_MSG, Settings, settings
from django.test import SimpleTestCase, ignore_warnings
from django.utils.deprecation import RemovedInDjango31Warning
class DeprecationTests(SimpleTestCase):
msg = FILE_CHARSET_DEPRECATED_MSG
def test_override_settings_warning(self):
with self.assertRaisesMessage(RemovedInDjango31Warning, self.msg):
with self.settings(FILE_CHARSET='latin1'):
pass
def test_settings_init_warning(self):
settings_module = ModuleType('fake_settings_module')
settings_module.FILE_CHARSET = 'latin1'
settings_module.SECRET_KEY = 'ABC'
sys.modules['fake_settings_module'] = settings_module
try:
with self.assertRaisesMessage(RemovedInDjango31Warning, self.msg):
Settings('fake_settings_module')
finally:
del sys.modules['fake_settings_module']
def test_access_warning(self):
with self.assertRaisesMessage(RemovedInDjango31Warning, self.msg):
settings.FILE_CHARSET
# Works a second time.
with self.assertRaisesMessage(RemovedInDjango31Warning, self.msg):
settings.FILE_CHARSET
@ignore_warnings(category=RemovedInDjango31Warning)
def test_access(self):
with self.settings(FILE_CHARSET='latin1'):
self.assertEqual(settings.FILE_CHARSET, 'latin1')
# Works a second time.
self.assertEqual(settings.FILE_CHARSET, 'latin1')
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment