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()