"""Support files for podman API implementation.""" from __future__ import absolute_import import collections import datetime import functools from dateutil.parser import parse as dateutil_parse __all__ = [ 'cached_property', 'datetime_format', 'datetime_parse', 'flatten', 'fold_keys', ] def cached_property(fn): """Decorate property to cache return value.""" return property(functools.lru_cache(maxsize=8)(fn)) class ConfigDict(collections.UserDict): """Silently ignore None values, only take key once.""" def __init__(self, **kwargs): """Construct dictionary.""" super().__init__(kwargs) def __setitem__(self, key, value): """Store unique, not None values.""" if value is None: return if super().__contains__(key): return super().__setitem__(key, value) class FoldedString(collections.UserString): """Foldcase sequences value.""" def __init__(self, seq): super().__init__(seq) self.data.casefold() def fold_keys(): # noqa: D202 """Fold case of dictionary keys.""" @functools.wraps(fold_keys) def wrapped(mapping): """Fold case of dictionary keys.""" return {k.casefold(): v for (k, v) in mapping.items()} return wrapped def datetime_parse(string): """Convert timestamps to datetime. tzinfo aware, if provided. """ return dateutil_parse(string.upper(), fuzzy=True) def datetime_format(dt): """Format datetime in consistent style.""" if isinstance(dt, str): return datetime_parse(dt).isoformat() if isinstance(dt, datetime.datetime): return dt.isoformat() raise ValueError('Unable to format {}. Type {} not supported.'.format( dt, type(dt))) def flatten(list_, ltypes=(list, tuple)): """Flatten lists of list into a list.""" ltype = type(list_) list_ = list(list_) i = 0 while i < len(list_): while isinstance(list_[i], ltypes): if not list_[i]: list_.pop(i) i -= 1 break else: list_[i:i + 1] = list_[i] i += 1 return ltype(list_)