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. |     on reloading. | ||||||
|     """ |     """ | ||||||
|     import django.__main__ |     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] |     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`. |         # The server was started with `python -m django runserver`. | ||||||
|         args += ['-m', 'django'] |         args += ['-m', 'django'] | ||||||
|         args += sys.argv[1:] |         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: |     else: | ||||||
|         args += sys.argv |         args += sys.argv | ||||||
|     return args |     return args | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ from pathlib import Path | |||||||
| from subprocess import CompletedProcess | from subprocess import CompletedProcess | ||||||
| from unittest import mock, skip, skipIf | from unittest import mock, skip, skipIf | ||||||
|  |  | ||||||
|  | import django.__main__ | ||||||
| from django.apps.registry import Apps | from django.apps.registry import Apps | ||||||
| from django.test import SimpleTestCase | from django.test import SimpleTestCase | ||||||
| from django.test.utils import extend_sys_path | 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): | class TestCommonRoots(SimpleTestCase): | ||||||
|     def test_common_roots(self): |     def test_common_roots(self): | ||||||
|         paths = ( |         paths = ( | ||||||
| @@ -360,6 +410,9 @@ class RestartWithReloaderTests(SimpleTestCase): | |||||||
|         return mock_call |         return mock_call | ||||||
|  |  | ||||||
|     def test_manage_py(self): |     def test_manage_py(self): | ||||||
|  |         script = Path('manage.py') | ||||||
|  |         script.touch() | ||||||
|  |         self.addCleanup(script.unlink) | ||||||
|         argv = ['./manage.py', 'runserver'] |         argv = ['./manage.py', 'runserver'] | ||||||
|         mock_call = self.patch_autoreload(argv) |         mock_call = self.patch_autoreload(argv) | ||||||
|         autoreload.restart_with_reloader() |         autoreload.restart_with_reloader() | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user