Package Bio :: Package _py3k
[hide private]
[frames] | no frames]

Source Code for Package Bio._py3k

  1  # Copyright 2010-2013 by Peter Cock.  All rights reserved. 
  2  # This code is part of the Biopython distribution and governed by its 
  3  # license.  Please see the LICENSE file that should have been included 
  4  # as part of this package. 
  5  """Python 3 compatibility tools (PRIVATE). 
  6   
  7  We currently have lines like this under Python 2 in order 
  8  to use iterator based zip, map and filter: 
  9   
 10      from future_builtins import zip 
 11   
 12  There is no similar option for range yet, other than: 
 13   
 14      range = xrange 
 15      input = raw_input 
 16   
 17  or: 
 18   
 19      from __builtin__ import xrange as range 
 20      from __builtin__ import raw_input as input 
 21   
 22  Under Python 3 this imports need to be removed. Also, deliberate 
 23  importing of built in functions like open changes from Python 2: 
 24   
 25      from __builtin__ import open 
 26   
 27  to this under Python 3: 
 28   
 29      from builtins import open 
 30   
 31  Instead, we can do this under either Python 2 or 3: 
 32   
 33      from Bio._py3k import open 
 34      from Bio._py3k import zip 
 35   
 36  Once we drop support for Python 2, the whole of Bio._py3k will 
 37  go away. 
 38  """ 
 39  import sys 
 40   
 41  if sys.version_info[0] >= 3: 
 42      #Code for Python 3 
 43      from builtins import open, zip, map, filter, range, input 
 44   
 45      import codecs 
 46   
 47      #Lots of our Python 2 code uses isinstance(x, basestring) 
 48      #which after 2to3 becomes isinstance(x, str) 
 49      basestring = str 
 50      unicode = str 
 51   
 52      _bytes_to_string = lambda b: b.decode() # bytes to unicode string 
 53      _string_to_bytes = lambda s: s.encode() # unicode string to bytes 
 54   
55 - def _as_unicode(s):
56 """Turn byte string or unicode string into a unicode string.""" 57 if isinstance(s, str): 58 return s 59 #Assume it is a bytes string 60 #Note ISO-8859-1 aka Latin-1 preserves first 256 chars 61 return codecs.latin_1_decode(s)[0]
62
63 - def _as_bytes(s):
64 """Turn byte string or unicode string into a bytes string. 65 66 The Python 2 version returns a (byte) string. 67 """ 68 if isinstance(s, bytes): 69 return s 70 #Assume it is a unicode string 71 #Note ISO-8859-1 aka Latin-1 preserves first 256 chars 72 return codecs.latin_1_encode(s)[0]
73 74 _as_string = _as_unicode 75
76 - def _is_int_or_long(i):
77 """Check if the value is an integer. 78 79 Note there are no longs on Python 3. 80 """ 81 return isinstance(i, int)
82 83 import io 84
85 - def _binary_to_string_handle(handle):
86 """Treat a binary (bytes) handle like a text (unicode) handle.""" 87 #See also http://bugs.python.org/issue5628 88 #and http://bugs.python.org/issue13541 89 #and http://bugs.python.org/issue13464 which should be fixed in Python 3.3 90 #return io.TextIOWrapper(io.BufferedReader(handle)) 91 #TODO - Re-evaluate this workaround under Python 3.3 92 #(perhaps we will only need it on Python 3.1 and 3.2?) 93 class EvilHandleHack(object): 94 def __init__(self, handle): 95 self._handle = handle
96 97 def read(self, length=None): 98 return _as_string(self._handle.read(length)) 99 100 def readline(self): 101 return _as_string(self._handle.readline()) 102 103 def __iter__(self): 104 for line in self._handle: 105 yield _as_string(line) 106 107 def close(self): 108 return self._handle.close() 109 110 def seek(self, pos): 111 return self._handle.seek(pos) 112 113 def tell(self): 114 return self._handle.tell() 115 116 return EvilHandleHack(handle) 117 118 #On Python 3, can depend on OrderedDict being present: 119 from collections import OrderedDict 120 121 #On Python 3, this will be a unicode StringIO 122 from io import StringIO 123 124 #On Python 3 urllib, urllib2, and urlparse were merged: 125 from urllib.request import urlopen, Request, urlretrieve, urlparse 126 from urllib.parse import urlencode, quote 127 from urllib.error import HTTPError 128 129 else: 130 #Python 2 code 131 from __builtin__ import open, basestring, unicode 132 133 #Import Python3 like iterator functions: 134 from future_builtins import zip, map, filter 135 from __builtin__ import xrange as range 136 from __builtin__ import raw_input as input 137 138 _bytes_to_string = lambda b: b # bytes to string, i.e. do nothing 139 _string_to_bytes = lambda s: str(s) # str (or unicode) to bytes string 140
141 - def _as_unicode(s):
142 """Turn a (byte) string or a unicode string into a (byte) string.""" 143 #Will be changed by 2to3 to "isinstance(s, str)" but doesn't matter: 144 if isinstance(s, unicode): 145 return s 146 return s.decode()
147
148 - def _as_bytes(s):
149 """Turn a (byte) string or a unicode string into a (byte) string.""" 150 return str(s)
151 152 _as_string = _as_bytes 153
154 - def _is_int_or_long(i):
155 """Check if the value is an integer or long.""" 156 return isinstance(i, (int, long))
157
158 - def _binary_to_string_handle(handle):
159 """Treat a binary handle like a text handle.""" 160 return handle
161 162 try: 163 #Present on Python 2.7 164 from collections import OrderedDict 165 except ImportError: 166 try: 167 #Raymond Hettinger's backport available on PyPI 168 from ordereddict import OrderedDict 169 except ImportError: 170 #Use our bundled copy instead 171 from ._ordereddict import OrderedDict 172 173 # On Python 2 this will be a (bytes) string based handle. 174 # Note this doesn't work as it is unicode based: 175 # from io import StringIO 176 try: 177 from cStringIO import StringIO 178 except ImportError: 179 from StringIO import StringIO 180 181 #Under urllib.request on Python 3: 182 from urllib2 import urlopen, Request 183 from urllib import urlretrieve 184 from urlparse import urlparse 185 186 #Under urllib.parse on Python 3: 187 from urllib import urlencode, quote 188 189 #Under urllib.error on Python 3: 190 from urllib2 import HTTPError 191 192 193 if sys.platform == "win32": 194 # Can't use commands.getoutput on Python 2, Unix only/broken: 195 # http://bugs.python.org/issue15073 196 # Can't use subprocess.getoutput on Python 3, Unix only/broken: 197 # http://bugs.python.org/issue10197
198 - def getoutput(cmd):
199 import subprocess 200 child = subprocess.Popen(cmd, 201 stdin=subprocess.PIPE, 202 stdout=subprocess.PIPE, 203 stderr=subprocess.STDOUT, 204 universal_newlines=True, 205 shell=False) 206 stdout, stderr = child.communicate() 207 # Remove trailing \n to match the Unix function, 208 return stdout.rstrip("\n")
209 elif sys.version_info[0] >= 3: 210 # Use subprocess.getoutput on Python 3, 211 from subprocess import getoutput 212 else: 213 # Use commands.getoutput on Python 2, 214 from commands import getoutput 215