summaryrefslogtreecommitdiff
path: root/cliff/lister.py
diff options
context:
space:
mode:
Diffstat (limited to 'cliff/lister.py')
-rw-r--r--cliff/lister.py25
1 files changed, 22 insertions, 3 deletions
diff --git a/cliff/lister.py b/cliff/lister.py
index cfba233..dde0f2d 100644
--- a/cliff/lister.py
+++ b/cliff/lister.py
@@ -13,7 +13,7 @@
"""Application base class for providing a list of data as output.
"""
import abc
-import operator
+import logging
from . import display
@@ -22,6 +22,8 @@ class Lister(display.DisplayCommandBase, metaclass=abc.ABCMeta):
"""Command base class for providing a list of data as output.
"""
+ log = logging.getLogger(__name__)
+
@property
def formatter_namespace(self):
return 'cliff.formatter.list'
@@ -63,8 +65,25 @@ class Lister(display.DisplayCommandBase, metaclass=abc.ABCMeta):
if parsed_args.sort_columns and self.need_sort_by_cliff:
indexes = [column_names.index(c) for c in parsed_args.sort_columns
if c in column_names]
- if indexes:
- data = sorted(data, key=operator.itemgetter(*indexes))
+ for index in indexes[::-1]:
+ try:
+ # We need to handle unset values (i.e. None) so we sort on
+ # multiple conditions: the first comparing the results of
+ # an 'is None' type check and the second comparing the
+ # actual value. The second condition will only be checked
+ # if the first returns True, which only happens if the
+ # returns from the 'is None' check on the two values are
+ # the same, i.e. both None or both not-None
+ data = sorted(
+ data, key=lambda k: (k[index] is None, k[index]),
+ )
+ except TypeError:
+ # Simply log and then ignore this; sorting is best effort
+ self.log.warning(
+ "Could not sort on field '%s'; unsortable types",
+ parsed_args.sort_columns[index],
+ )
+
(columns_to_include, selector) = self._generate_columns_and_selector(
parsed_args, column_names)
if selector: