summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2012-05-26 20:50:44 +0200
committerClaude Paroz <claude@2xlibre.net>2012-05-27 20:38:47 +0200
commitf2b6763ad7cb281ca8699a9c3d532a82f965be4f (patch)
tree7fbbb6d1bd00aa9b29b5b8f42e49c3e50cbdc5a0 /django
parent4423757c0c50afbe2470434778c8d5e5b4a70925 (diff)
Fixed #18387 -- Do not call sys.exit during call_command.
Moved sys.exit(1) so as failing management commands reach it only when running from command line.
Diffstat (limited to 'django')
-rw-r--r--django/contrib/auth/tests/management.py13
-rw-r--r--django/core/management/base.py44
2 files changed, 21 insertions, 36 deletions
diff --git a/django/contrib/auth/tests/management.py b/django/contrib/auth/tests/management.py
index 5d31bd70a4..81ab0aa052 100644
--- a/django/contrib/auth/tests/management.py
+++ b/django/contrib/auth/tests/management.py
@@ -2,6 +2,7 @@ from StringIO import StringIO
from django.contrib.auth import models, management
from django.contrib.auth.management.commands import changepassword
+from django.core.management.base import CommandError
from django.test import TestCase
@@ -56,16 +57,10 @@ class ChangepasswordManagementCommandTestCase(TestCase):
def test_that_max_tries_exits_1(self):
"""
A CommandError should be thrown by handle() if the user enters in
- mismatched passwords three times. This should be caught by execute() and
- converted to a SystemExit
+ mismatched passwords three times.
"""
command = changepassword.Command()
command._get_pass = lambda *args: args or 'foo'
- self.assertRaises(
- SystemExit,
- command.execute,
- "joe",
- stdout=self.stdout,
- stderr=self.stderr
- )
+ with self.assertRaises(CommandError):
+ command.execute("joe", stdout=self.stdout, stderr=self.stderr)
diff --git a/django/core/management/base.py b/django/core/management/base.py
index 6e06991bf0..a204f6f0bc 100644
--- a/django/core/management/base.py
+++ b/django/core/management/base.py
@@ -97,8 +97,9 @@ class BaseCommand(object):
output and, if the command is intended to produce a block of
SQL statements, will be wrapped in ``BEGIN`` and ``COMMIT``.
- 4. If ``handle()`` raised a ``CommandError``, ``execute()`` will
- instead print an error message to ``stderr``.
+ 4. If ``handle()`` or ``execute()`` raised any exception (e.g.
+ ``CommandError``), ``run_from_argv()`` will instead print an error
+ message to ``stderr``.
Thus, the ``handle()`` method is typically the starting point for
subclasses; many built-in commands and command types either place
@@ -210,23 +211,27 @@ class BaseCommand(object):
def run_from_argv(self, argv):
"""
Set up any environment changes requested (e.g., Python path
- and Django settings), then run this command.
-
+ and Django settings), then run this command. If the
+ command raises a ``CommandError``, intercept it and print it sensibly
+ to stderr.
"""
parser = self.create_parser(argv[0], argv[1])
options, args = parser.parse_args(argv[2:])
handle_default_options(options)
- self.execute(*args, **options.__dict__)
+ try:
+ self.execute(*args, **options.__dict__)
+ except Exception as e:
+ if options.traceback:
+ self.stderr.write(traceback.format_exc())
+ self.stderr.write('%s: %s' % (e.__class__.__name__, e))
+ sys.exit(1)
def execute(self, *args, **options):
"""
Try to execute this command, performing model validation if
needed (as controlled by the attribute
- ``self.requires_model_validation``, except if force-skipped). If the
- command raises a ``CommandError``, intercept it and print it sensibly
- to stderr.
+ ``self.requires_model_validation``, except if force-skipped).
"""
- show_traceback = options.get('traceback', False)
# Switch to English, because django-admin.py creates database content
# like permissions, and those shouldn't contain any translations.
@@ -237,18 +242,9 @@ class BaseCommand(object):
self.stderr = OutputWrapper(options.get('stderr', sys.stderr), self.style.ERROR)
if self.can_import_settings:
- try:
- from django.utils import translation
- saved_lang = translation.get_language()
- translation.activate('en-us')
- except ImportError as e:
- # If settings should be available, but aren't,
- # raise the error and quit.
- if show_traceback:
- traceback.print_exc()
- else:
- self.stderr.write('Error: %s' % e)
- sys.exit(1)
+ from django.utils import translation
+ saved_lang = translation.get_language()
+ translation.activate('en-us')
try:
if self.requires_model_validation and not options.get('skip_validation'):
@@ -265,12 +261,6 @@ class BaseCommand(object):
self.stdout.write(output)
if self.output_transaction:
self.stdout.write('\n' + self.style.SQL_KEYWORD("COMMIT;"))
- except CommandError as e:
- if show_traceback:
- traceback.print_exc()
- else:
- self.stderr.write('Error: %s' % e)
- sys.exit(1)
finally:
if saved_lang is not None:
translation.activate(saved_lang)