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.
This commit is contained in:
William Schwartz 2020-11-09 14:42:53 -06:00 committed by Mariusz Felisiak
parent 0773837e15
commit cc22693505
2 changed files with 22 additions and 2 deletions

View File

@ -344,7 +344,12 @@ class ManagementUtility:
# Preprocess options to extract --settings and --pythonpath. # Preprocess options to extract --settings and --pythonpath.
# These options could affect the commands that are available, so they # These options could affect the commands that are available, so they
# must be processed early. # 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('--settings')
parser.add_argument('--pythonpath') parser.add_argument('--pythonpath')
parser.add_argument('args', nargs='*') # catch-all parser.add_argument('args', nargs='*') # catch-all

View File

@ -17,7 +17,7 @@ from unittest import mock
from django import conf, get_version from django import conf, get_version
from django.conf import settings from django.conf import settings
from django.core.management import ( 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.loaddata import Command as LoaddataCommand
from django.core.management.commands.runserver import ( from django.core.management.commands.runserver import (
@ -31,6 +31,7 @@ from django.db.migrations.recorder import MigrationRecorder
from django.test import ( from django.test import (
LiveServerTestCase, SimpleTestCase, TestCase, override_settings, 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') 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') @override_settings(ROOT_URLCONF='admin_scripts.urls')
class StartProject(LiveServerTestCase, AdminScriptTestCase): class StartProject(LiveServerTestCase, AdminScriptTestCase):