summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorLoic Bistuer <loic.bistuer@gmail.com>2014-10-22 01:11:31 +0700
committerLoic Bistuer <loic.bistuer@gmail.com>2014-10-22 09:25:50 +0700
commit533532302ae842c95cf7294ef6cd7f3e2bfaca65 (patch)
tree8be8c0dfea5029e7fa360f412c1f590eec734079 /django
parent494cd857c897dc4051193abc10d181fa51de4966 (diff)
Fixed #23663 -- Initialize output streams for BaseCommand in __init__().
This helps with testability of management commands. Thanks to trac username daveoncode for the report and to Tim Graham and Claude Paroz for the reviews.
Diffstat (limited to 'django')
-rw-r--r--django/contrib/staticfiles/management/commands/collectstatic.py2
-rw-r--r--django/core/management/base.py39
2 files changed, 27 insertions, 14 deletions
diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py
index e593056ce2..f004727c83 100644
--- a/django/contrib/staticfiles/management/commands/collectstatic.py
+++ b/django/contrib/staticfiles/management/commands/collectstatic.py
@@ -22,7 +22,7 @@ class Command(BaseCommand):
requires_system_checks = False
def __init__(self, *args, **kwargs):
- super(BaseCommand, self).__init__(*args, **kwargs)
+ super(Command, self).__init__(*args, **kwargs)
self.copied_files = []
self.symlinked_files = []
self.unmodified_files = []
diff --git a/django/core/management/base.py b/django/core/management/base.py
index 7b62d6c259..9e0c70a653 100644
--- a/django/core/management/base.py
+++ b/django/core/management/base.py
@@ -79,11 +79,20 @@ class OutputWrapper(object):
"""
Wrapper around stdout/stderr
"""
+ @property
+ def style_func(self):
+ return self._style_func
+
+ @style_func.setter
+ def style_func(self, style_func):
+ if style_func and hasattr(self._out, 'isatty') and self._out.isatty():
+ self._style_func = style_func
+ else:
+ self._style_func = lambda x: x
+
def __init__(self, out, style_func=None, ending='\n'):
self._out = out
self.style_func = None
- if hasattr(out, 'isatty') and out.isatty():
- self.style_func = style_func
self.ending = ending
def __getattr__(self, name):
@@ -93,8 +102,7 @@ class OutputWrapper(object):
ending = self.ending if ending is None else ending
if ending and not msg.endswith(ending):
msg += ending
- style_func = [f for f in (style_func, self.style_func, lambda x:x)
- if f is not None][0]
+ style_func = style_func or self.style_func
self._out.write(force_str(style_func(msg)))
@@ -221,8 +229,14 @@ class BaseCommand(object):
#
# requires_system_checks = True
- def __init__(self):
- self.style = color_style()
+ def __init__(self, stdout=None, stderr=None, no_color=False):
+ self.stdout = OutputWrapper(stdout or sys.stdout)
+ self.stderr = OutputWrapper(stderr or sys.stderr)
+ if no_color:
+ self.style = no_style()
+ else:
+ self.style = color_style()
+ self.stderr.style_func = self.style.ERROR
# `requires_model_validation` is deprecated in favor of
# `requires_system_checks`. If both options are present, an error is
@@ -371,9 +385,7 @@ class BaseCommand(object):
if options.traceback or not isinstance(e, CommandError):
raise
- # self.stderr is not guaranteed to be set here
- stderr = getattr(self, 'stderr', OutputWrapper(sys.stderr, self.style.ERROR))
- stderr.write('%s: %s' % (e.__class__.__name__, e))
+ self.stderr.write('%s: %s' % (e.__class__.__name__, e))
sys.exit(1)
def execute(self, *args, **options):
@@ -382,12 +394,13 @@ class BaseCommand(object):
controlled by attributes ``self.requires_system_checks`` and
``self.requires_model_validation``, except if force-skipped).
"""
- self.stdout = OutputWrapper(options.get('stdout', sys.stdout))
if options.get('no_color'):
self.style = no_style()
- self.stderr = OutputWrapper(options.get('stderr', sys.stderr))
- else:
- self.stderr = OutputWrapper(options.get('stderr', sys.stderr), self.style.ERROR)
+ self.stderr.style_func = None
+ if options.get('stdout'):
+ self.stdout = OutputWrapper(options['stdout'])
+ if options.get('stderr'):
+ self.stderr = OutputWrapper(options.get('stderr'), self.stderr.style_func)
if self.can_import_settings:
from django.conf import settings # NOQA