Package logilab :: Package common :: Module compat
[frames] | no frames]

Source Code for Module logilab.common.compat

  1  # pylint: disable=E0601,W0622,W0611 
  2  # copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. 
  3  # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr 
  4  # 
  5  # This file is part of logilab-common. 
  6  # 
  7  # logilab-common is free software: you can redistribute it and/or modify it under 
  8  # the terms of the GNU Lesser General Public License as published by the Free 
  9  # Software Foundation, either version 2.1 of the License, or (at your option) any 
 10  # later version. 
 11  # 
 12  # logilab-common is distributed in the hope that it will be useful, but WITHOUT 
 13  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
 14  # FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more 
 15  # details. 
 16  # 
 17  # You should have received a copy of the GNU Lesser General Public License along 
 18  # with logilab-common.  If not, see <http://www.gnu.org/licenses/>. 
 19  """Wrappers around some builtins introduced in python 2.3, 2.4 and 
 20  2.5, making them available in for earlier versions of python. 
 21   
 22  See another compatibility snippets from other projects: 
 23       
 24      :mod:`lib2to3.fixes` 
 25      :mod:`coverage.backward` 
 26      :mod:`unittest2.compatibility` 
 27  """ 
 28   
 29  from __future__ import generators 
 30   
 31  __docformat__ = "restructuredtext en" 
 32   
 33  import os 
 34  import sys 
 35  from warnings import warn 
 36   
 37  import __builtin__ as builtins # 2to3 will tranform '__builtin__' to 'builtins' 
 38   
 39  if sys.version_info < (3, 0): 
 40      str_to_bytes = str 
41 - def str_encode(string, encoding):
42 if isinstance(string, unicode): 43 return string.encode(encoding) 44 return str(string)
45 else:
46 - def str_to_bytes(string):
47 return str.encode(string)
48 # we have to ignore the encoding in py3k to be able to write a string into a 49 # TextIOWrapper or like object (which expect an unicode string)
50 - def str_encode(string, encoding):
51 return str(string)
52 53 # XXX shouldn't we remove this and just let 2to3 do his job ? 54 try: 55 callable = callable 56 except NameError:# callable removed from py3k 57 import collections
58 - def callable(something):
59 return isinstance(something, collections.Callable)
60 del collections 61 62 if sys.version_info < (3, 0): 63 raw_input = raw_input 64 else: 65 raw_input = input 66 67 # Pythons 2 and 3 differ on where to get StringIO 68 if sys.version_info < (3, 0): 69 from cStringIO import StringIO 70 FileIO = file 71 BytesIO = StringIO 72 reload = reload 73 else: 74 from io import FileIO, BytesIO, StringIO 75 from imp import reload 76 77 # Where do pickles come from? 78 try: 79 import cPickle as pickle 80 except ImportError: 81 import pickle 82 83 from logilab.common.deprecation import deprecated 84 85 from itertools import izip, chain, imap 86 if sys.version_info < (3, 0):# 2to3 will remove the imports 87 izip = deprecated('izip exists in itertools since py2.3')(izip) 88 imap = deprecated('imap exists in itertools since py2.3')(imap) 89 chain = deprecated('chain exists in itertools since py2.3')(chain) 90 91 sum = deprecated('sum exists in builtins since py2.3')(sum) 92 enumerate = deprecated('enumerate exists in builtins since py2.3')(enumerate) 93 frozenset = deprecated('frozenset exists in builtins since py2.4')(frozenset) 94 reversed = deprecated('reversed exists in builtins since py2.4')(reversed) 95 sorted = deprecated('sorted exists in builtins since py2.4')(sorted) 96 max = deprecated('max exists in builtins since py2.4')(max) 97 98 99 # Python2.5 builtins 100 try: 101 any = any 102 all = all 103 except NameError:
104 - def any(iterable):
105 """any(iterable) -> bool 106 107 Return True if bool(x) is True for any x in the iterable. 108 """ 109 for elt in iterable: 110 if elt: 111 return True 112 return False
113
114 - def all(iterable):
115 """all(iterable) -> bool 116 117 Return True if bool(x) is True for all values x in the iterable. 118 """ 119 for elt in iterable: 120 if not elt: 121 return False 122 return True
123 124 125 # Python2.5 subprocess added functions and exceptions 126 try: 127 from subprocess import Popen 128 except ImportError: 129 # gae or python < 2.3 130
131 - class CalledProcessError(Exception):
132 """This exception is raised when a process run by check_call() returns 133 a non-zero exit status. The exit status will be stored in the 134 returncode attribute."""
135 - def __init__(self, returncode, cmd):
136 self.returncode = returncode 137 self.cmd = cmd
138 - def __str__(self):
139 return "Command '%s' returned non-zero exit status %d" % (self.cmd, 140 self.returncode)
141
142 - def call(*popenargs, **kwargs):
143 """Run command with arguments. Wait for command to complete, then 144 return the returncode attribute. 145 146 The arguments are the same as for the Popen constructor. Example: 147 148 retcode = call(["ls", "-l"]) 149 """ 150 # workaround: subprocess.Popen(cmd, stdout=sys.stdout) fails 151 # see http://bugs.python.org/issue1531862 152 if "stdout" in kwargs: 153 fileno = kwargs.get("stdout").fileno() 154 del kwargs['stdout'] 155 return Popen(stdout=os.dup(fileno), *popenargs, **kwargs).wait() 156 return Popen(*popenargs, **kwargs).wait()
157
158 - def check_call(*popenargs, **kwargs):
159 """Run command with arguments. Wait for command to complete. If 160 the exit code was zero then return, otherwise raise 161 CalledProcessError. The CalledProcessError object will have the 162 return code in the returncode attribute. 163 164 The arguments are the same as for the Popen constructor. Example: 165 166 check_call(["ls", "-l"]) 167 """ 168 retcode = call(*popenargs, **kwargs) 169 cmd = kwargs.get("args") 170 if cmd is None: 171 cmd = popenargs[0] 172 if retcode: 173 raise CalledProcessError(retcode, cmd) 174 return retcode
175 176 try: 177 from os.path import relpath 178 except ImportError: # python < 2.6 179 from os.path import curdir, abspath, sep, commonprefix, pardir, join
180 - def relpath(path, start=curdir):
181 """Return a relative version of a path""" 182 183 if not path: 184 raise ValueError("no path specified") 185 186 start_list = abspath(start).split(sep) 187 path_list = abspath(path).split(sep) 188 189 # Work out how much of the filepath is shared by start and path. 190 i = len(commonprefix([start_list, path_list])) 191 192 rel_list = [pardir] * (len(start_list)-i) + path_list[i:] 193 if not rel_list: 194 return curdir 195 return join(*rel_list)
196 197 198 # XXX don't know why tests don't pass if I don't do that : 199 _real_set, set = set, deprecated('set exists in builtins since py2.4')(set) 200 if (2, 5) <= sys.version_info[:2]: 201 InheritableSet = _real_set 202 else:
203 - class InheritableSet(_real_set):
204 """hacked resolving inheritancy issue from old style class in 2.4"""
205 - def __new__(cls, *args, **kwargs):
206 if args: 207 new_args = (args[0], ) 208 else: 209 new_args = () 210 obj = _real_set.__new__(cls, *new_args) 211 obj.__init__(*args, **kwargs) 212 return obj
213 214 # XXX shouldn't we remove this and just let 2to3 do his job ? 215 # range or xrange? 216 try: 217 range = xrange 218 except NameError: 219 range = range 220 221 # ConfigParser was renamed to the more-standard configparser 222 try: 223 import configparser 224 except ImportError: 225 import ConfigParser as configparser 226 227 try: 228 import json 229 except ImportError: 230 try: 231 import simplejson as json 232 except ImportError: 233 json = None 234