diff options
Diffstat (limited to 'lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util')
11 files changed, 0 insertions, 1259 deletions
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/__init__.py deleted file mode 100644 index 281c345c..00000000 --- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/__init__.py +++ /dev/null @@ -1,204 +0,0 @@ -# This file is part of Buildbot. Buildbot is free software: you can -# redistribute it and/or modify it under the terms of the GNU General Public -# License as published by the Free Software Foundation, version 2. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License along with -# this program; if not, write to the Free Software Foundation, Inc., 51 -# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Copyright Buildbot Team Members - - -import time, re, string -import datetime -import calendar -from buildbot.util.misc import deferredLocked, SerializedInvocation - -def naturalSort(l): - l = l[:] - def try_int(s): - try: - return int(s) - except ValueError: - return s - def key_func(item): - return [try_int(s) for s in re.split('(\d+)', item)] - # prepend integer keys to each element, sort them, then strip the keys - keyed_l = [ (key_func(i), i) for i in l ] - keyed_l.sort() - l = [ i[1] for i in keyed_l ] - return l - -def flatten(l): - if l and type(l[0]) == list: - rv = [] - for e in l: - if type(e) == list: - rv.extend(flatten(e)) - else: - rv.append(e) - return rv - else: - return l - -def now(_reactor=None): - if _reactor and hasattr(_reactor, "seconds"): - return _reactor.seconds() - else: - return time.time() - -def formatInterval(eta): - eta_parts = [] - if eta > 3600: - eta_parts.append("%d hrs" % (eta / 3600)) - eta %= 3600 - if eta > 60: - eta_parts.append("%d mins" % (eta / 60)) - eta %= 60 - eta_parts.append("%d secs" % eta) - return ", ".join(eta_parts) - -class ComparableMixin: - - compare_attrs = [] - - class _None: - pass - - def __hash__(self): - alist = [self.__class__] + \ - [getattr(self, name, self._None) for name in self.compare_attrs] - return hash(tuple(map(str, alist))) - - def __cmp__(self, them): - result = cmp(type(self), type(them)) - if result: - return result - - result = cmp(self.__class__.__name__, them.__class__.__name__) - if result: - return result - - result = cmp(self.compare_attrs, them.compare_attrs) - if result: - return result - - self_list = [getattr(self, name, self._None) - for name in self.compare_attrs] - them_list = [getattr(them, name, self._None) - for name in self.compare_attrs] - return cmp(self_list, them_list) - -def diffSets(old, new): - if not isinstance(old, set): - old = set(old) - if not isinstance(new, set): - new = set(new) - return old - new, new - old - -# Remove potentially harmful characters from builder name if it is to be -# used as the build dir. -badchars_map = string.maketrans("\t !#$%&'()*+,./:;<=>?@[\\]^{|}~", - "______________________________") -def safeTranslate(str): - if isinstance(str, unicode): - str = str.encode('utf8') - return str.translate(badchars_map) - -def none_or_str(x): - if x is not None and not isinstance(x, str): - return str(x) - return x - -# place a working json module at 'buildbot.util.json'. Code is adapted from -# Paul Wise <pabs@debian.org>: -# http://lists.debian.org/debian-python/2010/02/msg00016.html -# json doesn't exist as a standard module until python2.6 -# However python2.6's json module is much slower than simplejson, so we prefer -# to use simplejson if available. -try: - import simplejson as json - assert json -except ImportError: - import json # python 2.6 or 2.7 -try: - _tmp = json.loads -except AttributeError: - import warnings - import sys - warnings.warn("Use simplejson, not the old json module.") - sys.modules.pop('json') # get rid of the bad json module - import simplejson as json - -# changes and schedulers consider None to be a legitimate name for a branch, -# which makes default function keyword arguments hard to handle. This value -# is always false. -class NotABranch: - def __nonzero__(self): - return False -NotABranch = NotABranch() - -# time-handling methods - -class UTC(datetime.tzinfo): - """Simple definition of UTC timezone""" - def utcoffset(self, dt): - return datetime.timedelta(0) - - def dst(self, dt): - return datetime.timedelta(0) - - def tzname(self): - return "UTC" -UTC = UTC() - -def epoch2datetime(epoch): - """Convert a UNIX epoch time to a datetime object, in the UTC timezone""" - if epoch is not None: - return datetime.datetime.fromtimestamp(epoch, tz=UTC) - -def datetime2epoch(dt): - """Convert a non-naive datetime object to a UNIX epoch timestamp""" - if dt is not None: - return calendar.timegm(dt.utctimetuple()) - -def makeList(input): - if isinstance(input, basestring): - return [ input ] - elif input is None: - return [ ] - else: - return list(input) - -def in_reactor(f): - """decorate a function by running it with maybeDeferred in a reactor""" - def wrap(*args, **kwargs): - from twisted.internet import reactor, defer - result = [ ] - def async(): - d = defer.maybeDeferred(f, *args, **kwargs) - def eb(f): - f.printTraceback() - d.addErrback(eb) - def do_stop(r): - result.append(r) - reactor.stop() - d.addBoth(do_stop) - reactor.callWhenRunning(async) - reactor.run() - return result[0] - wrap.__doc__ = f.__doc__ - wrap.__name__ = f.__name__ - wrap._orig = f # for tests - return wrap - -__all__ = [ - 'naturalSort', 'now', 'formatInterval', 'ComparableMixin', 'json', - 'safeTranslate', 'LRUCache', 'none_or_str', - 'NotABranch', 'deferredLocked', 'SerializedInvocation', 'UTC', - 'diffLists', 'makeList', 'in_reactor' ] diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/bbcollections.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/bbcollections.py deleted file mode 100644 index 96e0eb27..00000000 --- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/bbcollections.py +++ /dev/null @@ -1,40 +0,0 @@ -# This file is part of Buildbot. Buildbot is free software: you can -# redistribute it and/or modify it under the terms of the GNU General Public -# License as published by the Free Software Foundation, version 2. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License along with -# this program; if not, write to the Free Software Foundation, Inc., 51 -# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Copyright Buildbot Team Members - -# this is here for compatibility -from collections import defaultdict -assert defaultdict - -class KeyedSets: - def __init__(self): - self.d = dict() - def add(self, key, value): - if key not in self.d: - self.d[key] = set() - self.d[key].add(value) - def discard(self, key, value): - if key in self.d: - self.d[key].discard(value) - if not self.d[key]: - del self.d[key] - def __contains__(self, key): - return key in self.d - def __getitem__(self, key): - return self.d.get(key, set()) - def pop(self, key): - if key in self.d: - return self.d.pop(key) - return set() - diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/croniter.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/croniter.py deleted file mode 100644 index 21ffca58..00000000 --- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/croniter.py +++ /dev/null @@ -1,311 +0,0 @@ -# Copied from croniter -# https://github.com/taichino/croniter -# Licensed under MIT license -# Pyflakes warnings corrected - -#!/usr/bin/python -# -*- coding: utf-8 -*- - -import re -from time import time, mktime -from datetime import datetime -from dateutil.relativedelta import relativedelta - -search_re = re.compile(r'^([^-]+)-([^-/]+)(/(.*))?$') -only_int_re = re.compile(r'^\d+$') -any_int_re = re.compile(r'^\d+') -star_or_int_re = re.compile(r'^(\d+|\*)$') - -__all__ = ('croniter',) - - -class croniter(object): - RANGES = ( - (0, 59), - (0, 23), - (1, 31), - (1, 12), - (0, 6), - (0, 59) - ) - DAYS = ( - 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 - ) - - ALPHACONV = ( - { }, - { }, - { }, - { 'jan':1, 'feb':2, 'mar':3, 'apr':4, 'may':5, 'jun':6, - 'jul':7, 'aug':8, 'sep':9, 'oct':10, 'nov':11, 'dec':12 }, - { 'sun':0, 'mon':1, 'tue':2, 'wed':3, 'thu':4, 'fri':5, 'sat':0 }, - { } - ) - - LOWMAP = ( - {}, - {}, - {0: 1}, - {0: 1}, - {7: 0}, - {}, - ) - - bad_length = 'Exactly 5 or 6 columns has to be specified for iterator' \ - 'expression.' - - def __init__(self, expr_format, start_time=time()): - if isinstance(start_time, datetime): - start_time = mktime(start_time.timetuple()) - - self.cur = start_time - self.exprs = expr_format.split() - - if len(self.exprs) != 5 and len(self.exprs) != 6: - raise ValueError(self.bad_length) - - expanded = [] - - for i, expr in enumerate(self.exprs): - e_list = expr.split(',') - res = [] - - while len(e_list) > 0: - e = e_list.pop() - t = re.sub(r'^\*(/.+)$', r'%d-%d\1' % (self.RANGES[i][0], - self.RANGES[i][1]), - str(e)) - m = search_re.search(t) - - if m: - (low, high, step) = m.group(1), m.group(2), m.group(4) or 1 - - if not any_int_re.search(low): - low = self.ALPHACONV[i][low.lower()] - - if not any_int_re.search(high): - high = self.ALPHACONV[i][high.lower()] - - if (not low or not high or int(low) > int(high) - or not only_int_re.search(str(step))): - raise ValueError("[%s] is not acceptable" %expr_format) - - for j in xrange(int(low), int(high)+1): - if j % int(step) == 0: - e_list.append(j) - else: - if not star_or_int_re.search(t): - t = self.ALPHACONV[i][t.lower()] - - try: - t = int(t) - except: - pass - - if t in self.LOWMAP[i]: - t = self.LOWMAP[i][t] - - if t != '*' and (int(t) < self.RANGES[i][0] or - int(t) > self.RANGES[i][1]): - raise ValueError("[%s] is not acceptable, out of range" % expr_format) - - res.append(t) - - res.sort() - expanded.append(['*'] if (len(res) == 1 and res[0] == '*') else res) - self.expanded = expanded - - def get_next(self, ret_type=float): - return self._get_next(ret_type, is_prev=False) - - def get_prev(self, ret_type=float): - return self._get_next(ret_type, is_prev=True) - - def _get_next(self, ret_type=float, is_prev=False): - expanded = self.expanded[:] - - if ret_type not in (float, datetime): - raise TypeError("Invalid ret_type, only 'float' or 'datetime' " \ - "is acceptable.") - - if expanded[2][0] != '*' and expanded[4][0] != '*': - bak = expanded[4] - expanded[4] = ['*'] - t1 = self._calc(self.cur, expanded, is_prev) - expanded[4] = bak - expanded[2] = ['*'] - - t2 = self._calc(self.cur, expanded, is_prev) - if not is_prev: - result = t1 if t1 < t2 else t2 - else: - result = t1 if t1 > t2 else t2 - else: - result = self._calc(self.cur, expanded, is_prev) - self.cur = result - - if ret_type == datetime: - result = datetime.fromtimestamp(result) - return result - - def _calc(self, now, expanded, is_prev): - if is_prev: - nearest_diff_method = self._get_prev_nearest_diff - sign = -1 - else: - nearest_diff_method = self._get_next_nearest_diff - sign = 1 - - offset = len(expanded) == 6 and 1 or 60 - dst = now = datetime.fromtimestamp(now + sign * offset) - - day, month, year = dst.day, dst.month, dst.year - current_year = now.year - DAYS = self.DAYS - - def proc_month(d): - if expanded[3][0] != '*': - diff_month = nearest_diff_method(d.month, expanded[3], 12) - days = DAYS[month - 1] - if month == 2 and self.is_leap(year) == True: - days += 1 - - reset_day = days if is_prev else 1 - - if diff_month != None and diff_month != 0: - if is_prev: - d += relativedelta(months=diff_month) - else: - d += relativedelta(months=diff_month, day=reset_day, - hour=0, minute=0, second=0) - return True, d - return False, d - - def proc_day_of_month(d): - if expanded[2][0] != '*': - days = DAYS[month - 1] - if month == 2 and self.is_leap(year) == True: - days += 1 - - diff_day = nearest_diff_method(d.day, expanded[2], days) - - if diff_day != None and diff_day != 0: - if is_prev: - d += relativedelta(days=diff_day) - else: - d += relativedelta(days=diff_day, hour=0, minute=0, second=0) - return True, d - return False, d - - def proc_day_of_week(d): - if expanded[4][0] != '*': - diff_day_of_week = nearest_diff_method(d.isoweekday() % 7, expanded[4], 7) - if diff_day_of_week != None and diff_day_of_week != 0: - if is_prev: - d += relativedelta(days=diff_day_of_week) - else: - d += relativedelta(days=diff_day_of_week, hour=0, minute=0, second=0) - return True, d - return False, d - - def proc_hour(d): - if expanded[1][0] != '*': - diff_hour = nearest_diff_method(d.hour, expanded[1], 24) - if diff_hour != None and diff_hour != 0: - if is_prev: - d += relativedelta(hours = diff_hour) - else: - d += relativedelta(hours = diff_hour, minute=0, second=0) - return True, d - return False, d - - def proc_minute(d): - if expanded[0][0] != '*': - diff_min = nearest_diff_method(d.minute, expanded[0], 60) - if diff_min != None and diff_min != 0: - if is_prev: - d += relativedelta(minutes = diff_min) - else: - d += relativedelta(minutes = diff_min, second=0) - return True, d - return False, d - - def proc_second(d): - if len(expanded) == 6: - if expanded[5][0] != '*': - diff_sec = nearest_diff_method(d.second, expanded[5], 60) - if diff_sec != None and diff_sec != 0: - d += relativedelta(seconds = diff_sec) - return True, d - else: - d += relativedelta(second = 0) - return False, d - - if is_prev: - procs = [proc_second, - proc_minute, - proc_hour, - proc_day_of_week, - proc_day_of_month, - proc_month] - else: - procs = [proc_month, - proc_day_of_month, - proc_day_of_week, - proc_hour, - proc_minute, - proc_second] - - while abs(year - current_year) <= 1: - next = False - for proc in procs: - (changed, dst) = proc(dst) - if changed: - next = True - break - if next: - continue - return mktime(dst.timetuple()) - - raise "failed to find prev date" - - def _get_next_nearest(self, x, to_check): - small = [item for item in to_check if item < x] - large = [item for item in to_check if item >= x] - large.extend(small) - return large[0] - - def _get_prev_nearest(self, x, to_check): - small = [item for item in to_check if item <= x] - large = [item for item in to_check if item > x] - small.reverse() - large.reverse() - small.extend(large) - return small[0] - - def _get_next_nearest_diff(self, x, to_check, range_val): - for i, d in enumerate(to_check): - if d >= x: - return d - x - return to_check[0] - x + range_val - - def _get_prev_nearest_diff(self, x, to_check, range_val): - candidates = to_check[:] - candidates.reverse() - for d in candidates: - if d <= x: - return d - x - return (candidates[0]) - x - range_val - - def is_leap(self, year): - if year % 400 == 0 or (year % 4 == 0 and year % 100 != 0): - return True - else: - return False - -if __name__ == '__main__': - - base = datetime(2010, 1, 25) - itr = croniter('0 0 1 * *', base) - n1 = itr.get_next(datetime) - print n1 diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/eventual.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/eventual.py deleted file mode 100644 index 15fba6cf..00000000 --- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/eventual.py +++ /dev/null @@ -1,85 +0,0 @@ -# This file is part of Buildbot. Buildbot is free software: you can -# redistribute it and/or modify it under the terms of the GNU General Public -# License as published by the Free Software Foundation, version 2. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License along with -# this program; if not, write to the Free Software Foundation, Inc., 51 -# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Copyright Buildbot Team Members - - -# copied from foolscap - -from twisted.internet import reactor, defer -from twisted.python import log - -class _SimpleCallQueue(object): - - _reactor = reactor - - def __init__(self): - self._events = [] - self._flushObservers = [] - self._timer = None - self._in_turn = False - - def append(self, cb, args, kwargs): - self._events.append((cb, args, kwargs)) - if not self._timer: - self._timer = self._reactor.callLater(0, self._turn) - - def _turn(self): - self._timer = None - self._in_turn = True - # flush all the messages that are currently in the queue. If anything - # gets added to the queue while we're doing this, those events will - # be put off until the next turn. - events, self._events = self._events, [] - for cb, args, kwargs in events: - try: - cb(*args, **kwargs) - except: - log.err() - self._in_turn = False - if self._events and not self._timer: - self._timer = self._reactor.callLater(0, self._turn) - if not self._events: - observers, self._flushObservers = self._flushObservers, [] - for o in observers: - o.callback(None) - - def flush(self): - if not self._events and not self._in_turn: - return defer.succeed(None) - d = defer.Deferred() - self._flushObservers.append(d) - return d - - -_theSimpleQueue = _SimpleCallQueue() - -def eventually(cb, *args, **kwargs): - _theSimpleQueue.append(cb, args, kwargs) - - -def fireEventually(value=None): - d = defer.Deferred() - eventually(d.callback, value) - return d - -def flushEventualQueue(_ignored=None): - return _theSimpleQueue.flush() - -def _setReactor(r=None): - # This sets the reactor used to schedule future events to r. If r is None - # (the default), the reactor is reset to its default value. - # This should only be used for unit tests. - if r is None: - r = reactor - _theSimpleQueue._reactor = r diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/lru.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/lru.py deleted file mode 100644 index d7ae14b7..00000000 --- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/lru.py +++ /dev/null @@ -1,232 +0,0 @@ -# This file is part of Buildbot. Buildbot is free software: you can -# redistribute it and/or modify it under the terms of the GNU General Public -# License as published by the Free Software Foundation, version 2. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License along with -# this program; if not, write to the Free Software Foundation, Inc., 51 -# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Copyright Buildbot Team Members - -from weakref import WeakValueDictionary -from itertools import ifilterfalse -from twisted.python import log -from twisted.internet import defer -from collections import deque -from collections import defaultdict - - -class LRUCache(object): - """ - A least-recently-used cache, with a fixed maximum size. - - See buildbot manual for more information. - """ - - __slots__ = ('max_size max_queue miss_fn queue cache weakrefs ' - 'refcount hits refhits misses'.split()) - sentinel = object() - QUEUE_SIZE_FACTOR = 10 - - def __init__(self, miss_fn, max_size=50): - self.max_size = max_size - self.max_queue = max_size * self.QUEUE_SIZE_FACTOR - self.queue = deque() - self.cache = {} - self.weakrefs = WeakValueDictionary() - self.hits = self.misses = self.refhits = 0 - self.refcount = defaultdict(lambda : 0) - self.miss_fn = miss_fn - - def put(self, key, value): - if key in self.cache: - self.cache[key] = value - self.weakrefs[key] = value - elif key in self.weakrefs: - self.weakrefs[key] = value - - def get(self, key, **miss_fn_kwargs): - try: - return self._get_hit(key) - except KeyError: - pass - - self.misses += 1 - - result = self.miss_fn(key, **miss_fn_kwargs) - if result is not None: - self.cache[key] = result - self.weakrefs[key] = result - self._ref_key(key) - self._purge() - - return result - - def keys(self): - return self.cache.keys() - - def set_max_size(self, max_size): - if self.max_size == max_size: - return - - self.max_size = max_size - self.max_queue = max_size * self.QUEUE_SIZE_FACTOR - self._purge() - - def inv(self): - global inv_failed - - # the keys of the queue and cache should be identical - cache_keys = set(self.cache.keys()) - queue_keys = set(self.queue) - if queue_keys - cache_keys: - log.msg("INV: uncached keys in queue:", queue_keys - cache_keys) - inv_failed = True - if cache_keys - queue_keys: - log.msg("INV: unqueued keys in cache:", cache_keys - queue_keys) - inv_failed = True - - # refcount should always represent the number of times each key appears - # in the queue - exp_refcount = dict() - for k in self.queue: - exp_refcount[k] = exp_refcount.get(k, 0) + 1 - if exp_refcount != self.refcount: - log.msg("INV: refcounts differ:") - log.msg(" expected:", sorted(exp_refcount.items())) - log.msg(" got:", sorted(self.refcount.items())) - inv_failed = True - - def _ref_key(self, key): - """Record a reference to the argument key.""" - queue = self.queue - refcount = self.refcount - - queue.append(key) - refcount[key] = refcount[key] + 1 - - # periodically compact the queue by eliminating duplicate keys - # while preserving order of most recent access. Note that this - # is only required when the cache does not exceed its maximum - # size - if len(queue) > self.max_queue: - refcount.clear() - queue_appendleft = queue.appendleft - queue_appendleft(self.sentinel) - for k in ifilterfalse(refcount.__contains__, - iter(queue.pop, self.sentinel)): - queue_appendleft(k) - refcount[k] = 1 - - def _get_hit(self, key): - """Try to do a value lookup from the existing cache entries.""" - try: - result = self.cache[key] - self.hits += 1 - self._ref_key(key) - return result - except KeyError: - pass - - result = self.weakrefs[key] - self.refhits += 1 - self.cache[key] = result - self._ref_key(key) - return result - - def _purge(self): - """ - Trim the cache down to max_size by evicting the - least-recently-used entries. - """ - if len(self.cache) <= self.max_size: - return - - cache = self.cache - refcount = self.refcount - queue = self.queue - max_size = self.max_size - - # purge least recently used entries, using refcount to count entries - # that appear multiple times in the queue - while len(cache) > max_size: - refc = 1 - while refc: - k = queue.popleft() - refc = refcount[k] = refcount[k] - 1 - del cache[k] - del refcount[k] - - -class AsyncLRUCache(LRUCache): - """ - An LRU cache with asynchronous locking to ensure that in the common case of - multiple concurrent requests for the same key, only one fetch is performed. - """ - - __slots__ = ['concurrent'] - - def __init__(self, miss_fn, max_size=50): - LRUCache.__init__(self, miss_fn, max_size=max_size) - self.concurrent = {} - - def get(self, key, **miss_fn_kwargs): - try: - result = self._get_hit(key) - return defer.succeed(result) - except KeyError: - pass - - concurrent = self.concurrent - conc = concurrent.get(key) - if conc: - self.hits += 1 - d = defer.Deferred() - conc.append(d) - return d - - # if we're here, we've missed and need to fetch - self.misses += 1 - - # create a list of waiting deferreds for this key - d = defer.Deferred() - assert key not in concurrent - concurrent[key] = [ d ] - - miss_d = self.miss_fn(key, **miss_fn_kwargs) - - def handle_result(result): - if result is not None: - self.cache[key] = result - self.weakrefs[key] = result - - # reference the key once, possibly standing in for multiple - # concurrent accesses - self._ref_key(key) - - self._purge() - - # and fire all of the waiting Deferreds - dlist = concurrent.pop(key) - for d in dlist: - d.callback(result) - - def handle_failure(f): - # errback all of the waiting Deferreds - dlist = concurrent.pop(key) - for d in dlist: - d.errback(f) - - miss_d.addCallbacks(handle_result, handle_failure) - miss_d.addErrback(log.err) - - return d - - -# for tests -inv_failed = False diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/maildir.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/maildir.py deleted file mode 100644 index 66e895b3..00000000 --- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/maildir.py +++ /dev/null @@ -1,142 +0,0 @@ -# This file is part of Buildbot. Buildbot is free software: you can -# redistribute it and/or modify it under the terms of the GNU General Public -# License as published by the Free Software Foundation, version 2. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License along with -# this program; if not, write to the Free Software Foundation, Inc., 51 -# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Copyright Buildbot Team Members - - -# This is a class which watches a maildir for new messages. It uses the -# linux dirwatcher API (if available) to look for new files. The -# .messageReceived method is invoked with the filename of the new message, -# relative to the top of the maildir (so it will look like "new/blahblah"). - -import os -from twisted.python import log, runtime -from twisted.application import service, internet -from twisted.internet import reactor, defer -dnotify = None -try: - import dnotify -except: - log.msg("unable to import dnotify, so Maildir will use polling instead") - -class NoSuchMaildir(Exception): - pass - -class MaildirService(service.MultiService): - pollinterval = 10 # only used if we don't have DNotify - - def __init__(self, basedir=None): - service.MultiService.__init__(self) - if basedir: - self.setBasedir(basedir) - self.files = [] - self.dnotify = None - self.timerService = None - - def setBasedir(self, basedir): - # some users of MaildirService (scheduler.Try_Jobdir, in particular) - # don't know their basedir until setServiceParent, since it is - # relative to the buildmaster's basedir. So let them set it late. We - # don't actually need it until our own startService. - self.basedir = basedir - self.newdir = os.path.join(self.basedir, "new") - self.curdir = os.path.join(self.basedir, "cur") - - def startService(self): - service.MultiService.startService(self) - if not os.path.isdir(self.newdir) or not os.path.isdir(self.curdir): - raise NoSuchMaildir("invalid maildir '%s'" % self.basedir) - try: - if dnotify: - # we must hold an fd open on the directory, so we can get - # notified when it changes. - self.dnotify = dnotify.DNotify(self.newdir, - self.dnotify_callback, - [dnotify.DNotify.DN_CREATE]) - except (IOError, OverflowError): - # IOError is probably linux<2.4.19, which doesn't support - # dnotify. OverflowError will occur on some 64-bit machines - # because of a python bug - log.msg("DNotify failed, falling back to polling") - if not self.dnotify: - self.timerService = internet.TimerService(self.pollinterval, self.poll) - self.timerService.setServiceParent(self) - self.poll() - - - def dnotify_callback(self): - log.msg("dnotify noticed something, now polling") - - # give it a moment. I found that qmail had problems when the message - # was removed from the maildir instantly. It shouldn't, that's what - # maildirs are made for. I wasn't able to eyeball any reason for the - # problem, and safecat didn't behave the same way, but qmail reports - # "Temporary_error_on_maildir_delivery" (qmail-local.c:165, - # maildir_child() process exited with rc not in 0,2,3,4). Not sure - # why, and I'd have to hack qmail to investigate further, so it's - # easier to just wait a second before yanking the message out of new/ - - reactor.callLater(0.1, self.poll) - - - def stopService(self): - if self.dnotify: - self.dnotify.remove() - self.dnotify = None - if self.timerService is not None: - self.timerService.disownServiceParent() - self.timerService = None - return service.MultiService.stopService(self) - - @defer.inlineCallbacks - def poll(self): - try: - assert self.basedir - # see what's new - for f in self.files: - if not os.path.isfile(os.path.join(self.newdir, f)): - self.files.remove(f) - newfiles = [] - for f in os.listdir(self.newdir): - if not f in self.files: - newfiles.append(f) - self.files.extend(newfiles) - for n in newfiles: - try: - yield self.messageReceived(n) - except: - log.err(None, "while reading '%s' from maildir '%s':" % (n, self.basedir)) - except Exception: - log.err(None, "while polling maildir '%s':" % (self.basedir,)) - - def moveToCurDir(self, filename): - if runtime.platformType == "posix": - # open the file before moving it, because I'm afraid that once - # it's in cur/, someone might delete it at any moment - path = os.path.join(self.newdir, filename) - f = open(path, "r") - os.rename(os.path.join(self.newdir, filename), - os.path.join(self.curdir, filename)) - elif runtime.platformType == "win32": - # do this backwards under windows, because you can't move a file - # that somebody is holding open. This was causing a Permission - # Denied error on bear's win32-twisted1.3 buildslave. - os.rename(os.path.join(self.newdir, filename), - os.path.join(self.curdir, filename)) - path = os.path.join(self.curdir, filename) - f = open(path, "r") - - return f - - def messageReceived(self, filename): - raise NotImplementedError diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/misc.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/misc.py deleted file mode 100644 index b869a5d5..00000000 --- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/misc.py +++ /dev/null @@ -1,69 +0,0 @@ -# This file is part of Buildbot. Buildbot is free software: you can -# redistribute it and/or modify it under the terms of the GNU General Public -# License as published by the Free Software Foundation, version 2. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License along with -# this program; if not, write to the Free Software Foundation, Inc., 51 -# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Copyright Buildbot Team Members - -""" -Miscellaneous utilities; these should be imported from C{buildbot.util}, not -directly from this module. -""" - -from twisted.python import log -from twisted.internet import defer - -def deferredLocked(lock_or_attr): - def decorator(fn): - def wrapper(*args, **kwargs): - lock = lock_or_attr - if isinstance(lock, basestring): - lock = getattr(args[0], lock) - return lock.run(fn, *args, **kwargs) - return wrapper - return decorator - -class SerializedInvocation(object): - def __init__(self, method): - self.method = method - self.running = False - self.pending_deferreds = [] - - def __call__(self): - d = defer.Deferred() - self.pending_deferreds.append(d) - if not self.running: - self.start() - return d - - def start(self): - self.running = True - invocation_deferreds = self.pending_deferreds - self.pending_deferreds = [] - d = self.method() - d.addErrback(log.err, 'in invocation of %r' % (self.method,)) - - def notify_callers(_): - for d in invocation_deferreds: - d.callback(None) - d.addCallback(notify_callers) - - def next(_): - self.running = False - if self.pending_deferreds: - self.start() - else: - self._quiet() - d.addBoth(next) - - def _quiet(self): # hook for tests - pass - diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/netstrings.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/netstrings.py deleted file mode 100644 index 47ff0623..00000000 --- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/netstrings.py +++ /dev/null @@ -1,60 +0,0 @@ -# This file is part of Buildbot. Buildbot is free software: you can -# redistribute it and/or modify it under the terms of the GNU General Public -# License as published by the Free Software Foundation, version 2. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License along with -# this program; if not, write to the Free Software Foundation, Inc., 51 -# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Copyright Buildbot Team Members - -from twisted.protocols import basic -from zope.interface import implements -from twisted.internet.interfaces import IAddress, ITransport - -class NullAddress(object): - "an address for NullTransport" - implements(IAddress) - -class NullTransport(object): - "a do-nothing transport to make NetstringReceiver happy" - implements(ITransport) - def write(self, data): raise NotImplementedError - def writeSequence(self, data): raise NotImplementedError - def loseConnection(self): pass - def getPeer(self): - return NullAddress - def getHost(self): - return NullAddress - -class NetstringParser(basic.NetstringReceiver): - """ - Adapts the Twisted netstring support (which assumes it is on a socket) to - work on simple strings, too. Call the C{feed} method with arbitrary blocks - of data, and override the C{stringReceived} method to get called for each - embedded netstring. The default implementation collects the netstrings in - the list C{self.strings}. - """ - - def __init__(self): - # most of the complexity here is stubbing out the transport code so - # that Twisted-10.2.0 and higher believes that this is a valid protocol - self.makeConnection(NullTransport()) - self.strings = [] - - def feed(self, data): - """ - """ - self.dataReceived(data) - # dataReceived handles errors unusually quietly! - if self.brokenPeer: - raise basic.NetstringParseError - - def stringReceived(self, string): - self.strings.append(string) - diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/sautils.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/sautils.py deleted file mode 100644 index d05cc3da..00000000 --- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/sautils.py +++ /dev/null @@ -1,42 +0,0 @@ -# This file is part of Buildbot. Buildbot is free software: you can -# redistribute it and/or modify it under the terms of the GNU General Public -# License as published by the Free Software Foundation, version 2. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License along with -# this program; if not, write to the Free Software Foundation, Inc., 51 -# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Copyright Buildbot Team Members - -import sqlalchemy as sa -from sqlalchemy.ext import compiler -from sqlalchemy.sql.expression import Executable, ClauseElement - -# from http://www.sqlalchemy.org/docs/core/compiler.html#compiling-sub-elements-of-a-custom-expression-construct - -class InsertFromSelect(Executable, ClauseElement): - def __init__(self, table, select): - self.table = table - self.select = select - -@compiler.compiles(InsertFromSelect) -def _visit_insert_from_select(element, compiler, **kw): - return "INSERT INTO %s %s" % ( - compiler.process(element.table, asfrom=True), - compiler.process(element.select) - ) - -def sa_version(): - if hasattr(sa, '__version__'): - def tryint(s): - try: - return int(s) - except: - return -1 - return tuple(map(tryint, sa.__version__.split('.'))) - return (0,0,0) # "it's old" diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/state.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/state.py deleted file mode 100644 index 509f6527..00000000 --- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/state.py +++ /dev/null @@ -1,26 +0,0 @@ -from twisted.internet import defer - -class StateMixin(object): - ## state management - - _objectid = None - - @defer.inlineCallbacks - def getState(self, *args, **kwargs): - # get the objectid, if not known - if self._objectid is None: - self._objectid = yield self.master.db.state.getObjectId(self.name, - self.__class__.__name__) - - rv = yield self.master.db.state.getState(self._objectid, *args, - **kwargs) - defer.returnValue(rv) - - @defer.inlineCallbacks - def setState(self, key, value): - # get the objectid, if not known - if self._objectid is None: - self._objectid = yield self.master.db.state.getObjectId(self.name, - self.__class__.__name__) - - yield self.master.db.state.setState(self._objectid, key, value) diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/subscription.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/subscription.py deleted file mode 100644 index 85ed7de4..00000000 --- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/subscription.py +++ /dev/null @@ -1,48 +0,0 @@ -# This file is part of Buildbot. Buildbot is free software: you can -# redistribute it and/or modify it under the terms of the GNU General Public -# License as published by the Free Software Foundation, version 2. -# -# This program is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more -# details. -# -# You should have received a copy of the GNU General Public License along with -# this program; if not, write to the Free Software Foundation, Inc., 51 -# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Copyright Buildbot Team Members - -from twisted.python import failure, log - -class SubscriptionPoint(object): - def __init__(self, name): - self.name = name - self.subscriptions = set() - - def __str__(self): - return "<SubscriptionPoint '%s'>" % self.name - - def subscribe(self, callback): - sub = Subscription(self, callback) - self.subscriptions.add(sub) - return sub - - def deliver(self, *args, **kwargs): - for sub in list(self.subscriptions): - try: - sub.callback(*args, **kwargs) - except: - log.err(failure.Failure(), - 'while invoking callback %s to %s' % (sub.callback, self)) - - def _unsubscribe(self, subscription): - self.subscriptions.remove(subscription) - -class Subscription(object): - def __init__(self, subpt, callback): - self.subpt = subpt - self.callback = callback - - def unsubscribe(self): - self.subpt._unsubscribe(self) |