summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Bistuer <loic.bistuer@gmail.com>2014-10-21 15:31:24 +0700
committerLoic Bistuer <loic.bistuer@gmail.com>2014-10-22 11:27:00 +0700
commiteb82fb0a9d14ca317d366afb65e21d742bbe46a5 (patch)
tree5105e3d635f823ba47753ae6fbbfe9213ba1f353
parentbdb4118b1ad166e2d02f725354ca1c1021976cb5 (diff)
Refactored color_style() and no_style() to improve testability. Refs #23663.
This includes the following improvements: - The type of the style object is now called 'Style' rather than 'dummy'. - The new make_style() function allows generating a Style object directly from a config string. Before the only way to get a style object was through the environ and it also required that the terminal supported colors which isn't necessarily the case when testing. - The output of no_style() is now cached with @lru_cache. - The output of no_style() now has the same set of attributes as the other Style objects. Previously it allowed anything to pass through with __getattr__.
-rw-r--r--django/core/management/color.py74
-rw-r--r--tests/admin_scripts/tests.py16
2 files changed, 61 insertions, 29 deletions
diff --git a/django/core/management/color.py b/django/core/management/color.py
index 3890a4546f..ce47f318ff 100644
--- a/django/core/management/color.py
+++ b/django/core/management/color.py
@@ -5,17 +5,18 @@ Sets up the terminal color scheme.
import os
import sys
+from django.utils import lru_cache
from django.utils import termcolors
def supports_color():
"""
- Returns True if the running system's terminal supports color, and False
- otherwise.
+ Returns True if the running system's terminal supports color,
+ and False otherwise.
"""
plat = sys.platform
- supported_platform = plat != 'Pocket PC' and (plat != 'win32' or
- 'ANSICON' in os.environ)
+ supported_platform = plat != 'Pocket PC' and (plat != 'win32' or 'ANSICON' in os.environ)
+
# isatty is not always implemented, #6223.
is_a_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
if not supported_platform or not is_a_tty:
@@ -23,34 +24,49 @@ def supports_color():
return True
-def color_style():
- """Returns a Style object with the Django color scheme."""
- if not supports_color():
- style = no_style()
- else:
- DJANGO_COLORS = os.environ.get('DJANGO_COLORS', '')
- color_settings = termcolors.parse_color_setting(DJANGO_COLORS)
+def make_style(config_string=''):
+ """
+ Create a Style object from the given config_string.
+
+ If config_string is empty django.utils.termcolors.DEFAULT_PALETTE is used.
+ """
+ class Style(object):
+ pass
+
+ style = Style()
+
+ color_settings = termcolors.parse_color_setting(config_string)
+
+ # The nocolor palette has all available roles.
+ # Use that palette as the basis for populating
+ # the palette as defined in the environment.
+ for role in termcolors.PALETTES[termcolors.NOCOLOR_PALETTE]:
if color_settings:
- class dummy:
- pass
- style = dummy()
- # The nocolor palette has all available roles.
- # Use that palette as the basis for populating
- # the palette as defined in the environment.
- for role in termcolors.PALETTES[termcolors.NOCOLOR_PALETTE]:
- format = color_settings.get(role, {})
- setattr(style, role, termcolors.make_style(**format))
- # For backwards compatibility,
- # set style for ERROR_OUTPUT == ERROR
- style.ERROR_OUTPUT = style.ERROR
+ format = color_settings.get(role, {})
+ style_func = termcolors.make_style(**format)
else:
- style = no_style()
+ style_func = lambda x: x
+ setattr(style, role, style_func)
+
+ # For backwards compatibility,
+ # set style for ERROR_OUTPUT == ERROR
+ style.ERROR_OUTPUT = style.ERROR
+
return style
+@lru_cache.lru_cache(maxsize=None)
def no_style():
- """Returns a Style object that has no colors."""
- class dummy:
- def __getattr__(self, attr):
- return lambda x: x
- return dummy()
+ """
+ Returns a Style object with no color scheme.
+ """
+ return make_style('nocolor')
+
+
+def color_style():
+ """
+ Returns a Style object from the Django color scheme.
+ """
+ if not supports_color():
+ return no_style()
+ return make_style(os.environ.get('DJANGO_COLORS', ''))
diff --git a/tests/admin_scripts/tests.py b/tests/admin_scripts/tests.py
index c19fbb9019..5bc0fb3ee1 100644
--- a/tests/admin_scripts/tests.py
+++ b/tests/admin_scripts/tests.py
@@ -1392,6 +1392,22 @@ class CommandTypes(AdminScriptTestCase):
self.assertOutput(out, "Prints the CREATE TABLE, custom SQL and CREATE INDEX SQL statements for the\ngiven model module name(s).")
self.assertEqual(out.count('optional arguments'), 1)
+ def test_color_style(self):
+ style = color.no_style()
+ self.assertEqual(style.ERROR('Hello, world!'), 'Hello, world!')
+
+ style = color.make_style('nocolor')
+ self.assertEqual(style.ERROR('Hello, world!'), 'Hello, world!')
+
+ style = color.make_style('dark')
+ self.assertIn('Hello, world!', style.ERROR('Hello, world!'))
+ self.assertNotEqual(style.ERROR('Hello, world!'), 'Hello, world!')
+
+ # Default palette has color.
+ style = color.make_style('')
+ self.assertIn('Hello, world!', style.ERROR('Hello, world!'))
+ self.assertNotEqual(style.ERROR('Hello, world!'), 'Hello, world!')
+
def test_command_color(self):
class Command(BaseCommand):
requires_system_checks = False