Loading django/contrib/auth/tests/management.py +4 −9 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) django/core/management/base.py +17 −27 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) 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. Loading @@ -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) try: if self.requires_model_validation and not options.get('skip_validation'): Loading @@ -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) Loading docs/howto/custom-management-commands.txt +7 −3 Original line number Diff line number Diff line Loading @@ -317,8 +317,12 @@ Exception class indicating a problem while executing a management command. If this exception is raised during the execution of a management command, it will be caught and turned into a nicely-printed error message to the appropriate output stream (i.e., stderr); as a result, raising this exception (with a sensible description of the command from a command line console, it will be caught and turned into a nicely-printed error message to the appropriate output stream (i.e., stderr); as a result, raising this exception (with a sensible description of the error) is the preferred way to indicate that something has gone wrong in the execution of a command. If a management command is called from code through :ref:`call_command <call-command>`, it's up to you to catch the exception when needed. docs/releases/1.5.txt +4 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,10 @@ Django 1.5 also includes several smaller improvements worth noting: * The generic views support OPTIONS requests. * Management commands do not raise ``SystemExit`` any more when called by code from :ref:`call_command <call-command>`. Any exception raised by the command (mostly :ref:`CommandError <ref-command-exceptions>`) is propagated. * The dumpdata management command outputs one row at a time, preventing out-of-memory errors when dumping large datasets. Loading tests/modeltests/fixtures/tests.py +2 −2 Original line number Diff line number Diff line Loading @@ -185,14 +185,14 @@ class FixtureLoadingTests(TestCase): exclude_list=['fixtures.Article', 'fixtures.Book', 'sites']) # Excluding a bogus app should throw an error self.assertRaises(SystemExit, self.assertRaises(management.CommandError, self._dumpdata_assert, ['fixtures', 'sites'], '', exclude_list=['foo_app']) # Excluding a bogus model should throw an error self.assertRaises(SystemExit, self.assertRaises(management.CommandError, self._dumpdata_assert, ['fixtures', 'sites'], '', Loading Loading
django/contrib/auth/tests/management.py +4 −9 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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)
django/core/management/base.py +17 −27 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) 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. Loading @@ -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) try: if self.requires_model_validation and not options.get('skip_validation'): Loading @@ -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) Loading
docs/howto/custom-management-commands.txt +7 −3 Original line number Diff line number Diff line Loading @@ -317,8 +317,12 @@ Exception class indicating a problem while executing a management command. If this exception is raised during the execution of a management command, it will be caught and turned into a nicely-printed error message to the appropriate output stream (i.e., stderr); as a result, raising this exception (with a sensible description of the command from a command line console, it will be caught and turned into a nicely-printed error message to the appropriate output stream (i.e., stderr); as a result, raising this exception (with a sensible description of the error) is the preferred way to indicate that something has gone wrong in the execution of a command. If a management command is called from code through :ref:`call_command <call-command>`, it's up to you to catch the exception when needed.
docs/releases/1.5.txt +4 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,10 @@ Django 1.5 also includes several smaller improvements worth noting: * The generic views support OPTIONS requests. * Management commands do not raise ``SystemExit`` any more when called by code from :ref:`call_command <call-command>`. Any exception raised by the command (mostly :ref:`CommandError <ref-command-exceptions>`) is propagated. * The dumpdata management command outputs one row at a time, preventing out-of-memory errors when dumping large datasets. Loading
tests/modeltests/fixtures/tests.py +2 −2 Original line number Diff line number Diff line Loading @@ -185,14 +185,14 @@ class FixtureLoadingTests(TestCase): exclude_list=['fixtures.Article', 'fixtures.Book', 'sites']) # Excluding a bogus app should throw an error self.assertRaises(SystemExit, self.assertRaises(management.CommandError, self._dumpdata_assert, ['fixtures', 'sites'], '', exclude_list=['foo_app']) # Excluding a bogus model should throw an error self.assertRaises(SystemExit, self.assertRaises(management.CommandError, self._dumpdata_assert, ['fixtures', 'sites'], '', Loading