2
0
Эх сурвалжийг харах

Fixed #32177 -- Made execute_from_command_line() use program name from the argv argument.

This caused crash in environments where sys.argv[0] is incorrectly set
to None.
William Schwartz 4 жил өмнө
parent
commit
cc22693505

+ 6 - 1
django/core/management/__init__.py

@@ -344,7 +344,12 @@ class ManagementUtility:
         # Preprocess options to extract --settings and --pythonpath.
         # These options could affect the commands that are available, so they
         # must be processed early.
-        parser = CommandParser(usage='%(prog)s subcommand [options] [args]', add_help=False, allow_abbrev=False)
+        parser = CommandParser(
+            prog=self.prog_name,
+            usage='%(prog)s subcommand [options] [args]',
+            add_help=False,
+            allow_abbrev=False,
+        )
         parser.add_argument('--settings')
         parser.add_argument('--pythonpath')
         parser.add_argument('args', nargs='*')  # catch-all

+ 16 - 1
tests/admin_scripts/tests.py

@@ -17,7 +17,7 @@ from unittest import mock
 from django import conf, get_version
 from django.conf import settings
 from django.core.management import (
-    BaseCommand, CommandError, call_command, color,
+    BaseCommand, CommandError, call_command, color, execute_from_command_line,
 )
 from django.core.management.commands.loaddata import Command as LoaddataCommand
 from django.core.management.commands.runserver import (
@@ -31,6 +31,7 @@ from django.db.migrations.recorder import MigrationRecorder
 from django.test import (
     LiveServerTestCase, SimpleTestCase, TestCase, override_settings,
 )
+from django.test.utils import captured_stderr, captured_stdout
 
 custom_templates_dir = os.path.join(os.path.dirname(__file__), 'custom_templates')
 
@@ -1867,6 +1868,20 @@ class ArgumentOrder(AdminScriptTestCase):
         )
 
 
+class ExecuteFromCommandLine(SimpleTestCase):
+    def test_program_name_from_argv(self):
+        """
+        Program name is computed from the execute_from_command_line()'s argv
+        argument, not sys.argv.
+        """
+        args = ['help', 'shell']
+        with captured_stdout() as out, captured_stderr() as err:
+            with mock.patch('sys.argv', [None] + args):
+                execute_from_command_line(['django-admin'] + args)
+        self.assertIn('usage: django-admin shell', out.getvalue())
+        self.assertEqual(err.getvalue(), '')
+
+
 @override_settings(ROOT_URLCONF='admin_scripts.urls')
 class StartProject(LiveServerTestCase, AdminScriptTestCase):