summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErik Rose <grinch@grinchcentral.com>2013-08-30 00:21:40 -0400
committerErik Rose <grinch@grinchcentral.com>2013-08-30 00:21:40 -0400
commit645ca3ec98dddf79c7f29569651e4395e81a8404 (patch)
treef9356e7154997e194702671eaf055f2c023abe2a
parentaa332f70c6235fd8fcb8194baf7653341218680b (diff)
parent7eb5c1854398d95c054f50f95f75a12b9b42a24b (diff)
downloadblessings-645ca3ec98dddf79c7f29569651e4395e81a8404.tar.gz
Merge Vitja Makarov's NullCallableString tty-less parametrization fix. Close #31.
-rw-r--r--README.rst2
-rw-r--r--blessings/__init__.py47
-rw-r--r--blessings/tests.py13
-rw-r--r--setup.py2
4 files changed, 54 insertions, 10 deletions
diff --git a/README.rst b/README.rst
index 36eb6e4..4586b02 100644
--- a/README.rst
+++ b/README.rst
@@ -440,6 +440,8 @@ Version History
* Work around a tox parsing bug in its config file.
* Make context managers clean up after themselves even if there's an
exception. (Vitja Makarov)
+ * Parametrizing a capability no longer crashes when there is no tty. (Vitja
+ Makarov)
1.5
* Add syntactic sugar and documentation for ``enter_fullscreen`` and
diff --git a/blessings/__init__.py b/blessings/__init__.py
index 276565b..725602e 100644
--- a/blessings/__init__.py
+++ b/blessings/__init__.py
@@ -152,7 +152,7 @@ class Terminal(object):
no_underline='rmul')
def __getattr__(self, attr):
- """Return parametrized terminal capabilities, like bold.
+ """Return a terminal capability, like bold.
For example, you can say ``term.bold`` to get the string that turns on
bold formatting and ``term.normal`` to get the string that turns it off
@@ -307,7 +307,11 @@ class Terminal(object):
return colors if colors >= 0 else 0
def _resolve_formatter(self, attr):
- """Resolve a sugary or plain capability name, color, or compound formatting function name into a callable capability."""
+ """Resolve a sugary or plain capability name, color, or compound formatting function name into a callable capability.
+
+ Return a ``ParametrizingString`` or a ``FormattingString``.
+
+ """
if attr in COLORS:
return self._resolve_color(attr)
elif attr in COMPOUNDABLES:
@@ -442,21 +446,46 @@ class FormattingString(unicode):
class NullCallableString(unicode):
- """A dummy class to stand in for ``FormattingString`` and ``ParametrizingString``
+ """A dummy callable Unicode to stand in for ``FormattingString`` and ``ParametrizingString``
- A callable bytestring that returns an empty Unicode when called with an int
- and the arg otherwise. We use this when there is no tty and so all
- capabilities are blank.
+ We use this when there is no tty and thus all capabilities should be blank.
"""
def __new__(cls):
new = unicode.__new__(cls, u'')
return new
- def __call__(self, arg):
- if isinstance(arg, int):
+ def __call__(self, *args):
+ """Return a Unicode or whatever you passed in as the first arg (hopefully a string of some kind).
+
+ When called with an int as the first arg, return an empty Unicode. An
+ int is a good hint that I am a ``ParametrizingString``, as there are
+ only about half a dozen string-returning capabilities on OS X's
+ terminfo man page which take any param that's not an int, and those are
+ seldom if ever used on modern terminal emulators. (Most have to do with
+ programming function keys. Blessings' story for supporting
+ non-string-returning caps is undeveloped.) And any parametrized
+ capability in a situation where all capabilities themselves are taken
+ to be blank are, of course, themselves blank.
+
+ When called with a non-int as the first arg (no no args at all), return
+ the first arg. I am acting as a ``FormattingString``.
+
+ """
+ if len(args) != 1 or isinstance(args[0], int):
+ # I am acting as a ParametrizingString.
+
+ # tparm can take not only ints but also (at least) strings as its
+ # second...nth args. But we don't support callably parametrizing
+ # caps that take non-ints yet, so we can cheap out here. TODO: Go
+ # through enough of the motions in the capability resolvers to
+ # determine which of 2 special-purpose classes,
+ # NullParametrizableString or NullFormattingString, to return, and
+ # retire this one.
return u''
- return arg # TODO: Force even strs in Python 2.x to be unicodes? Nah. How would I know what encoding to use to convert it?
+ return args[0] # Should we force even strs in Python 2.x to be
+ # unicodes? No. How would I know what encoding to use
+ # to convert it?
def split_into_formatters(compound):
diff --git a/blessings/tests.py b/blessings/tests.py
index a885c65..c7a3527 100644
--- a/blessings/tests.py
+++ b/blessings/tests.py
@@ -254,3 +254,16 @@ def test_force_styling_none():
"""If ``force_styling=None`` is passed to the constructor, don't ever do styling."""
t = TestTerminal(force_styling=None)
eq_(t.save, '')
+
+
+def test_null_callable_string():
+ """Make sure NullCallableString tolerates all numbers and kinds of args it might receive."""
+ t = TestTerminal(stream=StringIO())
+
+ # I don't promise this will keep working; it's not documented anywhere.
+ # However, it's what I intend to happen in an edge case, so let's make sure
+ # it works.
+ eq_(t.clear(), '')
+
+ eq_(t.move(1, 2), '')
+ eq_(t.move_x(1), '')
diff --git a/setup.py b/setup.py
index 7dd18d0..ba705da 100644
--- a/setup.py
+++ b/setup.py
@@ -16,7 +16,7 @@ if sys.version_info >= (3,):
setup(
name='blessings',
- version='1.5',
+ version='1.5.1',
description='A thin, practical wrapper around terminal coloring, styling, and positioning',
long_description=open('README.rst').read(),
author='Erik Rose',