Revision 153533f3 lib/utils.py
b/lib/utils.py | ||
---|---|---|
109 | 109 |
#: ASN1 time regexp |
110 | 110 |
_ASN1_TIME_REGEX = re.compile(r"^(\d+)([-+]\d\d)(\d\d)$") |
111 | 111 |
|
112 |
_SORTER_RE = re.compile("^%s(.*)$" % (8 * "(\D+|\d+)?")) |
|
113 |
_SORTER_DIGIT = re.compile("^\d+$") |
|
114 |
|
|
112 | 115 |
|
113 | 116 |
class RunResult(object): |
114 | 117 |
"""Holds the result of running external programs. |
... | ... | |
1279 | 1282 |
return os.path.isdir("/sys/class/net/%s/bridge" % bridge) |
1280 | 1283 |
|
1281 | 1284 |
|
1282 |
def NiceSort(name_list): |
|
1285 |
def _NiceSortTryInt(val): |
|
1286 |
"""Attempts to convert a string to an integer. |
|
1287 |
|
|
1288 |
""" |
|
1289 |
if val and _SORTER_DIGIT.match(val): |
|
1290 |
return int(val) |
|
1291 |
else: |
|
1292 |
return val |
|
1293 |
|
|
1294 |
|
|
1295 |
def _NiceSortKey(value): |
|
1296 |
"""Extract key for sorting. |
|
1297 |
|
|
1298 |
""" |
|
1299 |
return [_NiceSortTryInt(grp) |
|
1300 |
for grp in _SORTER_RE.match(value).groups()] |
|
1301 |
|
|
1302 |
|
|
1303 |
def NiceSort(values, key=None): |
|
1283 | 1304 |
"""Sort a list of strings based on digit and non-digit groupings. |
1284 | 1305 |
|
1285 | 1306 |
Given a list of names C{['a1', 'a10', 'a11', 'a2']} this function |
... | ... | |
1290 | 1311 |
or no-digits. Only the first eight such groups are considered, and |
1291 | 1312 |
after that we just use what's left of the string. |
1292 | 1313 |
|
1293 |
@type name_list: list |
|
1294 |
@param name_list: the names to be sorted |
|
1314 |
@type values: list |
|
1315 |
@param values: the names to be sorted |
|
1316 |
@type key: callable or None |
|
1317 |
@param key: function of one argument to extract a comparison key from each |
|
1318 |
list element, must return string |
|
1295 | 1319 |
@rtype: list |
1296 | 1320 |
@return: a copy of the name list sorted with our algorithm |
1297 | 1321 |
|
1298 | 1322 |
""" |
1299 |
_SORTER_BASE = "(\D+|\d+)" |
|
1300 |
_SORTER_FULL = "^%s%s?%s?%s?%s?%s?%s?%s?.*$" % (_SORTER_BASE, _SORTER_BASE, |
|
1301 |
_SORTER_BASE, _SORTER_BASE, |
|
1302 |
_SORTER_BASE, _SORTER_BASE, |
|
1303 |
_SORTER_BASE, _SORTER_BASE) |
|
1304 |
_SORTER_RE = re.compile(_SORTER_FULL) |
|
1305 |
_SORTER_NODIGIT = re.compile("^\D*$") |
|
1306 |
def _TryInt(val): |
|
1307 |
"""Attempts to convert a variable to integer.""" |
|
1308 |
if val is None or _SORTER_NODIGIT.match(val): |
|
1309 |
return val |
|
1310 |
rval = int(val) |
|
1311 |
return rval |
|
1312 |
|
|
1313 |
to_sort = [([_TryInt(grp) for grp in _SORTER_RE.match(name).groups()], name) |
|
1314 |
for name in name_list] |
|
1315 |
to_sort.sort() |
|
1316 |
return [tup[1] for tup in to_sort] |
|
1323 |
if key is None: |
|
1324 |
keyfunc = _NiceSortKey |
|
1325 |
else: |
|
1326 |
keyfunc = lambda value: _NiceSortKey(key(value)) |
|
1327 |
|
|
1328 |
return sorted(values, key=keyfunc) |
|
1317 | 1329 |
|
1318 | 1330 |
|
1319 | 1331 |
def TryConvert(fn, val): |
Also available in: Unified diff