django-orchestra/orchestra/utils/python.py

113 lines
3.1 KiB
Python
Raw Normal View History

2015-03-23 15:36:51 +00:00
import sys
2014-05-08 16:59:35 +00:00
import collections
2015-03-04 21:06:16 +00:00
import random
import string
2015-04-02 16:14:55 +00:00
from io import StringIO
2014-05-08 16:59:35 +00:00
2014-05-13 13:46:40 +00:00
def import_class(cls):
module = '.'.join(cls.split('.')[:-1])
cls = cls.split('.')[-1]
module = __import__(module, fromlist=[module])
return getattr(module, cls)
2015-03-04 21:06:16 +00:00
def random_ascii(length):
return ''.join([random.SystemRandom().choice(string.hexdigits) for i in range(0, length)]).lower()
2015-03-04 21:06:16 +00:00
2014-05-08 16:59:35 +00:00
class OrderedSet(collections.MutableSet):
def __init__(self, iterable=None):
self.end = end = []
end += [None, end, end] # sentinel node for doubly linked list
self.map = {} # key --> [key, prev, next]
if iterable is not None:
self |= iterable
2014-07-10 10:03:22 +00:00
2014-05-08 16:59:35 +00:00
def __len__(self):
return len(self.map)
2014-07-10 10:03:22 +00:00
2014-05-08 16:59:35 +00:00
def __contains__(self, key):
return key in self.map
2014-07-10 10:03:22 +00:00
2014-05-08 16:59:35 +00:00
def add(self, key):
if key not in self.map:
end = self.end
curr = end[1]
curr[2] = end[1] = self.map[key] = [key, curr, end]
2014-07-10 10:03:22 +00:00
2014-05-08 16:59:35 +00:00
def discard(self, key):
2014-07-10 10:03:22 +00:00
if key in self.map:
2014-05-08 16:59:35 +00:00
key, prev, next = self.map.pop(key)
prev[2] = next
next[1] = prev
2014-07-10 10:03:22 +00:00
2014-05-08 16:59:35 +00:00
def __iter__(self):
end = self.end
curr = end[2]
while curr is not end:
yield curr[0]
curr = curr[2]
2014-07-10 10:03:22 +00:00
2014-05-08 16:59:35 +00:00
def __reversed__(self):
end = self.end
curr = end[1]
while curr is not end:
yield curr[0]
curr = curr[1]
2014-07-10 10:03:22 +00:00
2014-05-08 16:59:35 +00:00
def pop(self, last=True):
if not self:
raise KeyError('set is empty')
key = self.end[1][0] if last else self.end[2][0]
self.discard(key)
return key
2014-07-10 10:03:22 +00:00
2014-05-08 16:59:35 +00:00
def __repr__(self):
if not self:
return '%s()' % (self.__class__.__name__,)
return '%s(%r)' % (self.__class__.__name__, list(self))
2014-07-10 10:03:22 +00:00
2014-05-08 16:59:35 +00:00
def __eq__(self, other):
if isinstance(other, OrderedSet):
return len(self) == len(other) and list(self) == list(other)
return set(self) == set(other)
2014-09-10 16:53:09 +00:00
2014-09-26 15:05:20 +00:00
class AttrDict(dict):
2014-09-10 16:53:09 +00:00
def __init__(self, *args, **kwargs):
2014-09-26 15:05:20 +00:00
super(AttrDict, self).__init__(*args, **kwargs)
2014-09-10 16:53:09 +00:00
self.__dict__ = self
2015-03-23 15:36:51 +00:00
class CaptureStdout(list):
def __enter__(self):
self._stdout = sys.stdout
sys.stdout = self._stringio = StringIO()
return self
def __exit__(self, *args):
self.extend(self._stringio.getvalue().splitlines())
sys.stdout = self._stdout
2015-04-14 14:29:22 +00:00
def cmp_to_key(mycmp):
'Convert a cmp= function into a key= function'
class K(object):
def __init__(self, obj, *args):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) < 0
def __gt__(self, other):
return mycmp(self.obj, other.obj) > 0
def __eq__(self, other):
return mycmp(self.obj, other.obj) == 0
def __le__(self, other):
return mycmp(self.obj, other.obj) <= 0
def __ge__(self, other):
return mycmp(self.obj, other.obj) >= 0
def __ne__(self, other):
return mycmp(self.obj, other.obj) != 0
return K