mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +00:00 
			
		
		
		
	[1.11.x] Fixed #28487 -- Fixed runserver crash with non-Unicode system encodings on Python 2 + Windows.
This commit is contained in:
		| @@ -40,7 +40,7 @@ from django.conf import settings | ||||
| from django.core.signals import request_finished | ||||
| from django.utils import six | ||||
| from django.utils._os import npath | ||||
| from django.utils.encoding import force_bytes, get_system_encoding | ||||
| from django.utils.encoding import get_system_encoding | ||||
| from django.utils.six.moves import _thread as thread | ||||
|  | ||||
| # This import does nothing, but it's necessary to avoid some race conditions | ||||
| @@ -290,8 +290,8 @@ def restart_with_reloader(): | ||||
|             # Environment variables on Python 2 + Windows must be str. | ||||
|             encoding = get_system_encoding() | ||||
|             for key in new_environ.keys(): | ||||
|                 str_key = force_bytes(key, encoding=encoding) | ||||
|                 str_value = force_bytes(new_environ[key], encoding=encoding) | ||||
|                 str_key = key.decode(encoding).encode('utf-8') | ||||
|                 str_value = new_environ[key].decode(encoding).encode('utf-8') | ||||
|                 del new_environ[key] | ||||
|                 new_environ[str_key] = str_value | ||||
|         new_environ["RUN_MAIN"] = 'true' | ||||
|   | ||||
| @@ -32,3 +32,6 @@ Bugfixes | ||||
|  | ||||
| * Fixed a regression where ``SelectDateWidget`` localized the years in the | ||||
|   select box (:ticket:`28530`). | ||||
|  | ||||
| * Fixed a regression in 1.11.4 where ``runserver`` crashed with non-Unicode | ||||
|   system encodings on Python 2 + Windows (:ticket:`28487`). | ||||
|   | ||||
| @@ -5,13 +5,14 @@ import os | ||||
| import shutil | ||||
| import sys | ||||
| import tempfile | ||||
| import unittest | ||||
| from importlib import import_module | ||||
|  | ||||
| from django import conf | ||||
| from django.contrib import admin | ||||
| from django.test import SimpleTestCase, mock, override_settings | ||||
| from django.test.utils import extend_sys_path | ||||
| from django.utils import autoreload | ||||
| from django.utils import autoreload, six | ||||
| from django.utils._os import npath, upath | ||||
| from django.utils.six.moves import _thread | ||||
| from django.utils.translation import trans_real | ||||
| @@ -258,6 +259,13 @@ class ResetTranslationsTests(SimpleTestCase): | ||||
|  | ||||
| class TestRestartWithReloader(SimpleTestCase): | ||||
|  | ||||
|     def setUp(self): | ||||
|         self._orig_environ = os.environ.copy() | ||||
|  | ||||
|     def tearDown(self): | ||||
|         os.environ.clear() | ||||
|         os.environ.update(self._orig_environ) | ||||
|  | ||||
|     def test_environment(self): | ||||
|         """" | ||||
|         With Python 2 on Windows, restart_with_reloader() coerces environment | ||||
| @@ -268,3 +276,24 @@ class TestRestartWithReloader(SimpleTestCase): | ||||
|         os.environ['SPAM'] = 'spam' | ||||
|         with mock.patch.object(sys, 'argv', ['-c', 'pass']): | ||||
|             autoreload.restart_with_reloader() | ||||
|  | ||||
|     @unittest.skipUnless(six.PY2 and sys.platform == 'win32', 'This is a Python 2 + Windows-specific issue.') | ||||
|     def test_environment_decoding(self): | ||||
|         """The system encoding is used for decoding.""" | ||||
|         os.environ['SPAM'] = 'spam' | ||||
|         os.environ['EGGS'] = b'\xc6u vi komprenas?' | ||||
|         with mock.patch('locale.getdefaultlocale') as default_locale: | ||||
|             # Latin-3 is the correct mapping. | ||||
|             default_locale.return_value = ('eo', 'latin3') | ||||
|             with mock.patch.object(sys, 'argv', ['-c', 'pass']): | ||||
|                 autoreload.restart_with_reloader() | ||||
|             # CP1252 interprets latin3's C circumflex as AE ligature. | ||||
|             # It's incorrect but doesn't raise an error. | ||||
|             default_locale.return_value = ('en_US', 'cp1252') | ||||
|             with mock.patch.object(sys, 'argv', ['-c', 'pass']): | ||||
|                 autoreload.restart_with_reloader() | ||||
|             # Interpreting the string as UTF-8 is fatal. | ||||
|             with self.assertRaises(UnicodeDecodeError): | ||||
|                 default_locale.return_value = ('en_US', 'utf-8') | ||||
|                 with mock.patch.object(sys, 'argv', ['-c', 'pass']): | ||||
|                     autoreload.restart_with_reloader() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user