This commit is contained in:
wangxiaolei 2025-11-17 23:31:10 +08:00 committed by GitHub
commit 3bc5c5b6de
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 31 additions and 1 deletions

View file

@ -24,6 +24,7 @@ from django.core.management.base import (
)
from django.core.management.color import color_style
from django.utils import autoreload
from django.utils.version import PY314
def find_commands(management_dir):
@ -364,11 +365,16 @@ class ManagementUtility:
# Preprocess options to extract --settings and --pythonpath.
# These options could affect the commands that are available, so they
# must be processed early.
if PY314:
color_kwargs = {"color": os.environ.get("DJANGO_COLORS") != "nocolor"}
else:
color_kwargs = {}
parser = CommandParser(
prog=self.prog_name,
usage="%(prog)s subcommand [options] [args]",
add_help=False,
allow_abbrev=False,
**color_kwargs,
)
parser.add_argument("--settings")
parser.add_argument("--pythonpath")

View file

@ -15,6 +15,7 @@ from django.core import checks
from django.core.exceptions import ImproperlyConfigured
from django.core.management.color import color_style, no_style
from django.db import DEFAULT_DB_ALIAS, connections
from django.utils.version import PY314
ALL_CHECKS = "__all__"
@ -301,11 +302,18 @@ class BaseCommand:
parse the arguments to this command.
"""
kwargs.setdefault("formatter_class", DjangoHelpFormatter)
# argparse's color defaults to True on Python 3.14+.
# Respect DJANGO_COLORS=nocolor by explicitly passing color=False.
if PY314:
color_kwargs = {"color": os.environ.get("DJANGO_COLORS") != "nocolor"}
else:
color_kwargs = {}
parser = CommandParser(
prog="%s %s" % (os.path.basename(prog_name), subcommand),
description=self.help or None,
missing_args_message=getattr(self, "missing_args_message", None),
called_from_command_line=getattr(self, "_called_from_command_line", None),
**color_kwargs,
**kwargs,
)
self.add_base_argument(

View file

@ -38,7 +38,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
from django.urls import path
from django.utils.version import PY313, get_docs_version
from django.utils.version import PY313, PY314, get_docs_version
from django.views.static import serve
from . import urls
@ -3332,3 +3332,19 @@ class DjangoAdminSuggestions(AdminScriptTestCase):
out, err = self.run_django_admin(args)
self.assertNoOutput(out)
self.assertNotInOutput(err, "Did you mean")
class AdminScriptsColorizedHelp(AdminScriptTestCase):
@unittest.skipUnless(PY314, "argparse colorized help requires Python 3.14+")
def test_help_is_colorized_on_py314(self):
# Use a command that doesn't need settings.
with mock.patch.dict(os.environ, {}, clear=False):
out, err = self.run_django_admin(["startproject", "--help"])
# Look for ANSI SGR sequences.
self.assertRegex(out, r"\x1b\\[[0-9;]*m")
@unittest.skipUnless(PY314, "argparse colorized help requires Python 3.14+")
def test_help_not_colorized_when_django_colors_nocolor(self):
with mock.patch.dict(os.environ, {"DJANGO_COLORS": "nocolor"}, clear=False):
out, err = self.run_django_admin(["startproject", "--help"])
self.assertNotRegex(out, r"\x1b\\[[0-9;]*m")