123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- ############## py3k #########################################################
- try:
- from UserList import UserList # noqa
- except ImportError:
- from collections import UserList # noqa
- try:
- from UserDict import UserDict # noqa
- except ImportError:
- from collections import UserDict # noqa
- try:
- from cStringIO import StringIO # noqa
- except ImportError:
- try:
- from StringIO import StringIO # noqa
- except ImportError:
- from io import StringIO # noqa
- ############## collections.OrderedDict ######################################
- import weakref
- try:
- from collections import MutableMapping
- except ImportError:
- from UserDict import DictMixin as MutableMapping # noqa
- from itertools import imap as _imap
- from operator import eq as _eq
- class _Link(object):
- """Doubly linked list."""
- # next can't be lowercase because 2to3 thinks it's a generator
- # and renames it to __next__.
- __slots__ = 'PREV', 'NEXT', 'key', '__weakref__'
- class CompatOrderedDict(dict, MutableMapping):
- """Dictionary that remembers insertion order"""
- # An inherited dict maps keys to values.
- # The inherited dict provides __getitem__, __len__, __contains__, and get.
- # The remaining methods are order-aware.
- # Big-O running times for all methods are the same as for regular
- # dictionaries.
- # The internal self.__map dictionary maps keys to links in a doubly
- # linked list.
- # The circular doubly linked list starts and ends with a sentinel element.
- # The sentinel element never gets deleted (this simplifies the algorithm).
- # The prev/next links are weakref proxies (to prevent circular
- # references).
- # Individual links are kept alive by the hard reference in self.__map.
- # Those hard references disappear when a key is deleted from
- # an OrderedDict.
- __marker = object()
- def __init__(self, *args, **kwds):
- """Initialize an ordered dictionary.
- Signature is the same as for regular dictionaries, but keyword
- arguments are not recommended because their insertion order is
- arbitrary.
- """
- if len(args) > 1:
- raise TypeError("expected at most 1 arguments, got %d" % (
- len(args)))
- try:
- self._root
- except AttributeError:
- # sentinel node for the doubly linked list
- self._root = root = _Link()
- root.PREV = root.NEXT = root
- self.__map = {}
- self.update(*args, **kwds)
- def clear(self):
- "od.clear() -> None. Remove all items from od."
- root = self._root
- root.PREV = root.NEXT = root
- self.__map.clear()
- dict.clear(self)
- def __setitem__(self, key, value):
- "od.__setitem__(i, y) <==> od[i]=y"
- # Setting a new item creates a new link which goes at the end of the
- # linked list, and the inherited dictionary is updated with the new
- # key/value pair.
- if key not in self:
- self.__map[key] = link = _Link()
- root = self._root
- last = root.PREV
- link.PREV, link.NEXT, link.key = last, root, key
- last.NEXT = root.PREV = weakref.proxy(link)
- dict.__setitem__(self, key, value)
- def __delitem__(self, key):
- """od.__delitem__(y) <==> del od[y]"""
- # Deleting an existing item uses self.__map to find the
- # link which is then removed by updating the links in the
- # predecessor and successor nodes.
- dict.__delitem__(self, key)
- link = self.__map.pop(key)
- link.PREV.NEXT = link.NEXT
- link.NEXT.PREV = link.PREV
- def __iter__(self):
- """od.__iter__() <==> iter(od)"""
- # Traverse the linked list in order.
- root = self._root
- curr = root.NEXT
- while curr is not root:
- yield curr.key
- curr = curr.NEXT
- def __reversed__(self):
- """od.__reversed__() <==> reversed(od)"""
- # Traverse the linked list in reverse order.
- root = self._root
- curr = root.PREV
- while curr is not root:
- yield curr.key
- curr = curr.PREV
- def __reduce__(self):
- """Return state information for pickling"""
- items = [[k, self[k]] for k in self]
- tmp = self.__map, self._root
- del(self.__map, self._root)
- inst_dict = vars(self).copy()
- self.__map, self._root = tmp
- if inst_dict:
- return (self.__class__, (items,), inst_dict)
- return self.__class__, (items,)
- def setdefault(self, key, default=None):
- try:
- return self[key]
- except KeyError:
- self[key] = default
- return default
- def update(self, other=(), **kwds):
- if isinstance(other, dict):
- for key in other:
- self[key] = other[key]
- elif hasattr(other, "keys"):
- for key in other.keys():
- self[key] = other[key]
- else:
- for key, value in other:
- self[key] = value
- for key, value in kwds.items():
- self[key] = value
- def pop(self, key, default=__marker):
- try:
- value = self[key]
- except KeyError:
- if default is self.__marker:
- raise
- return default
- else:
- del self[key]
- return value
- def values(self):
- return [self[key] for key in self]
- def items(self):
- return [(key, self[key]) for key in self]
- def itervalues(self):
- for key in self:
- yield self[key]
- def iteritems(self):
- for key in self:
- yield (key, self[key])
- def iterkeys(self):
- return iter(self)
- def keys(self):
- return list(self)
- def popitem(self, last=True):
- """od.popitem() -> (k, v)
- Return and remove a (key, value) pair.
- Pairs are returned in LIFO order if last is true or FIFO
- order if false.
- """
- if not self:
- raise KeyError('dictionary is empty')
- key = (last and reversed(self) or iter(self)).next()
- value = self.pop(key)
- return key, value
- def __repr__(self):
- "od.__repr__() <==> repr(od)"
- if not self:
- return '%s()' % (self.__class__.__name__,)
- return '%s(%r)' % (self.__class__.__name__, self.items())
- def copy(self):
- "od.copy() -> a shallow copy of od"
- return self.__class__(self)
- @classmethod
- def fromkeys(cls, iterable, value=None):
- """OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S
- and values equal to v (which defaults to None)."""
- d = cls()
- for key in iterable:
- d[key] = value
- return d
- def __eq__(self, other):
- """od.__eq__(y) <==> od==y. Comparison to another OD is
- order-sensitive while comparison to a regular mapping
- is order-insensitive."""
- if isinstance(other, OrderedDict):
- return len(self) == len(other) and \
- all(_imap(_eq, self.iteritems(), other.iteritems()))
- return dict.__eq__(self, other)
- def __ne__(self, other):
- return not (self == other)
- try:
- from collections import OrderedDict
- except ImportError:
- OrderedDict = CompatOrderedDict # noqa
- ############## logging.LoggerAdapter ########################################
- import inspect
- import logging
- try:
- import multiprocessing
- except ImportError:
- multiprocessing = None # noqa
- import sys
- def _checkLevel(level):
- if isinstance(level, int):
- rv = level
- elif str(level) == level:
- if level not in logging._levelNames:
- raise ValueError("Unknown level: %r" % level)
- rv = logging._levelNames[level]
- else:
- raise TypeError("Level not an integer or a valid string: %r" % level)
- return rv
- class _CompatLoggerAdapter(object):
- def __init__(self, logger, extra):
- self.logger = logger
- self.extra = extra
- def setLevel(self, level):
- self.logger.level = _checkLevel(level)
- def process(self, msg, kwargs):
- kwargs["extra"] = self.extra
- return msg, kwargs
- def debug(self, msg, *args, **kwargs):
- self.log(logging.DEBUG, msg, *args, **kwargs)
- def info(self, msg, *args, **kwargs):
- self.log(logging.INFO, msg, *args, **kwargs)
- def warning(self, msg, *args, **kwargs):
- self.log(logging.WARNING, msg, *args, **kwargs)
- warn = warning
- def error(self, msg, *args, **kwargs):
- self.log(logging.ERROR, msg, *args, **kwargs)
- def exception(self, msg, *args, **kwargs):
- kwargs.setdefault("exc_info", 1)
- self.error(msg, *args, **kwargs)
- def critical(self, msg, *args, **kwargs):
- self.log(logging.CRITICAL, msg, *args, **kwargs)
- fatal = critical
- def log(self, level, msg, *args, **kwargs):
- if self.logger.isEnabledFor(level):
- msg, kwargs = self.process(msg, kwargs)
- self._log(level, msg, args, **kwargs)
- def makeRecord(self, name, level, fn, lno, msg, args, exc_info,
- func=None, extra=None):
- rv = logging.LogRecord(name, level, fn, lno, msg, args, exc_info, func)
- if extra is not None:
- for key, value in extra.items():
- if key in ("message", "asctime") or key in rv.__dict__:
- raise KeyError(
- "Attempt to override %r in LogRecord" % key)
- rv.__dict__[key] = value
- if multiprocessing is not None:
- rv.processName = multiprocessing.current_process()._name
- else:
- rv.processName = ""
- return rv
- def _log(self, level, msg, args, exc_info=None, extra=None):
- defcaller = "(unknown file)", 0, "(unknown function)"
- if logging._srcfile:
- # IronPython doesn't track Python frames, so findCaller
- # throws an exception on some versions of IronPython.
- # We trap it here so that IronPython can use logging.
- try:
- fn, lno, func = self.logger.findCaller()
- except ValueError:
- fn, lno, func = defcaller
- else:
- fn, lno, func = defcaller
- if exc_info:
- if not isinstance(exc_info, tuple):
- exc_info = sys.exc_info()
- record = self.makeRecord(self.logger.name, level, fn, lno, msg,
- args, exc_info, func, extra)
- self.logger.handle(record)
- def isEnabledFor(self, level):
- return self.logger.isEnabledFor(level)
- def addHandler(self, hdlr):
- self.logger.addHandler(hdlr)
- def removeHandler(self, hdlr):
- self.logger.removeHandler(hdlr)
- @property
- def level(self):
- return self.logger.level
- try:
- from logging import LoggerAdapter
- except ImportError:
- LoggerAdapter = _CompatLoggerAdapter # noqa
- ############## itertools.izip_longest #######################################
- try:
- from itertools import izip_longest
- except ImportError:
- import itertools
- def izip_longest(*args, **kwds): # noqa
- fillvalue = kwds.get("fillvalue")
- def sentinel(counter=([fillvalue] * (len(args) - 1)).pop):
- yield counter() # yields the fillvalue, or raises IndexError
- fillers = itertools.repeat(fillvalue)
- iters = [itertools.chain(it, sentinel(), fillers)
- for it in args]
- try:
- for tup in itertools.izip(*iters):
- yield tup
- except IndexError:
- pass
- ############## itertools.chain.from_iterable ################################
- from itertools import chain
- def _compat_chain_from_iterable(iterables):
- for it in iterables:
- for element in it:
- yield element
- try:
- chain_from_iterable = getattr(chain, "from_iterable")
- except AttributeError:
- chain_from_iterable = _compat_chain_from_iterable
- ############## logging.handlers.WatchedFileHandler ##########################
- import os
- from stat import ST_DEV, ST_INO
- import platform as _platform
- if _platform.system() == "Windows":
- #since windows doesn't go with WatchedFileHandler use FileHandler instead
- WatchedFileHandler = logging.FileHandler
- else:
- try:
- from logging.handlers import WatchedFileHandler
- except ImportError:
- class WatchedFileHandler(logging.FileHandler): # noqa
- """
- A handler for logging to a file, which watches the file
- to see if it has changed while in use. This can happen because of
- usage of programs such as newsyslog and logrotate which perform
- log file rotation. This handler, intended for use under Unix,
- watches the file to see if it has changed since the last emit.
- (A file has changed if its device or inode have changed.)
- If it has changed, the old file stream is closed, and the file
- opened to get a new stream.
- This handler is not appropriate for use under Windows, because
- under Windows open files cannot be moved or renamed - logging
- opens the files with exclusive locks - and so there is no need
- for such a handler. Furthermore, ST_INO is not supported under
- Windows; stat always returns zero for this value.
- This handler is based on a suggestion and patch by Chad J.
- Schroeder.
- """
- def __init__(self, *args, **kwargs):
- logging.FileHandler.__init__(self, *args, **kwargs)
- if not os.path.exists(self.baseFilename):
- self.dev, self.ino = -1, -1
- else:
- stat = os.stat(self.baseFilename)
- self.dev, self.ino = stat[ST_DEV], stat[ST_INO]
- def emit(self, record):
- """
- Emit a record.
- First check if the underlying file has changed, and if it
- has, close the old stream and reopen the file to get the
- current stream.
- """
- if not os.path.exists(self.baseFilename):
- stat = None
- changed = 1
- else:
- stat = os.stat(self.baseFilename)
- changed = ((stat[ST_DEV] != self.dev) or
- (stat[ST_INO] != self.ino))
- if changed and self.stream is not None:
- self.stream.flush()
- self.stream.close()
- self.stream = self._open()
- if stat is None:
- stat = os.stat(self.baseFilename)
- self.dev, self.ino = stat[ST_DEV], stat[ST_INO]
- logging.FileHandler.emit(self, record)
|