1
0
mirror of https://github.com/django/django.git synced 2025-08-23 10:19:13 +00:00

[1.6.x] Fixed #21269 -- Don't crash when CommandError contains non-ascii

Thanks kontakt@eikefoken.de for the report.

Backport of 42a67ec1cd from master.
This commit is contained in:
Claude Paroz 2013-10-14 20:24:57 +02:00
parent 7f566fdb4c
commit ba9cf9596b
2 changed files with 37 additions and 19 deletions

View File

@ -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

View File

@ -20,6 +20,7 @@ from django.conf import settings
from django.core.management import BaseCommand, CommandError from django.core.management import BaseCommand, CommandError
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 import unittest from django.utils import unittest
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
@ -921,14 +922,14 @@ 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=[('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]") self.assertOutput(out, str_prefix("EXECUTE:NoArgsCommand options=[('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=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") self.assertOutput(out, str_prefix("EXECUTE:NoArgsCommand options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
self.assertNoOutput(err) self.assertNoOutput(err)
@ -1277,35 +1278,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=[('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=[('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=[('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=[('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=[('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=[('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=[('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=[('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=[('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=[('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):
""" """
@ -1346,12 +1347,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=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") self.assertOutput(out, str_prefix("EXECUTE:NoArgsCommand options=[('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"
@ -1366,7 +1382,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=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") self.assertOutput(out, str_prefix("'>, options=[('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"
@ -1381,10 +1397,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=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") self.assertOutput(out, str_prefix("'>, options=[('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=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") self.assertOutput(out, str_prefix("'>, options=[('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"
@ -1403,7 +1419,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=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") self.assertOutput(out, str_prefix("EXECUTE:LabelCommand label=testlabel, options=[('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"
@ -1416,8 +1432,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=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") self.assertOutput(out, str_prefix("EXECUTE:LabelCommand label=testlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', %(_)s'1')]"))
self.assertOutput(out, "EXECUTE:LabelCommand label=anotherlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]") self.assertOutput(out, str_prefix("EXECUTE:LabelCommand label=anotherlabel, options=[('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.
@ -1441,35 +1457,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=[('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=[('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=[('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=[('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=[('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=[('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=[('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=[('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=[('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=[('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):