mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[3.1.x] Fixed #31716 -- Fixed detection of console scripts in autoreloader on Windows.
Backport of 8a902b7ee6 from master
			
			
This commit is contained in:
		
				
					committed by
					
						 Mariusz Felisiak
						Mariusz Felisiak
					
				
			
			
				
	
			
			
			
						parent
						
							928f6a90e4
						
					
				
				
					commit
					ac7f7eab0f
				
			| @@ -207,12 +207,26 @@ def get_child_arguments(): | ||||
|     on reloading. | ||||
|     """ | ||||
|     import django.__main__ | ||||
|     django_main_path = Path(django.__main__.__file__) | ||||
|     py_script = Path(sys.argv[0]) | ||||
|  | ||||
|     args = [sys.executable] + ['-W%s' % o for o in sys.warnoptions] | ||||
|     if sys.argv[0] == django.__main__.__file__: | ||||
|     if py_script == django_main_path: | ||||
|         # The server was started with `python -m django runserver`. | ||||
|         args += ['-m', 'django'] | ||||
|         args += sys.argv[1:] | ||||
|     elif not py_script.exists(): | ||||
|         # sys.argv[0] may not exist for several reasons on Windows. | ||||
|         # It may exist with a .exe extension or have a -script.py suffix. | ||||
|         exe_entrypoint = py_script.with_suffix('.exe') | ||||
|         if exe_entrypoint.exists(): | ||||
|             # Should be executed directly, ignoring sys.executable. | ||||
|             return [exe_entrypoint, *sys.argv[1:]] | ||||
|         script_entrypoint = py_script.with_name('%s-script.py' % py_script.name) | ||||
|         if script_entrypoint.exists(): | ||||
|             # Should be executed as usual. | ||||
|             return [*args, script_entrypoint, *sys.argv[1:]] | ||||
|         raise RuntimeError('Script %s does not exist.' % py_script) | ||||
|     else: | ||||
|         args += sys.argv | ||||
|     return args | ||||
|   | ||||
| @@ -14,6 +14,7 @@ from pathlib import Path | ||||
| from subprocess import CompletedProcess | ||||
| from unittest import mock, skip, skipIf | ||||
|  | ||||
| import django.__main__ | ||||
| from django.apps.registry import Apps | ||||
| from django.test import SimpleTestCase | ||||
| from django.test.utils import extend_sys_path | ||||
| @@ -153,6 +154,55 @@ class TestIterModulesAndFiles(SimpleTestCase): | ||||
|                 ) | ||||
|  | ||||
|  | ||||
| class TestChildArguments(SimpleTestCase): | ||||
|     @mock.patch('sys.argv', [django.__main__.__file__, 'runserver']) | ||||
|     @mock.patch('sys.warnoptions', []) | ||||
|     def test_run_as_module(self): | ||||
|         self.assertEqual( | ||||
|             autoreload.get_child_arguments(), | ||||
|             [sys.executable, '-m', 'django', 'runserver'] | ||||
|         ) | ||||
|  | ||||
|     @mock.patch('sys.argv', [__file__, 'runserver']) | ||||
|     @mock.patch('sys.warnoptions', ['error']) | ||||
|     def test_warnoptions(self): | ||||
|         self.assertEqual( | ||||
|             autoreload.get_child_arguments(), | ||||
|             [sys.executable, '-Werror', __file__, 'runserver'] | ||||
|         ) | ||||
|  | ||||
|     @mock.patch('sys.warnoptions', []) | ||||
|     def test_exe_fallback(self): | ||||
|         tmpdir = tempfile.TemporaryDirectory() | ||||
|         self.addCleanup(tmpdir.cleanup) | ||||
|         exe_path = Path(tmpdir.name) / 'django-admin.exe' | ||||
|         exe_path.touch() | ||||
|         with mock.patch('sys.argv', [exe_path.with_suffix(''), 'runserver']): | ||||
|             self.assertEqual( | ||||
|                 autoreload.get_child_arguments(), | ||||
|                 [exe_path, 'runserver'] | ||||
|             ) | ||||
|  | ||||
|     @mock.patch('sys.warnoptions', []) | ||||
|     def test_entrypoint_fallback(self): | ||||
|         tmpdir = tempfile.TemporaryDirectory() | ||||
|         self.addCleanup(tmpdir.cleanup) | ||||
|         script_path = Path(tmpdir.name) / 'django-admin-script.py' | ||||
|         script_path.touch() | ||||
|         with mock.patch('sys.argv', [script_path.with_name('django-admin'), 'runserver']): | ||||
|             self.assertEqual( | ||||
|                 autoreload.get_child_arguments(), | ||||
|                 [sys.executable, script_path, 'runserver'] | ||||
|             ) | ||||
|  | ||||
|     @mock.patch('sys.argv', ['does-not-exist', 'runserver']) | ||||
|     @mock.patch('sys.warnoptions', []) | ||||
|     def test_raises_runtimeerror(self): | ||||
|         msg = 'Script does-not-exist does not exist.' | ||||
|         with self.assertRaisesMessage(RuntimeError, msg): | ||||
|             autoreload.get_child_arguments() | ||||
|  | ||||
|  | ||||
| class TestCommonRoots(SimpleTestCase): | ||||
|     def test_common_roots(self): | ||||
|         paths = ( | ||||
| @@ -360,6 +410,9 @@ class RestartWithReloaderTests(SimpleTestCase): | ||||
|         return mock_call | ||||
|  | ||||
|     def test_manage_py(self): | ||||
|         script = Path('manage.py') | ||||
|         script.touch() | ||||
|         self.addCleanup(script.unlink) | ||||
|         argv = ['./manage.py', 'runserver'] | ||||
|         mock_call = self.patch_autoreload(argv) | ||||
|         autoreload.restart_with_reloader() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user