From cc2269350548307e3fe31723ff4e40a879a7a173 Mon Sep 17 00:00:00 2001 From: William Schwartz Date: Mon, 9 Nov 2020 14:42:53 -0600 Subject: [PATCH] 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. --- django/core/management/__init__.py | 7 ++++++- tests/admin_scripts/tests.py | 17 ++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py index 1ba093e51f8..4e30a28f338 100644 --- a/django/core/management/__init__.py +++ b/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 diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py index 62c6f485aa6..a82f5be5ed6 100644 --- a/tests/admin_scripts/tests.py +++ b/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):