Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.5.x] Fixed #19665 -- Ensured proper stderr output for Command.run_…

…from_argv

Thanks Stefan Koegl for the report and Simon Charette for the review.
Backport of b9c8bbf from master.
  • Loading branch information...
commit 2d8b0315f46d24c6567a05422bd609f3a689bda8 1 parent 42fcfca
Claude Paroz authored January 25, 2013
7  django/core/management/base.py
@@ -221,9 +221,12 @@ def run_from_argv(self, argv):
221 221
         try:
222 222
             self.execute(*args, **options.__dict__)
223 223
         except Exception as e:
  224
+            # self.stderr is not guaranteed to be set here
  225
+            stderr = getattr(self, 'stderr', OutputWrapper(sys.stderr, self.style.ERROR))
224 226
             if options.traceback:
225  
-                self.stderr.write(traceback.format_exc())
226  
-            self.stderr.write('%s: %s' % (e.__class__.__name__, e))
  227
+                stderr.write(traceback.format_exc())
  228
+            else:
  229
+                stderr.write('%s: %s' % (e.__class__.__name__, e))
227 230
             sys.exit(1)
228 231
 
229 232
     def execute(self, *args, **options):
27  tests/regressiontests/admin_scripts/tests.py
@@ -16,11 +16,13 @@
16 16
 
17 17
 from django import conf, bin, get_version
18 18
 from django.conf import settings
  19
+from django.core.management import BaseCommand
19 20
 from django.db import connection
20 21
 from django.test.simple import DjangoTestSuiteRunner
21 22
 from django.utils import unittest
22 23
 from django.utils.encoding import force_str, force_text
23 24
 from django.utils._os import upath
  25
+from django.utils.six import StringIO
24 26
 from django.test import LiveServerTestCase
25 27
 
26 28
 test_dir = os.path.dirname(os.path.dirname(upath(__file__)))
@@ -1279,6 +1281,31 @@ def test_base_command_with_options(self):
1279 1281
         self.assertNoOutput(err)
1280 1282
         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')]")
1281 1283
 
  1284
+    def test_base_run_from_argv(self):
  1285
+        """
  1286
+        Test run_from_argv properly terminates even with custom execute() (#19665)
  1287
+        Also test proper traceback display.
  1288
+        """
  1289
+        command = BaseCommand()
  1290
+        command.execute = lambda args: args  # This will trigger TypeError
  1291
+
  1292
+        old_stderr = sys.stderr
  1293
+        sys.stderr = err = StringIO()
  1294
+        try:
  1295
+            with self.assertRaises(SystemExit):
  1296
+                command.run_from_argv(['', ''])
  1297
+            err_message = err.getvalue()
  1298
+            self.assertNotIn("Traceback", err_message)
  1299
+            self.assertIn("TypeError", err_message)
  1300
+
  1301
+            with self.assertRaises(SystemExit):
  1302
+                command.run_from_argv(['', '', '--traceback'])
  1303
+            err_message = err.getvalue()
  1304
+            self.assertIn("Traceback (most recent call last)", err_message)
  1305
+            self.assertIn("TypeError", err_message)
  1306
+        finally:
  1307
+            sys.stderr = old_stderr
  1308
+
1282 1309
     def test_noargs(self):
1283 1310
         "NoArg Commands can be executed"
1284 1311
         args = ['noargs_command']

0 notes on commit 2d8b031

Please sign in to comment.
Something went wrong with that request. Please try again.