| Index: third_party/logilab/common/compat.py
 | 
| diff --git a/third_party/logilab/common/compat.py b/third_party/logilab/common/compat.py
 | 
| index f2eb5905601add2c30207278883b69d67934c3e1..8983ece98915f29254296326d2e127fc8adc9e24 100644
 | 
| --- a/third_party/logilab/common/compat.py
 | 
| +++ b/third_party/logilab/common/compat.py
 | 
| @@ -26,6 +26,7 @@ See another compatibility snippets from other projects:
 | 
|      :mod:`unittest2.compatibility`
 | 
|  """
 | 
|  
 | 
| +from __future__ import generators
 | 
|  
 | 
|  __docformat__ = "restructuredtext en"
 | 
|  
 | 
| @@ -34,8 +35,7 @@ import sys
 | 
|  import types
 | 
|  from warnings import warn
 | 
|  
 | 
| -# not used here, but imported to preserve API
 | 
| -from six.moves import builtins
 | 
| +import __builtin__ as builtins # 2to3 will tranform '__builtin__' to 'builtins'
 | 
|  
 | 
|  if sys.version_info < (3, 0):
 | 
|      str_to_bytes = str
 | 
| @@ -51,6 +51,15 @@ else:
 | 
|      def str_encode(string, encoding):
 | 
|          return str(string)
 | 
|  
 | 
| +# XXX callable built-in seems back in all python versions
 | 
| +try:
 | 
| +    callable = builtins.callable
 | 
| +except AttributeError:
 | 
| +    from collections import Callable
 | 
| +    def callable(something):
 | 
| +        return isinstance(something, Callable)
 | 
| +    del Callable
 | 
| +
 | 
|  # See also http://bugs.python.org/issue11776
 | 
|  if sys.version_info[0] == 3:
 | 
|      def method_type(callable, instance, klass):
 | 
| @@ -60,6 +69,11 @@ else:
 | 
|      # alias types otherwise
 | 
|      method_type = types.MethodType
 | 
|  
 | 
| +if sys.version_info < (3, 0):
 | 
| +    raw_input = raw_input
 | 
| +else:
 | 
| +    raw_input = input
 | 
| +
 | 
|  # Pythons 2 and 3 differ on where to get StringIO
 | 
|  if sys.version_info < (3, 0):
 | 
|      from cStringIO import StringIO
 | 
| @@ -70,9 +84,160 @@ else:
 | 
|      from io import FileIO, BytesIO, StringIO
 | 
|      from imp import reload
 | 
|  
 | 
| +# Where do pickles come from?
 | 
| +try:
 | 
| +    import cPickle as pickle
 | 
| +except ImportError:
 | 
| +    import pickle
 | 
| +
 | 
|  from logilab.common.deprecation import deprecated
 | 
|  
 | 
| -# Other projects import these from here, keep providing them for
 | 
| -# backwards compat
 | 
| -any = deprecated('use builtin "any"')(any)
 | 
| -all = deprecated('use builtin "all"')(all)
 | 
| +from itertools import izip, chain, imap
 | 
| +if sys.version_info < (3, 0):# 2to3 will remove the imports
 | 
| +    izip = deprecated('izip exists in itertools since py2.3')(izip)
 | 
| +    imap = deprecated('imap exists in itertools since py2.3')(imap)
 | 
| +chain = deprecated('chain exists in itertools since py2.3')(chain)
 | 
| +
 | 
| +sum = deprecated('sum exists in builtins since py2.3')(sum)
 | 
| +enumerate = deprecated('enumerate exists in builtins since py2.3')(enumerate)
 | 
| +frozenset = deprecated('frozenset exists in builtins since py2.4')(frozenset)
 | 
| +reversed = deprecated('reversed exists in builtins since py2.4')(reversed)
 | 
| +sorted = deprecated('sorted exists in builtins since py2.4')(sorted)
 | 
| +max = deprecated('max exists in builtins since py2.4')(max)
 | 
| +
 | 
| +
 | 
| +# Python2.5 builtins
 | 
| +try:
 | 
| +    any = any
 | 
| +    all = all
 | 
| +except NameError:
 | 
| +    def any(iterable):
 | 
| +        """any(iterable) -> bool
 | 
| +
 | 
| +        Return True if bool(x) is True for any x in the iterable.
 | 
| +        """
 | 
| +        for elt in iterable:
 | 
| +            if elt:
 | 
| +                return True
 | 
| +        return False
 | 
| +
 | 
| +    def all(iterable):
 | 
| +        """all(iterable) -> bool
 | 
| +
 | 
| +        Return True if bool(x) is True for all values x in the iterable.
 | 
| +        """
 | 
| +        for elt in iterable:
 | 
| +            if not elt:
 | 
| +                return False
 | 
| +        return True
 | 
| +
 | 
| +
 | 
| +# Python2.5 subprocess added functions and exceptions
 | 
| +try:
 | 
| +    from subprocess import Popen
 | 
| +except ImportError:
 | 
| +    # gae or python < 2.3
 | 
| +
 | 
| +    class CalledProcessError(Exception):
 | 
| +        """This exception is raised when a process run by check_call() returns
 | 
| +        a non-zero exit status.  The exit status will be stored in the
 | 
| +        returncode attribute."""
 | 
| +        def __init__(self, returncode, cmd):
 | 
| +            self.returncode = returncode
 | 
| +            self.cmd = cmd
 | 
| +        def __str__(self):
 | 
| +            return "Command '%s' returned non-zero exit status %d" % (self.cmd,
 | 
| +    self.returncode)
 | 
| +
 | 
| +    def call(*popenargs, **kwargs):
 | 
| +        """Run command with arguments.  Wait for command to complete, then
 | 
| +        return the returncode attribute.
 | 
| +
 | 
| +        The arguments are the same as for the Popen constructor.  Example:
 | 
| +
 | 
| +        retcode = call(["ls", "-l"])
 | 
| +        """
 | 
| +        # workaround: subprocess.Popen(cmd, stdout=sys.stdout) fails
 | 
| +        # see http://bugs.python.org/issue1531862
 | 
| +        if "stdout" in kwargs:
 | 
| +            fileno = kwargs.get("stdout").fileno()
 | 
| +            del kwargs['stdout']
 | 
| +            return Popen(stdout=os.dup(fileno), *popenargs, **kwargs).wait()
 | 
| +        return Popen(*popenargs, **kwargs).wait()
 | 
| +
 | 
| +    def check_call(*popenargs, **kwargs):
 | 
| +        """Run command with arguments.  Wait for command to complete.  If
 | 
| +        the exit code was zero then return, otherwise raise
 | 
| +        CalledProcessError.  The CalledProcessError object will have the
 | 
| +        return code in the returncode attribute.
 | 
| +
 | 
| +        The arguments are the same as for the Popen constructor.  Example:
 | 
| +
 | 
| +        check_call(["ls", "-l"])
 | 
| +        """
 | 
| +        retcode = call(*popenargs, **kwargs)
 | 
| +        cmd = kwargs.get("args")
 | 
| +        if cmd is None:
 | 
| +            cmd = popenargs[0]
 | 
| +        if retcode:
 | 
| +            raise CalledProcessError(retcode, cmd)
 | 
| +        return retcode
 | 
| +
 | 
| +try:
 | 
| +    from os.path import relpath
 | 
| +except ImportError: # python < 2.6
 | 
| +    from os.path import curdir, abspath, sep, commonprefix, pardir, join
 | 
| +    def relpath(path, start=curdir):
 | 
| +        """Return a relative version of a path"""
 | 
| +
 | 
| +        if not path:
 | 
| +            raise ValueError("no path specified")
 | 
| +
 | 
| +        start_list = abspath(start).split(sep)
 | 
| +        path_list = abspath(path).split(sep)
 | 
| +
 | 
| +        # Work out how much of the filepath is shared by start and path.
 | 
| +        i = len(commonprefix([start_list, path_list]))
 | 
| +
 | 
| +        rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
 | 
| +        if not rel_list:
 | 
| +            return curdir
 | 
| +        return join(*rel_list)
 | 
| +
 | 
| +
 | 
| +# XXX don't know why tests don't pass if I don't do that :
 | 
| +_real_set, set = set, deprecated('set exists in builtins since py2.4')(set)
 | 
| +if (2, 5) <= sys.version_info[:2]:
 | 
| +    InheritableSet = _real_set
 | 
| +else:
 | 
| +    class InheritableSet(_real_set):
 | 
| +        """hacked resolving inheritancy issue from old style class in 2.4"""
 | 
| +        def __new__(cls, *args, **kwargs):
 | 
| +            if args:
 | 
| +                new_args = (args[0], )
 | 
| +            else:
 | 
| +                new_args = ()
 | 
| +            obj = _real_set.__new__(cls, *new_args)
 | 
| +            obj.__init__(*args, **kwargs)
 | 
| +            return obj
 | 
| +
 | 
| +# XXX shouldn't we remove this and just let 2to3 do his job ?
 | 
| +# range or xrange?
 | 
| +try:
 | 
| +    range = xrange
 | 
| +except NameError:
 | 
| +    range = range
 | 
| +
 | 
| +# ConfigParser was renamed to the more-standard configparser
 | 
| +try:
 | 
| +    import configparser
 | 
| +except ImportError:
 | 
| +    import ConfigParser as configparser
 | 
| +
 | 
| +try:
 | 
| +    import json
 | 
| +except ImportError:
 | 
| +    try:
 | 
| +        import simplejson as json
 | 
| +    except ImportError:
 | 
| +        json = None
 | 
| 
 |