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