# HG changeset patch # User Mads Kiilerich # Date 2016-09-12 17:41:19 # Node ID f4d128af1a01a9b8b0e26f1c1c5e7dfd3e747839 # Parent 46db3368c2aeb8fbd1d8aa9a7e5196f523c1149c compat: drop unnecessary wrappers for old Python versions Made unnecessary by other cleanup or upgrade to Python 2.6+. diff --git a/kallithea/controllers/api/__init__.py b/kallithea/controllers/api/__init__.py --- a/kallithea/controllers/api/__init__.py +++ b/kallithea/controllers/api/__init__.py @@ -30,6 +30,7 @@ import logging import types import traceback import time +import itertools from paste.response import replace_header from pylons.controllers import WSGIController @@ -38,7 +39,7 @@ from webob.exc import HTTPError from kallithea.model.db import User from kallithea.model import meta -from kallithea.lib.compat import izip_longest, json +from kallithea.lib.compat import json from kallithea.lib.auth import AuthUser from kallithea.lib.base import _get_ip_addr as _get_ip, _get_access_path from kallithea.lib.utils2 import safe_unicode, safe_str @@ -183,8 +184,8 @@ class JSONRPCController(WSGIController): default_empty = types.NotImplementedType # kw arguments required by this method - func_kwargs = dict(izip_longest(reversed(arglist), reversed(defaults), - fillvalue=default_empty)) + func_kwargs = dict(itertools.izip_longest(reversed(arglist), reversed(defaults), + fillvalue=default_empty)) # this is little trick to inject logged in user for # perms decorators to work they expect the controller class to have diff --git a/kallithea/controllers/summary.py b/kallithea/controllers/summary.py --- a/kallithea/controllers/summary.py +++ b/kallithea/controllers/summary.py @@ -28,6 +28,7 @@ Original author and date, and relevant c import traceback import calendar import logging +import itertools from time import mktime from datetime import timedelta, date @@ -37,7 +38,6 @@ from webob.exc import HTTPBadRequest from beaker.cache import cache_region, region_invalidate -from kallithea.lib.compat import product from kallithea.lib.vcs.exceptions import ChangesetError, EmptyRepositoryError, \ NodeDoesNotExistError from kallithea.config.conf import ALL_READMES, ALL_EXTS, LANGUAGES_EXTENSIONS_MAP @@ -57,7 +57,7 @@ from kallithea.controllers.changelog imp log = logging.getLogger(__name__) README_FILES = [''.join([x[0][0], x[1][0]]) for x in - sorted(list(product(ALL_READMES, ALL_EXTS)), + sorted(list(itertools.product(ALL_READMES, ALL_EXTS)), key=lambda y:y[0][1] + y[1][1])] diff --git a/kallithea/lib/auth_modules/__init__.py b/kallithea/lib/auth_modules/__init__.py --- a/kallithea/lib/auth_modules/__init__.py +++ b/kallithea/lib/auth_modules/__init__.py @@ -17,8 +17,8 @@ Authentication modules import logging import traceback +import importlib -from kallithea.lib.compat import importlib from kallithea.lib.utils2 import str2bool from kallithea.lib.compat import formatted_json, hybrid_property from kallithea.lib.auth import PasswordGenerator diff --git a/kallithea/lib/compat.py b/kallithea/lib/compat.py --- a/kallithea/lib/compat.py +++ b/kallithea/lib/compat.py @@ -27,10 +27,9 @@ Original author and date, and relevant c """ +import sys import os import functools -import importlib -from kallithea import __py_version__, is_windows #============================================================================== # json @@ -40,37 +39,18 @@ from kallithea.lib.ext_json import json # alias for formatted json formatted_json = functools.partial(json.dumps, indent=4, sort_keys=True) -if __py_version__ >= (2, 7): + +#============================================================================== +# unittest +#============================================================================== +if sys.version_info >= (2, 7): import unittest else: import unittest2 as unittest -#============================================================================== -# izip_longest -#============================================================================== -try: - from itertools import izip_longest -except ImportError: - import itertools - - def izip_longest(*args, **kwds): - 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 - #============================================================================== -# OrderedDict +# OrderedDict - Python 2.7 could perhaps use collections.OrderedDict #============================================================================== # Python Software Foundation License @@ -377,13 +357,13 @@ from sqlalchemy.util import OrderedSet #============================================================================== # Hybrid property/method #============================================================================== -from sqlalchemy.ext.hybrid import hybrid_method, hybrid_property +from sqlalchemy.ext.hybrid import hybrid_property #============================================================================== -# kill FUNCTIONS +# kill #============================================================================== -if is_windows: +if os.name == 'nt': # Windows import ctypes def kill(pid, sig): @@ -394,177 +374,3 @@ if is_windows: else: kill = os.kill - - -#============================================================================== -# itertools.product -#============================================================================== - -try: - from itertools import product -except ImportError: - def product(*args, **kwds): - # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy - # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111 - pools = map(tuple, args) * kwds.get('repeat', 1) - result = [[]] - for pool in pools: - result = [x + [y] for x in result for y in pool] - for prod in result: - yield tuple(prod) - - -#============================================================================== -# BytesIO -#============================================================================== - -try: - from io import BytesIO -except ImportError: - from cStringIO import StringIO as BytesIO - - -#============================================================================== -# bytes -#============================================================================== -if __py_version__ >= (2, 6): - _bytes = bytes -else: - # in py2.6 bytes is a synonym for str - _bytes = str - -if __py_version__ >= (2, 6): - _bytearray = bytearray -else: - import array - # no idea if this is correct but all integration tests are passing - # i think we never use bytearray anyway - _bytearray = array - - -#============================================================================== -# deque -#============================================================================== - -if __py_version__ >= (2, 6): - from collections import deque -else: - #need to implement our own deque with maxlen - class deque(object): - - def __init__(self, iterable=(), maxlen= -1): - if not hasattr(self, 'data'): - self.left = self.right = 0 - self.data = {} - self.maxlen = maxlen or -1 - self.extend(iterable) - - def append(self, x): - self.data[self.right] = x - self.right += 1 - if self.maxlen != -1 and len(self) > self.maxlen: - self.popleft() - - def appendleft(self, x): - self.left -= 1 - self.data[self.left] = x - if self.maxlen != -1 and len(self) > self.maxlen: - self.pop() - - def pop(self): - if self.left == self.right: - raise IndexError('cannot pop from empty deque') - self.right -= 1 - elem = self.data[self.right] - del self.data[self.right] - return elem - - def popleft(self): - if self.left == self.right: - raise IndexError('cannot pop from empty deque') - elem = self.data[self.left] - del self.data[self.left] - self.left += 1 - return elem - - def clear(self): - self.data.clear() - self.left = self.right = 0 - - def extend(self, iterable): - for elem in iterable: - self.append(elem) - - def extendleft(self, iterable): - for elem in iterable: - self.appendleft(elem) - - def rotate(self, n=1): - if self: - n %= len(self) - for i in xrange(n): - self.appendleft(self.pop()) - - def __getitem__(self, i): - if i < 0: - i += len(self) - try: - return self.data[i + self.left] - except KeyError: - raise IndexError - - def __setitem__(self, i, value): - if i < 0: - i += len(self) - try: - self.data[i + self.left] = value - except KeyError: - raise IndexError - - def __delitem__(self, i): - size = len(self) - if not (-size <= i < size): - raise IndexError - data = self.data - if i < 0: - i += size - for j in xrange(self.left + i, self.right - 1): - data[j] = data[j + 1] - self.pop() - - def __len__(self): - return self.right - self.left - - def __cmp__(self, other): - if type(self) != type(other): - return cmp(type(self), type(other)) - return cmp(list(self), list(other)) - - def __repr__(self, _track=None): - _track = _track or [] - if id(self) in _track: - return '...' - _track.append(id(self)) - r = 'deque(%r, maxlen=%s)' % (list(self), self.maxlen) - _track.remove(id(self)) - return r - - def __getstate__(self): - return (tuple(self),) - - def __setstate__(self, s): - self.__init__(s[0]) - - def __hash__(self): - raise TypeError - - def __copy__(self): - return self.__class__(self) - - def __deepcopy__(self, memo=None): - from copy import deepcopy - memo = memo or {} - result = self.__class__() - memo[id(self)] = result - result.__init__(deepcopy(tuple(self), memo)) - return result diff --git a/kallithea/lib/vcs/subprocessio.py b/kallithea/lib/vcs/subprocessio.py --- a/kallithea/lib/vcs/subprocessio.py +++ b/kallithea/lib/vcs/subprocessio.py @@ -24,10 +24,11 @@ If not, see = (2, 7): unittest = __import__('unittest') else: unittest = __import__('unittest2') - - -if sys.version_info >= (2, 6): - _bytes = bytes -else: - # in py2.6 bytes is a synonym for str - _bytes = str - -if sys.version_info >= (2, 6): - _bytearray = bytearray -else: - # no idea if this is correct but all integration tests are passing - # i think we never use bytearray anyway - _bytearray = array - -if sys.version_info >= (2, 6): - from collections import deque -else: - #need to implement our own deque with maxlen - class deque(object): - - def __init__(self, iterable=(), maxlen= -1): - if not hasattr(self, 'data'): - self.left = self.right = 0 - self.data = {} - self.maxlen = maxlen or -1 - self.extend(iterable) - - def append(self, x): - self.data[self.right] = x - self.right += 1 - if self.maxlen != -1 and len(self) > self.maxlen: - self.popleft() - - def appendleft(self, x): - self.left -= 1 - self.data[self.left] = x - if self.maxlen != -1 and len(self) > self.maxlen: - self.pop() - - def pop(self): - if self.left == self.right: - raise IndexError('cannot pop from empty deque') - self.right -= 1 - elem = self.data[self.right] - del self.data[self.right] - return elem - - def popleft(self): - if self.left == self.right: - raise IndexError('cannot pop from empty deque') - elem = self.data[self.left] - del self.data[self.left] - self.left += 1 - return elem - - def clear(self): - self.data.clear() - self.left = self.right = 0 - - def extend(self, iterable): - for elem in iterable: - self.append(elem) - - def extendleft(self, iterable): - for elem in iterable: - self.appendleft(elem) - - def rotate(self, n=1): - if self: - n %= len(self) - for i in xrange(n): - self.appendleft(self.pop()) - - def __getitem__(self, i): - if i < 0: - i += len(self) - try: - return self.data[i + self.left] - except KeyError: - raise IndexError - - def __setitem__(self, i, value): - if i < 0: - i += len(self) - try: - self.data[i + self.left] = value - except KeyError: - raise IndexError - - def __delitem__(self, i): - size = len(self) - if not (-size <= i < size): - raise IndexError - data = self.data - if i < 0: - i += size - for j in xrange(self.left + i, self.right - 1): - data[j] = data[j + 1] - self.pop() - - def __len__(self): - return self.right - self.left - - def __cmp__(self, other): - if type(self) != type(other): - return cmp(type(self), type(other)) - return cmp(list(self), list(other)) - - def __repr__(self, _track=None): - _track = _track or [] - if id(self) in _track: - return '...' - _track.append(id(self)) - r = 'deque(%r, maxlen=%s)' % (list(self), self.maxlen) - _track.remove(id(self)) - return r - - def __getstate__(self): - return (tuple(self),) - - def __setstate__(self, s): - self.__init__(s[0]) - - def __hash__(self): - raise TypeError - - def __copy__(self): - return self.__class__(self) - - def __deepcopy__(self, memo=None): - from copy import deepcopy - memo = memo or {} - result = self.__class__() - memo[id(self)] = result - result.__init__(deepcopy(tuple(self), memo)) - return result - - -#============================================================================== -# threading.Event -#============================================================================== - -if sys.version_info >= (2, 6): - from threading import Event, Thread -else: - from threading import _Verbose, Lock, Thread, _time, \ - _allocate_lock, RLock, _sleep - - def Condition(*args, **kwargs): - return _Condition(*args, **kwargs) - - class _Condition(_Verbose): - - def __init__(self, lock=None, verbose=None): - _Verbose.__init__(self, verbose) - if lock is None: - lock = RLock() - self.__lock = lock - # Export the lock's acquire() and release() methods - self.acquire = lock.acquire - self.release = lock.release - # If the lock defines _release_save() and/or _acquire_restore(), - # these override the default implementations (which just call - # release() and acquire() on the lock). Ditto for _is_owned(). - try: - self._release_save = lock._release_save - except AttributeError: - pass - try: - self._acquire_restore = lock._acquire_restore - except AttributeError: - pass - try: - self._is_owned = lock._is_owned - except AttributeError: - pass - self.__waiters = [] - - def __enter__(self): - return self.__lock.__enter__() - - def __exit__(self, *args): - return self.__lock.__exit__(*args) - - def __repr__(self): - return "" % (self.__lock, len(self.__waiters)) - - def _release_save(self): - self.__lock.release() # No state to save - - def _acquire_restore(self, x): - self.__lock.acquire() # Ignore saved state - - def _is_owned(self): - # Return True if lock is owned by current_thread. - # This method is called only if __lock doesn't have _is_owned(). - if self.__lock.acquire(0): - self.__lock.release() - return False - else: - return True - - def wait(self, timeout=None): - if not self._is_owned(): - raise RuntimeError("cannot wait on un-acquired lock") - waiter = _allocate_lock() - waiter.acquire() - self.__waiters.append(waiter) - saved_state = self._release_save() - try: # restore state no matter what (e.g., KeyboardInterrupt) - if timeout is None: - waiter.acquire() - if __debug__: - self._note("%s.wait(): got it", self) - else: - # Balancing act: We can't afford a pure busy loop, so we - # have to sleep; but if we sleep the whole timeout time, - # we'll be unresponsive. The scheme here sleeps very - # little at first, longer as time goes on, but never longer - # than 20 times per second (or the timeout time remaining). - endtime = _time() + timeout - delay = 0.0005 # 500 us -> initial delay of 1 ms - while True: - gotit = waiter.acquire(0) - if gotit: - break - remaining = endtime - _time() - if remaining <= 0: - break - delay = min(delay * 2, remaining, .05) - _sleep(delay) - if not gotit: - if __debug__: - self._note("%s.wait(%s): timed out", self, timeout) - try: - self.__waiters.remove(waiter) - except ValueError: - pass - else: - if __debug__: - self._note("%s.wait(%s): got it", self, timeout) - finally: - self._acquire_restore(saved_state) - - def notify(self, n=1): - if not self._is_owned(): - raise RuntimeError("cannot notify on un-acquired lock") - __waiters = self.__waiters - waiters = __waiters[:n] - if not waiters: - if __debug__: - self._note("%s.notify(): no waiters", self) - return - self._note("%s.notify(): notifying %d waiter%s", self, n, - n != 1 and "s" or "") - for waiter in waiters: - waiter.release() - try: - __waiters.remove(waiter) - except ValueError: - pass - - def notifyAll(self): - self.notify(len(self.__waiters)) - - notify_all = notifyAll - - def Event(*args, **kwargs): - return _Event(*args, **kwargs) - - class _Event(_Verbose): - - # After Tim Peters' event class (without is_posted()) - - def __init__(self, verbose=None): - _Verbose.__init__(self, verbose) - self.__cond = Condition(Lock()) - self.__flag = False - - def isSet(self): - return self.__flag - - is_set = isSet - - def set(self): - self.__cond.acquire() - try: - self.__flag = True - self.__cond.notify_all() - finally: - self.__cond.release() - - def clear(self): - self.__cond.acquire() - try: - self.__flag = False - finally: - self.__cond.release() - - def wait(self, timeout=None): - self.__cond.acquire() - try: - if not self.__flag: - self.__cond.wait(timeout) - finally: - self.__cond.release()