Mercurial > kallithea
changeset 6208:f4d128af1a01
compat: drop unnecessary wrappers for old Python versions
Made unnecessary by other cleanup or upgrade to Python 2.6+.
author | Mads Kiilerich <madski@unity3d.com> |
---|---|
date | Mon, 12 Sep 2016 17:41:19 +0200 |
parents | 46db3368c2ae |
children | 41e70d120a5e |
files | kallithea/controllers/api/__init__.py kallithea/controllers/summary.py kallithea/lib/auth_modules/__init__.py kallithea/lib/compat.py kallithea/lib/vcs/subprocessio.py kallithea/lib/vcs/utils/compat.py |
diffstat | 6 files changed, 32 insertions(+), 530 deletions(-) [+] |
line wrap: on
line diff
--- a/kallithea/controllers/api/__init__.py Mon Sep 12 17:41:19 2016 +0200 +++ b/kallithea/controllers/api/__init__.py Mon Sep 12 17:41:19 2016 +0200 @@ -30,6 +30,7 @@ import types import traceback import time +import itertools from paste.response import replace_header from pylons.controllers import WSGIController @@ -38,7 +39,7 @@ 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 @@ 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
--- a/kallithea/controllers/summary.py Mon Sep 12 17:41:19 2016 +0200 +++ b/kallithea/controllers/summary.py Mon Sep 12 17:41:19 2016 +0200 @@ -28,6 +28,7 @@ import traceback import calendar import logging +import itertools from time import mktime from datetime import timedelta, date @@ -37,7 +38,6 @@ 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 @@ 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])]
--- a/kallithea/lib/auth_modules/__init__.py Mon Sep 12 17:41:19 2016 +0200 +++ b/kallithea/lib/auth_modules/__init__.py Mon Sep 12 17:41:19 2016 +0200 @@ -17,8 +17,8 @@ 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
--- a/kallithea/lib/compat.py Mon Sep 12 17:41:19 2016 +0200 +++ b/kallithea/lib/compat.py Mon Sep 12 17:41:19 2016 +0200 @@ -27,10 +27,9 @@ """ +import sys import os import functools -import importlib -from kallithea import __py_version__, is_windows #============================================================================== # json @@ -40,37 +39,18 @@ # 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 @@ #============================================================================== # 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 @@ 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
--- a/kallithea/lib/vcs/subprocessio.py Mon Sep 12 17:41:19 2016 +0200 +++ b/kallithea/lib/vcs/subprocessio.py Mon Sep 12 17:41:19 2016 +0200 @@ -24,10 +24,11 @@ """ import os import subprocess -from kallithea.lib.vcs.utils.compat import deque, Event, Thread, _bytes, _bytearray +import collections +import threading -class StreamFeeder(Thread): +class StreamFeeder(threading.Thread): """ Normal writing into pipe-like is blocking once the buffer is filled. This thread allows a thread to seep data from a file-like into a pipe @@ -39,9 +40,9 @@ super(StreamFeeder, self).__init__() self.daemon = True filelike = False - self.bytes = _bytes() - if type(source) in (type(''), _bytes, _bytearray): # string-like - self.bytes = _bytes(source) + self.bytes = bytes() + if type(source) in (type(''), bytes, bytearray): # string-like + self.bytes = bytes(source) else: # can be either file pointer or file-like if type(source) in (int, long): # file pointer it is ## converting file descriptor (int) stdin into file-like @@ -71,7 +72,7 @@ return self.readiface -class InputStreamChunker(Thread): +class InputStreamChunker(threading.Thread): def __init__(self, source, target, buffer_size, chunk_size): super(InputStreamChunker, self).__init__() @@ -83,16 +84,16 @@ self.chunk_count_max = int(buffer_size / chunk_size) + 1 self.chunk_size = chunk_size - self.data_added = Event() + self.data_added = threading.Event() self.data_added.clear() - self.keep_reading = Event() + self.keep_reading = threading.Event() self.keep_reading.set() - self.EOF = Event() + self.EOF = threading.Event() self.EOF.clear() - self.go = Event() + self.go = threading.Event() self.go.set() def stop(self): @@ -163,7 +164,7 @@ else: maxlen = None - self.data = deque(starting_values, maxlen) + self.data = collections.deque(starting_values, maxlen) self.worker = InputStreamChunker(source, self.data, buffer_size, chunk_size) if starting_values: @@ -183,7 +184,7 @@ self.worker.data_added.wait(0.2) if len(self.data): self.worker.keep_reading.set() - return _bytes(self.data.popleft()) + return bytes(self.data.popleft()) elif self.worker.EOF.is_set(): raise StopIteration @@ -233,7 +234,7 @@ Iterator might have done reading from underlying source, but the read chunks might still be available for serving through .next() method. - :returns: An Event class instance. + :returns: An threading.Event class instance. """ return self.worker.EOF
--- a/kallithea/lib/vcs/utils/compat.py Mon Sep 12 17:41:19 2016 +0200 +++ b/kallithea/lib/vcs/utils/compat.py Mon Sep 12 17:41:19 2016 +0200 @@ -4,6 +4,7 @@ Those utilities may be deleted once ``vcs`` stops support for older Python versions. """ + import sys import array @@ -11,310 +12,3 @@ 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 "<Condition(%s, %d)>" % (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()