Fixed #34259 -- Passed called_from_command_line to command subparsers.

This commit is contained in:
Adam Johnson 2023-01-15 09:19:52 +00:00 committed by Mariusz Felisiak
parent 1250483ebf
commit 017fa23d3b
3 changed files with 47 additions and 0 deletions

View File

@ -6,6 +6,7 @@ import argparse
import os import os
import sys import sys
from argparse import ArgumentParser, HelpFormatter from argparse import ArgumentParser, HelpFormatter
from functools import partial
from io import TextIOBase from io import TextIOBase
import django import django
@ -71,6 +72,15 @@ class CommandParser(ArgumentParser):
else: else:
raise CommandError("Error: %s" % message) raise CommandError("Error: %s" % message)
def add_subparsers(self, **kwargs):
parser_class = kwargs.get("parser_class", type(self))
if issubclass(parser_class, CommandParser):
kwargs["parser_class"] = partial(
parser_class,
called_from_command_line=self.called_from_command_line,
)
return super().add_subparsers(**kwargs)
def handle_default_options(options): def handle_default_options(options):
""" """

View File

@ -0,0 +1,13 @@
import argparse
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def add_arguments(self, parser):
subparsers = parser.add_subparsers(parser_class=argparse.ArgumentParser)
parser_foo = subparsers.add_parser("foo")
parser_foo.add_argument("bar", type=int)
def handle(self, *args, **options):
pass

View File

@ -468,6 +468,30 @@ class CommandRunTests(AdminScriptTestCase):
self.assertNoOutput(err) self.assertNoOutput(err)
self.assertEqual(out.strip(), "Set foo") self.assertEqual(out.strip(), "Set foo")
def test_subparser_error_formatting(self):
self.write_settings("settings.py", apps=["user_commands"])
out, err = self.run_manage(["subparser", "foo", "twelve"])
self.maxDiff = None
self.assertNoOutput(out)
err_lines = err.splitlines()
self.assertEqual(len(err_lines), 2)
self.assertEqual(
err_lines[1],
"manage.py subparser foo: error: argument bar: invalid int value: 'twelve'",
)
def test_subparser_non_django_error_formatting(self):
self.write_settings("settings.py", apps=["user_commands"])
out, err = self.run_manage(["subparser_vanilla", "foo", "seven"])
self.assertNoOutput(out)
err_lines = err.splitlines()
self.assertEqual(len(err_lines), 2)
self.assertEqual(
err_lines[1],
"manage.py subparser_vanilla foo: error: argument bar: invalid int value: "
"'seven'",
)
class UtilsTests(SimpleTestCase): class UtilsTests(SimpleTestCase):
def test_no_existent_external_program(self): def test_no_existent_external_program(self):