diff options
| author | Claude Paroz <claude@2xlibre.net> | 2012-05-26 20:50:44 +0200 |
|---|---|---|
| committer | Claude Paroz <claude@2xlibre.net> | 2012-05-27 20:38:47 +0200 |
| commit | f2b6763ad7cb281ca8699a9c3d532a82f965be4f (patch) | |
| tree | 7fbbb6d1bd00aa9b29b5b8f42e49c3e50cbdc5a0 /django | |
| parent | 4423757c0c50afbe2470434778c8d5e5b4a70925 (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.py | 13 | ||||
| -rw-r--r-- | django/core/management/base.py | 44 |
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) |
