Fixed #21269 -- Don't crash when CommandError contains non-ascii
Thanks kontakt@eikefoken.de for the report.
This commit is contained in:
parent
8ab5f1fe47
commit
42a67ec1cd
|
@ -3,6 +3,8 @@ Base classes for writing management commands (named commands which can
|
||||||
be executed through ``django-admin.py`` or ``manage.py``).
|
be executed through ``django-admin.py`` or ``manage.py``).
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ from django.conf import settings
|
||||||
from django.core.management import BaseCommand, CommandError, call_command
|
from django.core.management import BaseCommand, CommandError, call_command
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.test.runner import DiscoverRunner
|
from django.test.runner import DiscoverRunner
|
||||||
|
from django.test.utils import str_prefix
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
from django.utils.six import StringIO
|
from django.utils.six import StringIO
|
||||||
|
@ -921,21 +922,21 @@ class ManageAlternateSettings(AdminScriptTestCase):
|
||||||
"alternate: manage.py can execute user commands if settings are provided as argument"
|
"alternate: manage.py can execute user commands if settings are provided as argument"
|
||||||
args = ['noargs_command', '--settings=alternate_settings']
|
args = ['noargs_command', '--settings=alternate_settings']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('no_color', False), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:NoArgsCommand options=[('no_color', False), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
|
|
||||||
def test_custom_command_with_environment(self):
|
def test_custom_command_with_environment(self):
|
||||||
"alternate: manage.py can execute user commands if settings are provided in environment"
|
"alternate: manage.py can execute user commands if settings are provided in environment"
|
||||||
args = ['noargs_command']
|
args = ['noargs_command']
|
||||||
out, err = self.run_manage(args, 'alternate_settings')
|
out, err = self.run_manage(args, 'alternate_settings')
|
||||||
self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:NoArgsCommand options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
|
|
||||||
def test_custom_command_output_color(self):
|
def test_custom_command_output_color(self):
|
||||||
"alternate: manage.py output syntax color can be deactivated with the `--no-color` option"
|
"alternate: manage.py output syntax color can be deactivated with the `--no-color` option"
|
||||||
args = ['noargs_command', '--no-color', '--settings=alternate_settings']
|
args = ['noargs_command', '--no-color', '--settings=alternate_settings']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('no_color', True), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:NoArgsCommand options=[('no_color', True), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1290,35 +1291,35 @@ class CommandTypes(AdminScriptTestCase):
|
||||||
args = ['base_command', 'testlabel']
|
args = ['base_command', 'testlabel']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_base_command_no_label(self):
|
def test_base_command_no_label(self):
|
||||||
"User BaseCommands can execute when no labels are provided"
|
"User BaseCommands can execute when no labels are provided"
|
||||||
args = ['base_command']
|
args = ['base_command']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:BaseCommand labels=(), options=[('no_color', False), ('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:BaseCommand labels=(), options=[('no_color', False), ('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_base_command_multiple_label(self):
|
def test_base_command_multiple_label(self):
|
||||||
"User BaseCommands can execute when no labels are provided"
|
"User BaseCommands can execute when no labels are provided"
|
||||||
args = ['base_command', 'testlabel', 'anotherlabel']
|
args = ['base_command', 'testlabel', 'anotherlabel']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel', 'anotherlabel'), options=[('no_color', False), ('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:BaseCommand labels=('testlabel', 'anotherlabel'), options=[('no_color', False), ('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_base_command_with_option(self):
|
def test_base_command_with_option(self):
|
||||||
"User BaseCommands can execute with options when a label is provided"
|
"User BaseCommands can execute with options when a label is provided"
|
||||||
args = ['base_command', 'testlabel', '--option_a=x']
|
args = ['base_command', 'testlabel', '--option_a=x']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_base_command_with_options(self):
|
def test_base_command_with_options(self):
|
||||||
"User BaseCommands can execute with multiple options when a label is provided"
|
"User BaseCommands can execute with multiple options when a label is provided"
|
||||||
args = ['base_command', 'testlabel', '-a', 'x', '--option_b=y']
|
args = ['base_command', 'testlabel', '-a', 'x', '--option_b=y']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_base_run_from_argv(self):
|
def test_base_run_from_argv(self):
|
||||||
"""
|
"""
|
||||||
|
@ -1359,12 +1360,27 @@ class CommandTypes(AdminScriptTestCase):
|
||||||
finally:
|
finally:
|
||||||
sys.stderr = old_stderr
|
sys.stderr = old_stderr
|
||||||
|
|
||||||
|
def test_run_from_argv_non_ascii_error(self):
|
||||||
|
"""
|
||||||
|
Test that non-ascii message of CommandError does not raise any
|
||||||
|
UnicodeDecodeError in run_from_argv.
|
||||||
|
"""
|
||||||
|
def raise_command_error(*args, **kwargs):
|
||||||
|
raise CommandError("Erreur personnalisée")
|
||||||
|
|
||||||
|
command = BaseCommand()
|
||||||
|
command.execute = raise_command_error
|
||||||
|
command.stderr = StringIO()
|
||||||
|
|
||||||
|
with self.assertRaises(SystemExit):
|
||||||
|
command.run_from_argv(['', ''])
|
||||||
|
|
||||||
def test_noargs(self):
|
def test_noargs(self):
|
||||||
"NoArg Commands can be executed"
|
"NoArg Commands can be executed"
|
||||||
args = ['noargs_command']
|
args = ['noargs_command']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:NoArgsCommand options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_noargs_with_args(self):
|
def test_noargs_with_args(self):
|
||||||
"NoArg Commands raise an error if an argument is provided"
|
"NoArg Commands raise an error if an argument is provided"
|
||||||
|
@ -1379,7 +1395,7 @@ class CommandTypes(AdminScriptTestCase):
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'")
|
self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'")
|
||||||
self.assertOutput(out, os.sep.join(['django', 'contrib', 'auth', 'models.py']))
|
self.assertOutput(out, os.sep.join(['django', 'contrib', 'auth', 'models.py']))
|
||||||
self.assertOutput(out, "'>, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("'>, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_app_command_no_apps(self):
|
def test_app_command_no_apps(self):
|
||||||
"User AppCommands raise an error when no app name is provided"
|
"User AppCommands raise an error when no app name is provided"
|
||||||
|
@ -1394,10 +1410,10 @@ class CommandTypes(AdminScriptTestCase):
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'")
|
self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'")
|
||||||
self.assertOutput(out, os.sep.join(['django', 'contrib', 'auth', 'models.py']))
|
self.assertOutput(out, os.sep.join(['django', 'contrib', 'auth', 'models.py']))
|
||||||
self.assertOutput(out, "'>, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("'>, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.contenttypes.models'")
|
self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.contenttypes.models'")
|
||||||
self.assertOutput(out, os.sep.join(['django', 'contrib', 'contenttypes', 'models.py']))
|
self.assertOutput(out, os.sep.join(['django', 'contrib', 'contenttypes', 'models.py']))
|
||||||
self.assertOutput(out, "'>, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("'>, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_app_command_invalid_appname(self):
|
def test_app_command_invalid_appname(self):
|
||||||
"User AppCommands can execute when a single app name is provided"
|
"User AppCommands can execute when a single app name is provided"
|
||||||
|
@ -1416,7 +1432,7 @@ class CommandTypes(AdminScriptTestCase):
|
||||||
args = ['label_command', 'testlabel']
|
args = ['label_command', 'testlabel']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:LabelCommand label=testlabel, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_label_command_no_label(self):
|
def test_label_command_no_label(self):
|
||||||
"User LabelCommands raise an error if no label is provided"
|
"User LabelCommands raise an error if no label is provided"
|
||||||
|
@ -1429,8 +1445,8 @@ class CommandTypes(AdminScriptTestCase):
|
||||||
args = ['label_command', 'testlabel', 'anotherlabel']
|
args = ['label_command', 'testlabel', 'anotherlabel']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:LabelCommand label=testlabel, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
self.assertOutput(out, "EXECUTE:LabelCommand label=anotherlabel, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:LabelCommand label=anotherlabel, options=[('no_color', False), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
class ArgumentOrder(AdminScriptTestCase):
|
class ArgumentOrder(AdminScriptTestCase):
|
||||||
"""Tests for 2-stage argument parsing scheme.
|
"""Tests for 2-stage argument parsing scheme.
|
||||||
|
@ -1454,35 +1470,35 @@ class ArgumentOrder(AdminScriptTestCase):
|
||||||
args = ['base_command', 'testlabel', '--settings=alternate_settings', '--option_a=x']
|
args = ['base_command', 'testlabel', '--settings=alternate_settings', '--option_a=x']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_setting_then_short_option(self):
|
def test_setting_then_short_option(self):
|
||||||
"Short options passed after settings are correctly handled"
|
"Short options passed after settings are correctly handled"
|
||||||
args = ['base_command', 'testlabel', '--settings=alternate_settings', '--option_a=x']
|
args = ['base_command', 'testlabel', '--settings=alternate_settings', '--option_a=x']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_option_then_setting(self):
|
def test_option_then_setting(self):
|
||||||
"Options passed before settings are correctly handled"
|
"Options passed before settings are correctly handled"
|
||||||
args = ['base_command', 'testlabel', '--option_a=x', '--settings=alternate_settings']
|
args = ['base_command', 'testlabel', '--option_a=x', '--settings=alternate_settings']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_short_option_then_setting(self):
|
def test_short_option_then_setting(self):
|
||||||
"Short options passed before settings are correctly handled"
|
"Short options passed before settings are correctly handled"
|
||||||
args = ['base_command', 'testlabel', '-a', 'x', '--settings=alternate_settings']
|
args = ['base_command', 'testlabel', '-a', 'x', '--settings=alternate_settings']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
def test_option_then_setting_then_option(self):
|
def test_option_then_setting_then_option(self):
|
||||||
"Options are correctly handled when they are passed before and after a setting"
|
"Options are correctly handled when they are passed before and after a setting"
|
||||||
args = ['base_command', 'testlabel', '--option_a=x', '--settings=alternate_settings', '--option_b=y']
|
args = ['base_command', 'testlabel', '--option_a=x', '--settings=alternate_settings', '--option_b=y']
|
||||||
out, err = self.run_manage(args)
|
out, err = self.run_manage(args)
|
||||||
self.assertNoOutput(err)
|
self.assertNoOutput(err)
|
||||||
self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
|
self.assertOutput(out, str_prefix("EXECUTE:BaseCommand labels=('testlabel',), options=[('no_color', False), ('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', %(_)s'1')]"))
|
||||||
|
|
||||||
|
|
||||||
class StartProject(LiveServerTestCase, AdminScriptTestCase):
|
class StartProject(LiveServerTestCase, AdminScriptTestCase):
|
||||||
|
|
Loading…
Reference in New Issue