Hello community,

here is the log from the commit of package python-cliff for openSUSE:Factory 
checked in at 2016-10-04 16:00:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-cliff (Old)
 and      /work/SRC/openSUSE:Factory/.python-cliff.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-cliff"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-cliff/python-cliff.changes        
2016-07-14 09:46:16.000000000 +0200
+++ /work/SRC/openSUSE:Factory/.python-cliff.new/python-cliff.changes   
2016-10-04 16:00:34.000000000 +0200
@@ -1,0 +2,15 @@
+Tue Oct  4 10:25:23 UTC 2016 - [email protected]
+
+update to version 2.2.0
+  * Fixed broken link
+  * pep8: fix F405 error
+  * add formattable columns concept
+  * command: make run() return take_action() value
+  * Fix cliff URLs in doc and demoapp
+  * Avoid ASCII encoding errors when output is redirected
+  * Fix Command class doc typo
+  * Remove announce.rst
+  * Updated from global requirements
+  * Add tests, cover more cases
+
+-------------------------------------------------------------------

Old:
----
  cliff-2.1.0.tar.gz

New:
----
  cliff-2.2.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-cliff.spec ++++++
--- /var/tmp/diff_new_pack.6GtgcB/_old  2016-10-04 16:00:35.000000000 +0200
+++ /var/tmp/diff_new_pack.6GtgcB/_new  2016-10-04 16:00:35.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           python-cliff
-Version:        2.1.0
+Version:        2.2.0
 Release:        0
 Url:            https://github.com/dreamhost/cliff
 Summary:        Command Line Interface Formulation Framework

++++++ cliff-2.1.0.tar.gz -> cliff-2.2.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/AUTHORS new/cliff-2.2.0/AUTHORS
--- old/cliff-2.1.0/AUTHORS     2016-06-16 15:21:48.000000000 +0200
+++ new/cliff-2.2.0/AUTHORS     2016-08-15 21:21:08.000000000 +0200
@@ -22,6 +22,7 @@
 Jamie Lennox <[email protected]>
 Jeremy Stanley <[email protected]>
 Joe Server <[email protected]>
+John Dennis <[email protected]>
 Jonathan LaCour <[email protected]>
 Juan Antonio Osorio Robles <[email protected]>
 Julien Danjou <[email protected]>
@@ -39,6 +40,7 @@
 Ricardo Kirkner <[email protected]>
 Rui Chen <[email protected]>
 Ryan Petrello <[email protected]>
+Ryan Selden <[email protected]>
 Sascha Peilicke <[email protected]>
 Sean Perry <[email protected]>
 Steve Baker <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/ChangeLog new/cliff-2.2.0/ChangeLog
--- old/cliff-2.1.0/ChangeLog   2016-06-16 15:21:48.000000000 +0200
+++ new/cliff-2.2.0/ChangeLog   2016-08-15 21:21:08.000000000 +0200
@@ -1,6 +1,21 @@
 CHANGES
 =======
 
+2.2.0
+-----
+
+* Avoid ASCII encoding errors when output is redirected
+* Fix cliff URLs in doc and demoapp
+* Remove announce.rst
+* Fix Command class doc typo
+* Updated from global requirements
+* Fixed broken link
+* add formattable columns concept
+* Add tests, cover more cases
+* Updated from global requirements
+* pep8: fix F405 error
+* command: make run() return take_action() value
+
 2.1.0
 -----
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/PKG-INFO new/cliff-2.2.0/PKG-INFO
--- old/cliff-2.1.0/PKG-INFO    2016-06-16 15:21:48.000000000 +0200
+++ new/cliff-2.2.0/PKG-INFO    2016-08-15 21:21:09.000000000 +0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: cliff
-Version: 2.1.0
+Version: 2.2.0
 Summary: Command Line Interface Formulation Framework
 Home-page: https://launchpad.net/python-cliff
 Author: OpenStack
@@ -14,7 +14,7 @@
         `setuptools entry points`_ to provide subcommands, output formatters, 
and
         other extensions.
         
-        .. _setuptools entry points: 
http://pythonhosted.org/setuptools/pkg_resources.html#convenience-api
+        .. _setuptools entry points: 
http://setuptools.readthedocs.io/en/latest/pkg_resources.html#convenience-api
         
         * Free software: Apache license
         * Documentation: http://docs.openstack.org/developer/cliff
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/README.rst new/cliff-2.2.0/README.rst
--- old/cliff-2.1.0/README.rst  2016-06-16 15:19:52.000000000 +0200
+++ new/cliff-2.2.0/README.rst  2016-08-15 21:19:43.000000000 +0200
@@ -6,7 +6,7 @@
 `setuptools entry points`_ to provide subcommands, output formatters, and
 other extensions.
 
-.. _setuptools entry points: 
http://pythonhosted.org/setuptools/pkg_resources.html#convenience-api
+.. _setuptools entry points: 
http://setuptools.readthedocs.io/en/latest/pkg_resources.html#convenience-api
 
 * Free software: Apache license
 * Documentation: http://docs.openstack.org/developer/cliff
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/announce.rst new/cliff-2.2.0/announce.rst
--- old/cliff-2.1.0/announce.rst        2016-06-16 15:19:52.000000000 +0200
+++ new/cliff-2.2.0/announce.rst        1970-01-01 01:00:00.000000000 +0100
@@ -1,40 +0,0 @@
-========================================================================
- cliff -- Command Line Interface Formulation Framework -- version 1.5.0
-========================================================================
-
-.. tags:: python cliff release DreamHost
-
-cliff is a framework for building command line programs. It uses
-setuptools entry points to provide subcommands, output formatters, and
-other extensions.
-
-What's New In This Release?
-===========================
-
-- Fix the arguments passed to commands when they are instantiated to
-  pull out help. See https://github.com/dreamhost/cliff/issues/52 for
-  details.
-- Add bash command completion. (Contributed by Terry Howe)
-- Use stevedore to load formatter plugins.
-- Use pbr for packaging.
-
-Documentation
-=============
-
-`Documentation for cliff`_ is hosted on `readthedocs.org`_
-
-.. _Documentation for cliff: http://readthedocs.org/docs/cliff/en/latest/
-
-.. _readthedocs.org: http://readthedocs.org
-
-Installation
-============
-
-Use pip::
-
-  $ pip install cliff
-
-See `the installation guide`_ for more details.
-
-.. _the installation guide: http://cliff.readthedocs.org/en/latest/install.html
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/app.py new/cliff-2.2.0/cliff/app.py
--- old/cliff-2.1.0/cliff/app.py        2016-06-16 15:19:52.000000000 +0200
+++ new/cliff-2.2.0/cliff/app.py        2016-08-15 21:19:43.000000000 +0200
@@ -1,11 +1,13 @@
 """Application base class.
 """
 
+import codecs
 import inspect
 import locale
 import logging
 import logging.handlers
 import os
+import six
 import sys
 
 from cliff import argparse
@@ -70,6 +72,45 @@
             locale.setlocale(locale.LC_ALL, '')
         except locale.Error:
             pass
+
+        # Unicode must be encoded/decoded for text I/O streams, the
+        # correct encoding for the stream must be selected and it must
+        # be capable of handling the set of characters in the stream
+        # or Python will raise a codec error. The correct codec is
+        # selected based on the locale. Python2 uses the locales
+        # encoding but only when the I/O stream is attached to a
+        # terminal (TTY) otherwise it uses the default ASCII
+        # encoding. The effect is internationalized text written to
+        # the terminal works as expected but if command line output is
+        # redirected (file or pipe) the ASCII codec is used and the
+        # program aborts with a codec error.
+        #
+        # The default I/O streams stdin, stdout and stderr can be
+        # wrapped in a codec based on the locale thus assuring the
+        # users desired encoding is always used no matter the I/O
+        # destination. Python3 does this by default.
+        #
+        # If the caller supplies an I/O stream we use it unmodified on
+        # the assumption the caller has taken all responsibility for
+        # the stream.  But with Python2 if the caller allows us to
+        # default the I/O streams to sys.stdin, sys.stdout and
+        # sys.stderr we apply the locales encoding just as Python3
+        # would do. We also check to make sure the main Python program
+        # has not already already wrapped sys.stdin, sys.stdout and
+        # sys.stderr as this is a common recommendation.
+
+        if six.PY2:
+            encoding = locale.getpreferredencoding()
+            if encoding:
+                if not (stdin or isinstance(sys.stdin, codecs.StreamReader)):
+                    stdin = codecs.getreader(encoding)(sys.stdin)
+
+                if not (stdout or isinstance(sys.stdout, codecs.StreamWriter)):
+                    stdout = codecs.getwriter(encoding)(sys.stdout)
+
+                if not (stderr or isinstance(sys.stderr, codecs.StreamWriter)):
+                    stderr = codecs.getwriter(encoding)(sys.stderr)
+
         self.stdin = stdin or sys.stdin
         self.stdout = stdout or sys.stdout
         self.stderr = stderr or sys.stderr
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/argparse.py 
new/cliff-2.2.0/cliff/argparse.py
--- old/cliff-2.1.0/cliff/argparse.py   2016-06-16 15:19:52.000000000 +0200
+++ new/cliff-2.2.0/cliff/argparse.py   2016-08-15 21:19:43.000000000 +0200
@@ -6,7 +6,7 @@
 
 
 if sys.version_info < (3, 5):
-    class ArgumentParser(ArgumentParser):
+    class ArgumentParser(ArgumentParser):  # noqa
         def __init__(self, *args, **kwargs):
             self.allow_abbrev = kwargs.pop("allow_abbrev", True)
             super(ArgumentParser, self).__init__(*args, **kwargs)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/columns.py 
new/cliff-2.2.0/cliff/columns.py
--- old/cliff-2.1.0/cliff/columns.py    1970-01-01 01:00:00.000000000 +0100
+++ new/cliff-2.2.0/cliff/columns.py    2016-08-15 21:19:43.000000000 +0200
@@ -0,0 +1,28 @@
+"""Formattable column tools.
+"""
+
+import abc
+
+import six
+
+
[email protected]_metaclass(abc.ABCMeta)
+class FormattableColumn(object):
+
+    def __init__(self, value):
+        self._value = value
+
+    @abc.abstractmethod
+    def human_readable(self):
+        """Return a basic human readable version of the data.
+        """
+
+    def machine_readable(self):
+        """Return a raw data structure using only Python built-in types.
+
+        It must be possible to serialize the return value directly
+        using a formatter like JSON, and it will be up to the
+        formatter plugin to decide how to make that transformation.
+
+        """
+        return self._value
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/command.py 
new/cliff-2.2.0/cliff/command.py
--- old/cliff-2.1.0/cliff/command.py    2016-06-16 15:19:52.000000000 +0200
+++ new/cliff-2.2.0/cliff/command.py    2016-08-15 21:19:43.000000000 +0200
@@ -40,6 +40,8 @@
     @abc.abstractmethod
     def take_action(self, parsed_args):
         """Override to do something useful.
+
+        The returned value will be returned by the program.
         """
 
     def run(self, parsed_args):
@@ -51,6 +53,7 @@
         Developers creating new command base classes (such as
         :class:`Lister` and :class:`ShowOne`) should override this
         method to wrap :meth:`take_action`.
+
+        Return the value returned by :meth:`take_action` or 0.
         """
-        self.take_action(parsed_args)
-        return 0
+        return self.take_action(parsed_args) or 0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/formatters/base.py 
new/cliff-2.2.0/cliff/formatters/base.py
--- old/cliff-2.1.0/cliff/formatters/base.py    2016-06-16 15:19:52.000000000 
+0200
+++ new/cliff-2.2.0/cliff/formatters/base.py    2016-08-15 21:19:43.000000000 
+0200
@@ -26,11 +26,18 @@
     def emit_list(self, column_names, data, stdout, parsed_args):
         """Format and print the list from the iterable data source.
 
+        Data values can be primitive types like ints and strings, or
+        can be an instance of a :class:`FormattableColumn` for
+        situations where the value is complex, and may need to be
+        handled differently for human readable output vs. machine
+        readable output.
+
         :param column_names: names of the columns
         :param data: iterable data source, one tuple per object
                      with values in order of column names
         :param stdout: output stream where data should be written
         :param parsed_args: argparse namespace from our local options
+
         """
 
 
@@ -43,6 +50,12 @@
     def emit_one(self, column_names, data, stdout, parsed_args):
         """Format and print the values associated with the single object.
 
+        Data values can be primitive types like ints and strings, or
+        can be an instance of a :class:`FormattableColumn` for
+        situations where the value is complex, and may need to be
+        handled differently for human readable output vs. machine
+        readable output.
+
         :param column_names: names of the columns
         :param data: iterable data source with values in order of column names
         :param stdout: output stream where data should be written
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/formatters/commaseparated.py 
new/cliff-2.2.0/cliff/formatters/commaseparated.py
--- old/cliff-2.1.0/cliff/formatters/commaseparated.py  2016-06-16 
15:19:52.000000000 +0200
+++ new/cliff-2.2.0/cliff/formatters/commaseparated.py  2016-08-15 
21:19:43.000000000 +0200
@@ -5,6 +5,9 @@
 import sys
 
 from .base import ListFormatter
+from cliff import columns
+
+import six
 
 if sys.version_info[0] == 3:
     import csv
@@ -35,8 +38,14 @@
         writer = csv.writer(stdout,
                             quoting=self.QUOTE_MODES[parsed_args.quote_mode],
                             lineterminator=os.linesep,
+                            escapechar='\\',
                             )
         writer.writerow(column_names)
         for row in data:
-            writer.writerow(row)
+            writer.writerow(
+                [(six.text_type(c.machine_readable())
+                  if isinstance(c, columns.FormattableColumn)
+                  else c)
+                 for c in row]
+            )
         return
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/formatters/json_format.py 
new/cliff-2.2.0/cliff/formatters/json_format.py
--- old/cliff-2.1.0/cliff/formatters/json_format.py     2016-06-16 
15:19:52.000000000 +0200
+++ new/cliff-2.2.0/cliff/formatters/json_format.py     2016-08-15 
21:19:43.000000000 +0200
@@ -4,6 +4,7 @@
 import json
 
 from .base import ListFormatter, SingleFormatter
+from cliff import columns
 
 
 class JSONFormatter(ListFormatter, SingleFormatter):
@@ -20,11 +21,21 @@
     def emit_list(self, column_names, data, stdout, parsed_args):
         items = []
         for item in data:
-            items.append(dict(zip(column_names, item)))
+            items.append(
+                {n: (i.machine_readable()
+                     if isinstance(i, columns.FormattableColumn)
+                     else i)
+                 for n, i in zip(column_names, item)}
+            )
         indent = None if parsed_args.noindent else 2
         json.dump(items, stdout, indent=indent)
 
     def emit_one(self, column_names, data, stdout, parsed_args):
-        one = dict(zip(column_names, data))
+        one = {
+            n: (i.machine_readable()
+                if isinstance(i, columns.FormattableColumn)
+                else i)
+            for n, i in zip(column_names, data)
+        }
         indent = None if parsed_args.noindent else 2
         json.dump(one, stdout, indent=indent)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/formatters/shell.py 
new/cliff-2.2.0/cliff/formatters/shell.py
--- old/cliff-2.1.0/cliff/formatters/shell.py   2016-06-16 15:19:52.000000000 
+0200
+++ new/cliff-2.2.0/cliff/formatters/shell.py   2016-08-15 21:19:43.000000000 
+0200
@@ -2,6 +2,7 @@
 """
 
 from .base import SingleFormatter
+from cliff import columns
 
 import argparse
 import six
@@ -37,6 +38,9 @@
         desired_columns = parsed_args.variables
         for name, value in zip(variable_names, data):
             if name in desired_columns or not desired_columns:
+                value = (six.text_type(value.machine_readable())
+                         if isinstance(value, columns.FormattableColumn)
+                         else value)
                 if isinstance(value, six.string_types):
                     value = value.replace('"', '\\"')
                 stdout.write('%s%s="%s"\n' % (parsed_args.prefix, name, value))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/formatters/table.py 
new/cliff-2.2.0/cliff/formatters/table.py
--- old/cliff-2.1.0/cliff/formatters/table.py   2016-06-16 15:19:52.000000000 
+0200
+++ new/cliff-2.2.0/cliff/formatters/table.py   2016-08-15 21:19:43.000000000 
+0200
@@ -7,6 +7,18 @@
 
 from cliff import utils
 from .base import ListFormatter, SingleFormatter
+from cliff import columns
+
+
+def _format_row(row):
+    new_row = []
+    for r in row:
+        if isinstance(r, columns.FormattableColumn):
+            r = r.human_readable()
+        if isinstance(r, six.string_types):
+            r = r.replace('\r\n', '\n').replace('\r', ' ')
+        new_row.append(r)
+    return new_row
 
 
 class TableFormatter(ListFormatter, SingleFormatter):
@@ -52,12 +64,9 @@
                 alignment = self.ALIGNMENTS.get(type(value), 'l')
                 x.align[name] = alignment
             # Now iterate over the data and add the rows.
-            x.add_row(first_row)
+            x.add_row(_format_row(first_row))
             for row in data_iter:
-                row = [r.replace('\r\n', '\n').replace('\r', ' ')
-                       if isinstance(r, six.string_types) else r
-                       for r in row]
-                x.add_row(row)
+                x.add_row(_format_row(row))
 
         # Choose a reasonable min_width to better handle many columns on a
         # narrow console. The table will overflow the console width in
@@ -80,9 +89,7 @@
         x.align['Field'] = 'l'
         x.align['Value'] = 'l'
         for name, value in zip(column_names, data):
-            value = (value.replace('\r\n', '\n').replace('\r', ' ') if
-                     isinstance(value, six.string_types) else value)
-            x.add_row((name, value))
+            x.add_row(_format_row((name, value)))
 
         # Choose a reasonable min_width to better handle a narrow
         # console. The table will overflow the console width in preference
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/formatters/value.py 
new/cliff-2.2.0/cliff/formatters/value.py
--- old/cliff-2.1.0/cliff/formatters/value.py   2016-06-16 15:19:52.000000000 
+0200
+++ new/cliff-2.2.0/cliff/formatters/value.py   2016-08-15 21:19:43.000000000 
+0200
@@ -5,6 +5,7 @@
 
 from .base import ListFormatter
 from .base import SingleFormatter
+from cliff import columns
 
 
 class ValueFormatter(ListFormatter, SingleFormatter):
@@ -14,10 +15,19 @@
 
     def emit_list(self, column_names, data, stdout, parsed_args):
         for row in data:
-            stdout.write(' '.join(map(six.text_type, row)) + u'\n')
+            stdout.write(
+                ' '.join(
+                    six.text_type(c.machine_readable()
+                                  if isinstance(c, columns.FormattableColumn)
+                                  else c)
+                    for c in row) + u'\n')
         return
 
     def emit_one(self, column_names, data, stdout, parsed_args):
         for value in data:
-            stdout.write('%s\n' % str(value))
+            stdout.write('%s\n' % six.text_type(
+                value.machine_readable()
+                if isinstance(value, columns.FormattableColumn)
+                else value)
+            )
         return
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/formatters/yaml_format.py 
new/cliff-2.2.0/cliff/formatters/yaml_format.py
--- old/cliff-2.1.0/cliff/formatters/yaml_format.py     2016-06-16 
15:19:52.000000000 +0200
+++ new/cliff-2.2.0/cliff/formatters/yaml_format.py     2016-08-15 
21:19:43.000000000 +0200
@@ -4,6 +4,7 @@
 import yaml
 
 from .base import ListFormatter, SingleFormatter
+from cliff import columns
 
 
 class YAMLFormatter(ListFormatter, SingleFormatter):
@@ -14,10 +15,19 @@
     def emit_list(self, column_names, data, stdout, parsed_args):
         items = []
         for item in data:
-            items.append(dict(zip(column_names, item)))
+            items.append(
+                {n: (i.machine_readable()
+                     if isinstance(i, columns.FormattableColumn)
+                     else i)
+                 for n, i in zip(column_names, item)}
+            )
         yaml.safe_dump(items, stream=stdout, default_flow_style=False)
 
     def emit_one(self, column_names, data, stdout, parsed_args):
         for key, value in zip(column_names, data):
-            dict_data = {key: value}
+            dict_data = {
+                key: (value.machine_readable()
+                      if isinstance(value, columns.FormattableColumn)
+                      else value)
+            }
             yaml.safe_dump(dict_data, stream=stdout, default_flow_style=False)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/tests/test_app.py 
new/cliff-2.2.0/cliff/tests/test_app.py
--- old/cliff-2.1.0/cliff/tests/test_app.py     2016-06-16 15:19:52.000000000 
+0200
+++ new/cliff-2.2.0/cliff/tests/test_app.py     2016-08-15 21:19:43.000000000 
+0200
@@ -5,7 +5,11 @@
 except ImportError:
     from io import StringIO
 
+import codecs
+import locale
 import mock
+import six
+import sys
 
 from cliff.app import App
 from cliff.command import Command
@@ -398,3 +402,82 @@
         pass
     else:
         raise Exception('Exception was not thrown')
+
+
+def test_io_streams():
+    cmd_mgr = CommandManager('cliff.tests')
+    io = mock.Mock()
+
+    if six.PY2:
+        stdin_save = sys.stdin
+        stdout_save = sys.stdout
+        stderr_save = sys.stderr
+        encoding = locale.getpreferredencoding() or 'utf-8'
+
+        app = App('no io streams', 1, cmd_mgr)
+        assert isinstance(app.stdin, codecs.StreamReader)
+        assert isinstance(app.stdout, codecs.StreamWriter)
+        assert isinstance(app.stderr, codecs.StreamWriter)
+
+        app = App('with stdin io stream', 1, cmd_mgr, stdin=io)
+        assert app.stdin is io
+        assert isinstance(app.stdout, codecs.StreamWriter)
+        assert isinstance(app.stderr, codecs.StreamWriter)
+
+        app = App('with stdout io stream', 1, cmd_mgr, stdout=io)
+        assert isinstance(app.stdin, codecs.StreamReader)
+        assert app.stdout is io
+        assert isinstance(app.stderr, codecs.StreamWriter)
+
+        app = App('with stderr io stream', 1, cmd_mgr, stderr=io)
+        assert isinstance(app.stdin, codecs.StreamReader)
+        assert isinstance(app.stdout, codecs.StreamWriter)
+        assert app.stderr is io
+
+        try:
+            sys.stdin = codecs.getreader(encoding)(sys.stdin)
+            app = App('with wrapped sys.stdin io stream', 1, cmd_mgr)
+            assert app.stdin is sys.stdin
+            assert isinstance(app.stdout, codecs.StreamWriter)
+            assert isinstance(app.stderr, codecs.StreamWriter)
+        finally:
+            sys.stdin = stdin_save
+
+        try:
+            sys.stdout = codecs.getwriter(encoding)(sys.stdout)
+            app = App('with wrapped stdout io stream', 1, cmd_mgr)
+            assert isinstance(app.stdin, codecs.StreamReader)
+            assert app.stdout is sys.stdout
+            assert isinstance(app.stderr, codecs.StreamWriter)
+        finally:
+            sys.stdout = stdout_save
+
+        try:
+            sys.stderr = codecs.getwriter(encoding)(sys.stderr)
+            app = App('with wrapped stderr io stream', 1, cmd_mgr)
+            assert isinstance(app.stdin, codecs.StreamReader)
+            assert isinstance(app.stdout, codecs.StreamWriter)
+            assert app.stderr is sys.stderr
+        finally:
+            sys.stderr = stderr_save
+
+    else:
+        app = App('no io streams', 1, cmd_mgr)
+        assert app.stdin is sys.stdin
+        assert app.stdout is sys.stdout
+        assert app.stderr is sys.stderr
+
+        app = App('with stdin io stream', 1, cmd_mgr, stdin=io)
+        assert app.stdin is io
+        assert app.stdout is sys.stdout
+        assert app.stderr is sys.stderr
+
+        app = App('with stdout io stream', 1, cmd_mgr, stdout=io)
+        assert app.stdin is sys.stdin
+        assert app.stdout is io
+        assert app.stderr is sys.stderr
+
+        app = App('with stderr io stream', 1, cmd_mgr, stderr=io)
+        assert app.stdin is sys.stdin
+        assert app.stdout is sys.stdout
+        assert app.stderr is io
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/tests/test_columns.py 
new/cliff-2.2.0/cliff/tests/test_columns.py
--- old/cliff-2.1.0/cliff/tests/test_columns.py 1970-01-01 01:00:00.000000000 
+0100
+++ new/cliff-2.2.0/cliff/tests/test_columns.py 2016-08-15 21:19:43.000000000 
+0200
@@ -0,0 +1,18 @@
+from cliff import columns
+
+
+class FauxColumn(columns.FormattableColumn):
+
+    def human_readable(self):
+        return u'I made this string myself: {}'.format(self._value)
+
+
+def test_faux_column_machine():
+    c = FauxColumn(['list', 'of', 'values'])
+    assert c.machine_readable() == ['list', 'of', 'values']
+
+
+def test_faux_column_human():
+    c = FauxColumn(['list', 'of', 'values'])
+    assert c.human_readable() == \
+        u"I made this string myself: ['list', 'of', 'values']"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/tests/test_command.py 
new/cliff-2.2.0/cliff/tests/test_command.py
--- old/cliff-2.1.0/cliff/tests/test_command.py 2016-06-16 15:19:52.000000000 
+0200
+++ new/cliff-2.2.0/cliff/tests/test_command.py 2016-08-15 21:19:43.000000000 
+0200
@@ -7,7 +7,7 @@
     """
 
     def take_action(self, parsed_args):
-        return
+        return 42
 
 
 def test_get_description():
@@ -25,3 +25,8 @@
 def test_get_name():
     cmd = TestCommand(None, None, cmd_name='object action')
     assert cmd.cmd_name == 'object action'
+
+
+def test_run_return():
+    cmd = TestCommand(None, None, cmd_name='object action')
+    assert cmd.run(None) == 42
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/tests/test_formatters_csv.py 
new/cliff-2.2.0/cliff/tests/test_formatters_csv.py
--- old/cliff-2.1.0/cliff/tests/test_formatters_csv.py  2016-06-16 
15:19:53.000000000 +0200
+++ new/cliff-2.2.0/cliff/tests/test_formatters_csv.py  2016-08-15 
21:19:43.000000000 +0200
@@ -6,6 +6,7 @@
 import six
 
 from cliff.formatters import commaseparated
+from cliff.tests import test_columns
 
 
 def test_commaseparated_list_formatter():
@@ -38,6 +39,20 @@
     sf.emit_list(c, data, output, parsed_args)
     actual = output.getvalue()
     assert expected == actual
+
+
+def test_commaseparated_list_formatter_formattable_column():
+    sf = commaseparated.CSVLister()
+    c = ('a', 'b', 'c')
+    d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
+    data = [d1]
+    expected = 'a,b,c\nA,B,[\'the\'\\, \'value\']\n'
+    output = six.StringIO()
+    parsed_args = mock.Mock()
+    parsed_args.quote_mode = 'none'
+    sf.emit_list(c, data, output, parsed_args)
+    actual = output.getvalue()
+    assert expected == actual
 
 
 def test_commaseparated_list_formatter_unicode():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/tests/test_formatters_json.py 
new/cliff-2.2.0/cliff/tests/test_formatters_json.py
--- old/cliff-2.1.0/cliff/tests/test_formatters_json.py 2016-06-16 
15:19:52.000000000 +0200
+++ new/cliff-2.2.0/cliff/tests/test_formatters_json.py 2016-08-15 
21:19:43.000000000 +0200
@@ -3,6 +3,7 @@
 import json
 
 from cliff.formatters import json_format
+from cliff.tests import test_columns
 
 import mock
 
@@ -38,6 +39,29 @@
     assert expected == actual
 
 
+def test_json_format_formattablecolumn_one():
+    sf = json_format.JSONFormatter()
+    c = ('a', 'b', 'c', 'd')
+    d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
+    expected = {
+        'a': 'A',
+        'b': 'B',
+        'c': 'C',
+        'd': ['the', 'value'],
+    }
+    args = mock.Mock()
+    sf.add_argument_group(args)
+
+    args.noindent = True
+    output = StringIO()
+    sf.emit_one(c, d, output, args)
+    value = output.getvalue()
+    print(len(value.splitlines()))
+    assert 1 == len(value.splitlines())
+    actual = json.loads(value)
+    assert expected == actual
+
+
 def test_json_format_list():
     sf = json_format.JSONFormatter()
     c = ('a', 'b', 'c')
@@ -69,3 +93,24 @@
     assert 17 == len(value.splitlines())
     actual = json.loads(value)
     assert expected == actual
+
+
+def test_json_format_formattablecolumn_list():
+    sf = json_format.JSONFormatter()
+    c = ('a', 'b', 'c')
+    d = (
+        ('A1', 'B1', test_columns.FauxColumn(['the', 'value'])),
+    )
+    expected = [
+        {'a': 'A1', 'b': 'B1', 'c': ['the', 'value']},
+    ]
+    args = mock.Mock()
+    sf.add_argument_group(args)
+
+    args.noindent = True
+    output = StringIO()
+    sf.emit_list(c, d, output, args)
+    value = output.getvalue()
+    assert 1 == len(value.splitlines())
+    actual = json.loads(value)
+    assert expected == actual
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/tests/test_formatters_shell.py 
new/cliff-2.2.0/cliff/tests/test_formatters_shell.py
--- old/cliff-2.1.0/cliff/tests/test_formatters_shell.py        2016-06-16 
15:19:53.000000000 +0200
+++ new/cliff-2.2.0/cliff/tests/test_formatters_shell.py        2016-08-15 
21:19:43.000000000 +0200
@@ -5,6 +5,7 @@
 from six import StringIO, text_type
 
 from cliff.formatters import shell
+from cliff.tests import test_columns
 
 import mock
 
@@ -37,6 +38,24 @@
     actual = output.getvalue()
     assert expected == actual
 
+
+def test_shell_formatter_formattable_column():
+    sf = shell.ShellFormatter()
+    c = ('a', 'b', 'c')
+    d = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
+    expected = '\n'.join([
+        'a="A"',
+        'b="B"',
+        'c="[\'the\', \'value\']"\n',
+    ])
+    output = StringIO()
+    args = mock.Mock()
+    args.variables = ['a', 'b', 'c']
+    args.prefix = ''
+    sf.emit_one(c, d, output, args)
+    actual = output.getvalue()
+    assert expected == actual
+
 
 def test_shell_formatter_with_non_string_values():
     sf = shell.ShellFormatter()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/tests/test_formatters_table.py 
new/cliff-2.2.0/cliff/tests/test_formatters_table.py
--- old/cliff-2.1.0/cliff/tests/test_formatters_table.py        2016-06-16 
15:19:52.000000000 +0200
+++ new/cliff-2.2.0/cliff/tests/test_formatters_table.py        2016-08-15 
21:19:43.000000000 +0200
@@ -6,6 +6,7 @@
 import argparse
 
 from cliff.formatters import table
+from cliff.tests import test_columns
 
 
 class args(object):
@@ -65,7 +66,7 @@
 '''
     assert expected == _table_tester_helper(c, d)
 
-
+# Multi-line output when width is restricted to 42 columns
 expected_ml_val = '''\
 +-------+--------------------------------+
 | Field | Value                          |
@@ -79,6 +80,39 @@
 +-------+--------------------------------+
 '''
 
+# Multi-line output when width is restricted to 80 columns
+expected_ml_80_val = '''\
++-------+----------------------------------------------------------------------+
+| Field | Value                                                                
|
++-------+----------------------------------------------------------------------+
+| a     | A                                                                    
|
+| b     | B                                                                    
|
+| c     | C                                                                    
|
+| d     | dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd 
|
+|       | ddddddddd                                                            
|
++-------+----------------------------------------------------------------------+
+'''  # noqa
+
+# Single-line output, for when no line length restriction apply
+expected_sl_val = '''\
++-------+-------------------------------------------------------------------------------+
+| Field | Value                                                                
         |
++-------+-------------------------------------------------------------------------------+
+| a     | A                                                                    
         |
+| b     | B                                                                    
         |
+| c     | C                                                                    
         |
+| d     | 
ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd |
++-------+-------------------------------------------------------------------------------+
+'''  # noqa
+
+
[email protected]('cliff.utils.terminal_width')
+def test_table_formatter_no_cli_param(tw):
+    tw.return_value = 80
+    c = ('a', 'b', 'c', 'd')
+    d = ('A', 'B', 'C', 'd' * 77)
+    assert expected_ml_80_val == _table_tester_helper(c, d, extra_args=args())
+
 
 @mock.patch('cliff.utils.terminal_width')
 def test_table_formatter_cli_param(tw):
@@ -90,6 +124,24 @@
 
 
 @mock.patch('cliff.utils.terminal_width')
+def test_table_formatter_no_cli_param_unlimited_tw(tw):
+    tw.return_value = 0
+    c = ('a', 'b', 'c', 'd')
+    d = ('A', 'B', 'C', 'd' * 77)
+    # output should not be wrapped to multiple lines
+    assert expected_sl_val == _table_tester_helper(c, d, extra_args=args())
+
+
[email protected]('cliff.utils.terminal_width')
+def test_table_formatter_cli_param_unlimited_tw(tw):
+    tw.return_value = 0
+    c = ('a', 'b', 'c', 'd')
+    d = ('A', 'B', 'C', 'd' * 77)
+    assert (expected_ml_val ==
+            _table_tester_helper(c, d, extra_args=['--max-width', '42']))
+
+
[email protected]('cliff.utils.terminal_width')
 @mock.patch.dict(os.environ, {'CLIFF_MAX_TERM_WIDTH': '666'})
 def test_table_formatter_cli_param_envvar_big(tw):
     tw.return_value = 80
@@ -185,6 +237,24 @@
     assert expected == _table_tester_helper(c, data)
 
 
[email protected]('cliff.utils.terminal_width')
+def test_table_formatter_formattable_column(tw):
+    tw.return_value = 0
+    c = ('a', 'b', 'c', 'd')
+    d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
+    expected = '''\
++-------+---------------------------------------------+
+| Field | Value                                       |
++-------+---------------------------------------------+
+| a     | A                                           |
+| b     | B                                           |
+| c     | C                                           |
+| d     | I made this string myself: ['the', 'value'] |
++-------+---------------------------------------------+
+'''
+    assert expected == _table_tester_helper(c, d)
+
+
 _col_names = ('one', 'two', 'three')
 _col_data = [(
     'one one one one one',
@@ -250,6 +320,22 @@
 
 
 @mock.patch('cliff.utils.terminal_width')
+def test_table_list_formatter_formattable_column(tw):
+    tw.return_value = 80
+    c = ('a', 'b', 'c')
+    d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
+    data = [d1]
+    expected = '''\
++---+---+---------------------------------------------+
+| a | b | c                                           |
++---+---+---------------------------------------------+
+| A | B | I made this string myself: ['the', 'value'] |
++---+---+---------------------------------------------+
+'''
+    assert expected == _table_tester_helper(c, data)
+
+
[email protected]('cliff.utils.terminal_width')
 def test_table_list_formatter_max_width(tw):
     # no resize
     l = tw.return_value = 80
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/tests/test_formatters_value.py 
new/cliff-2.2.0/cliff/tests/test_formatters_value.py
--- old/cliff-2.1.0/cliff/tests/test_formatters_value.py        2016-06-16 
15:19:52.000000000 +0200
+++ new/cliff-2.2.0/cliff/tests/test_formatters_value.py        2016-08-15 
21:19:43.000000000 +0200
@@ -2,6 +2,7 @@
 from six import StringIO
 
 from cliff.formatters import value
+from cliff.tests import test_columns
 
 
 def test_value_formatter():
@@ -15,6 +16,17 @@
     assert expected == actual
 
 
+def test_value_formatter_formattable_column():
+    sf = value.ValueFormatter()
+    c = ('a', 'b', 'c', 'd')
+    d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
+    expected = "A\nB\nC\n['the', 'value']\n"
+    output = StringIO()
+    sf.emit_one(c, d, output, None)
+    actual = output.getvalue()
+    assert expected == actual
+
+
 def test_value_list_formatter():
     sf = value.ValueFormatter()
     c = ('a', 'b', 'c')
@@ -25,4 +37,16 @@
     output = StringIO()
     sf.emit_list(c, data, output, None)
     actual = output.getvalue()
+    assert expected == actual
+
+
+def test_value_list_formatter_formattable_column():
+    sf = value.ValueFormatter()
+    c = ('a', 'b', 'c')
+    d1 = ('A', 'B', test_columns.FauxColumn(['the', 'value']))
+    data = [d1]
+    expected = "A B ['the', 'value']\n"
+    output = StringIO()
+    sf.emit_list(c, data, output, None)
+    actual = output.getvalue()
     assert expected == actual
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff/tests/test_formatters_yaml.py 
new/cliff-2.2.0/cliff/tests/test_formatters_yaml.py
--- old/cliff-2.1.0/cliff/tests/test_formatters_yaml.py 2016-06-16 
15:19:52.000000000 +0200
+++ new/cliff-2.2.0/cliff/tests/test_formatters_yaml.py 2016-08-15 
21:19:43.000000000 +0200
@@ -3,6 +3,7 @@
 import yaml
 
 from cliff.formatters import yaml_format
+from cliff.tests import test_columns
 
 import mock
 
@@ -24,6 +25,28 @@
     assert expected == actual
 
 
+def test_yaml_format_formattablecolumn_one():
+    sf = yaml_format.YAMLFormatter()
+    c = ('a', 'b', 'c', 'd')
+    d = ('A', 'B', 'C', test_columns.FauxColumn(['the', 'value']))
+    expected = {
+        'a': 'A',
+        'b': 'B',
+        'c': 'C',
+        'd': ['the', 'value'],
+    }
+    args = mock.Mock()
+    sf.add_argument_group(args)
+
+    args.noindent = True
+    output = StringIO()
+    sf.emit_one(c, d, output, args)
+    value = output.getvalue()
+    print(len(value.splitlines()))
+    actual = yaml.safe_load(output.getvalue())
+    assert expected == actual
+
+
 def test_yaml_format_list():
     sf = yaml_format.YAMLFormatter()
     c = ('a', 'b', 'c')
@@ -43,3 +66,22 @@
     sf.emit_list(c, d, output, args)
     actual = yaml.safe_load(output.getvalue())
     assert expected == actual
+
+
+def test_yaml_format_formattablecolumn_list():
+    sf = yaml_format.YAMLFormatter()
+    c = ('a', 'b', 'c')
+    d = (
+        ('A1', 'B1', test_columns.FauxColumn(['the', 'value'])),
+    )
+    expected = [
+        {'a': 'A1', 'b': 'B1', 'c': ['the', 'value']},
+    ]
+    args = mock.Mock()
+    sf.add_argument_group(args)
+
+    args.noindent = True
+    output = StringIO()
+    sf.emit_list(c, d, output, args)
+    actual = yaml.safe_load(output.getvalue())
+    assert expected == actual
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff.egg-info/PKG-INFO 
new/cliff-2.2.0/cliff.egg-info/PKG-INFO
--- old/cliff-2.1.0/cliff.egg-info/PKG-INFO     2016-06-16 15:21:48.000000000 
+0200
+++ new/cliff-2.2.0/cliff.egg-info/PKG-INFO     2016-08-15 21:21:08.000000000 
+0200
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: cliff
-Version: 2.1.0
+Version: 2.2.0
 Summary: Command Line Interface Formulation Framework
 Home-page: https://launchpad.net/python-cliff
 Author: OpenStack
@@ -14,7 +14,7 @@
         `setuptools entry points`_ to provide subcommands, output formatters, 
and
         other extensions.
         
-        .. _setuptools entry points: 
http://pythonhosted.org/setuptools/pkg_resources.html#convenience-api
+        .. _setuptools entry points: 
http://setuptools.readthedocs.io/en/latest/pkg_resources.html#convenience-api
         
         * Free software: Apache license
         * Documentation: http://docs.openstack.org/developer/cliff
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff.egg-info/SOURCES.txt 
new/cliff-2.2.0/cliff.egg-info/SOURCES.txt
--- old/cliff-2.1.0/cliff.egg-info/SOURCES.txt  2016-06-16 15:21:48.000000000 
+0200
+++ new/cliff-2.2.0/cliff.egg-info/SOURCES.txt  2016-08-15 21:21:09.000000000 
+0200
@@ -6,7 +6,6 @@
 MANIFEST.in
 Makefile
 README.rst
-announce.rst
 openstack-common.conf
 requirements.txt
 setup.cfg
@@ -16,6 +15,7 @@
 cliff/__init__.py
 cliff/app.py
 cliff/argparse.py
+cliff/columns.py
 cliff/command.py
 cliff/commandmanager.py
 cliff/complete.py
@@ -43,6 +43,7 @@
 cliff/formatters/yaml_format.py
 cliff/tests/__init__.py
 cliff/tests/test_app.py
+cliff/tests/test_columns.py
 cliff/tests/test_command.py
 cliff/tests/test_commandmanager.py
 cliff/tests/test_complete.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff.egg-info/pbr.json 
new/cliff-2.2.0/cliff.egg-info/pbr.json
--- old/cliff-2.1.0/cliff.egg-info/pbr.json     2016-06-16 15:21:48.000000000 
+0200
+++ new/cliff-2.2.0/cliff.egg-info/pbr.json     2016-08-15 21:21:08.000000000 
+0200
@@ -1 +1 @@
-{"is_release": true, "git_version": "21f133f"}
\ No newline at end of file
+{"is_release": true, "git_version": "50d6708"}
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/cliff.egg-info/requires.txt 
new/cliff-2.2.0/cliff.egg-info/requires.txt
--- old/cliff-2.1.0/cliff.egg-info/requires.txt 2016-06-16 15:21:48.000000000 
+0200
+++ new/cliff-2.2.0/cliff.egg-info/requires.txt 2016-08-15 21:21:08.000000000 
+0200
@@ -3,6 +3,6 @@
 PrettyTable<0.8,>=0.7
 pyparsing>=2.0.1
 six>=1.9.0
-stevedore>=1.10.0
+stevedore>=1.16.0
 unicodecsv>=0.8.0
 PyYAML>=3.1.0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/demoapp/setup.py 
new/cliff-2.2.0/demoapp/setup.py
--- old/cliff-2.1.0/demoapp/setup.py    2016-06-16 15:19:52.000000000 +0200
+++ new/cliff-2.2.0/demoapp/setup.py    2016-08-15 21:19:43.000000000 +0200
@@ -22,8 +22,8 @@
     author='Doug Hellmann',
     author_email='[email protected]',
 
-    url='https://github.com/dreamhost/cliff',
-    download_url='https://github.com/dreamhost/cliff/tarball/master',
+    url='https://github.com/openstack/cliff',
+    download_url='https://github.com/openstack/cliff/tarball/master',
 
     classifiers=['Development Status :: 3 - Alpha',
                  'License :: OSI Approved :: Apache Software License',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/doc/source/install.rst 
new/cliff-2.2.0/doc/source/install.rst
--- old/cliff-2.1.0/doc/source/install.rst      2016-06-16 15:19:52.000000000 
+0200
+++ new/cliff-2.2.0/doc/source/install.rst      2016-08-15 21:19:43.000000000 
+0200
@@ -42,10 +42,10 @@
 Source Code
 ===========
 
-The source is hosted on github: https://github.com/dreamhost/cliff
+The source is hosted on github: http://git.openstack.org/cgit/openstack/cliff
 
 Reporting Bugs
 ==============
 
 Please report bugs through the github project:
-https://github.com/dreamhost/cliff/issues
+https://bugs.launchpad.net/python-cliff
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/requirements.txt 
new/cliff-2.2.0/requirements.txt
--- old/cliff-2.1.0/requirements.txt    2016-06-16 15:19:52.000000000 +0200
+++ new/cliff-2.2.0/requirements.txt    2016-08-15 21:19:43.000000000 +0200
@@ -6,6 +6,6 @@
 PrettyTable<0.8,>=0.7 # BSD
 pyparsing>=2.0.1 # MIT
 six>=1.9.0 # MIT
-stevedore>=1.10.0 # Apache-2.0
+stevedore>=1.16.0 # Apache-2.0
 unicodecsv>=0.8.0;python_version<'3.0' # BSD
 PyYAML>=3.1.0 # MIT
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cliff-2.1.0/test-requirements.txt 
new/cliff-2.2.0/test-requirements.txt
--- old/cliff-2.1.0/test-requirements.txt       2016-06-16 15:19:52.000000000 
+0200
+++ new/cliff-2.2.0/test-requirements.txt       2016-08-15 21:19:43.000000000 
+0200
@@ -5,5 +5,5 @@
 mock>=2.0 # BSD
 coverage>=3.6 # Apache-2.0
 # this is required for the docs build jobs
-sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
+sphinx!=1.3b1,<1.3,>=1.2.1 # BSD
 oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0

++++++ relax-sphinx-requirement.patch ++++++
--- /var/tmp/diff_new_pack.6GtgcB/_old  2016-10-04 16:00:36.000000000 +0200
+++ /var/tmp/diff_new_pack.6GtgcB/_new  2016-10-04 16:00:36.000000000 +0200
@@ -6,6 +6,6 @@
  mock>=2.0 # BSD
  coverage>=3.6 # Apache-2.0
  # this is required for the docs build jobs
--sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2 # BSD
+-sphinx!=1.3b1,<1.3,>=1.2.1 # BSD
 +sphinx
  oslosphinx!=3.4.0,>=2.5.0 # Apache-2.0


Reply via email to