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 _bytes_bytearray_to_str(s):
57 """If s is bytes or bytearray, convert to a unicode string.""" 58 if isinstance(s, (bytes, bytearray)): 59 return s.decode() 60 return s
61
62 - def _as_unicode(s):
63 """Turn byte string or unicode string into a unicode string.""" 64 if isinstance(s, str): 65 return s 66 # Assume it is a bytes string 67 # Note ISO-8859-1 aka Latin-1 preserves first 256 chars 68 return codecs.latin_1_decode(s)[0]
69
70 - def _as_bytes(s):
71 """Turn byte string or unicode string into a bytes string. 72 73 The Python 2 version returns a (byte) string. 74 """ 75 if isinstance(s, bytes): 76 return s 77 # Assume it is a unicode string 78 # Note ISO-8859-1 aka Latin-1 preserves first 256 chars 79 return codecs.latin_1_encode(s)[0]
80 81 _as_string = _as_unicode 82
83 - def _is_int_or_long(i):
84 """Check if the value is an integer. 85 86 Note there are no longs on Python 3. 87 """ 88 return isinstance(i, int)
89 90 import io 91
92 - def _binary_to_string_handle(handle):
93 """Treat a binary (bytes) handle like a text (unicode) handle.""" 94 # TODO, once drop all of Python 3.0 - 3.3, replace this with just: 95 # 96 # return io.TextIOWrapper(io.BufferedReader(handle)) 97 # 98 # See also http://bugs.python.org/issue5628 99 # and http://bugs.python.org/issue13541 100 # and http://bugs.python.org/issue13464 which should be fixed in Python 3.3 101 # 102 # However, still have problems under Python 3.3.0, e.g. 103 # 104 # $ python3.3 test_SeqIO_online.py 105 # test_nuccore_X52960 (__main__.EntrezTests) 106 # Bio.Entrez.efetch('nuccore', id='X52960', ...) ... ERROR 107 # test_nucleotide_6273291 (__main__.EntrezTests) 108 # Bio.Entrez.efetch('nucleotide', id='6273291', ...) ... ERROR 109 # test_protein_16130152 (__main__.EntrezTests) 110 # Bio.Entrez.efetch('protein', id='16130152', ...) ... ERROR 111 # test_get_sprot_raw (__main__.ExPASyTests) 112 # Bio.ExPASy.get_sprot_raw("O23729") ... ok 113 # .. 114 # ValueError: I/O operation on closed file. 115 # 116 class EvilHandleHack(object): 117 def __init__(self, handle): 118 self._handle = handle 119 try: 120 # If wrapping an online handle, this this is nice to have: 121 self.url = handle.url 122 except AttributeError: 123 pass
124 125 def read(self, length=None): 126 return _as_string(self._handle.read(length)) 127 128 def readline(self): 129 return _as_string(self._handle.readline()) 130 131 def __iter__(self): 132 for line in self._handle: 133 yield _as_string(line) 134 135 def close(self): 136 return self._handle.close() 137 138 def seek(self, pos): 139 return self._handle.seek(pos) 140 141 def tell(self): 142 return self._handle.tell() 143 144 return EvilHandleHack(handle) 145 146 # This is to avoid the deprecation warning from open(filename, "rU") 147 _universal_read_mode = "r" # text mode does universal new lines 148 149 # On Python 3, can depend on OrderedDict being present: 150 from collections import OrderedDict 151 152 # On Python 3, this will be a unicode StringIO 153 from io import StringIO 154 155 # On Python 3 urllib, urllib2, and urlparse were merged: 156 from urllib.request import urlopen, Request, urlretrieve, urlparse 157 from urllib.parse import urlencode, quote 158 from urllib.error import HTTPError 159 160 else: 161 # Python 2 code 162 from __builtin__ import open, basestring, unicode 163 164 # Import Python3 like iterator functions: 165 from future_builtins import zip, map, filter 166 from __builtin__ import xrange as range 167 from __builtin__ import raw_input as input 168 169 _bytes_to_string = lambda b: b # bytes to string, i.e. do nothing 170 _string_to_bytes = lambda s: str(s) # str (or unicode) to bytes string 171
172 - def _bytes_bytearray_to_str(s):
173 """If s is bytes or bytearray, convert to a string.""" 174 if isinstance(s, (bytes, bytearray)): 175 return str(s) 176 return s
177
178 - def _as_unicode(s):
179 """Turn a (byte) string or a unicode string into a (byte) string.""" 180 # Will be changed by 2to3 to "isinstance(s, str)" but doesn't matter: 181 if isinstance(s, unicode): 182 return s 183 return s.decode()
184
185 - def _as_bytes(s):
186 """Turn a (byte) string or a unicode string into a (byte) string.""" 187 return str(s)
188 189 _as_string = _as_bytes 190
191 - def _is_int_or_long(i):
192 """Check if the value is an integer or long.""" 193 return isinstance(i, (int, long))
194
195 - def _binary_to_string_handle(handle):
196 """Treat a binary handle like a text handle.""" 197 return handle
198 199 # This private variable is set to "r" on Python 3 for text 200 # mode which include universal readlines mode 201 _universal_read_mode = "rU" 202 203 try: 204 # Present on Python 2.7 205 from collections import OrderedDict 206 except ImportError: 207 try: 208 # Raymond Hettinger's backport available on PyPI 209 from ordereddict import OrderedDict 210 except ImportError: 211 # Use our bundled copy instead 212 from ._ordereddict import OrderedDict 213 214 # On Python 2 this will be a (bytes) string based handle. 215 # Note this doesn't work as it is unicode based: 216 # from io import StringIO 217 try: 218 from cStringIO import StringIO 219 except ImportError: 220 from StringIO import StringIO 221 222 # Under urllib.request on Python 3: 223 from urllib2 import urlopen, Request 224 from urllib import urlretrieve 225 from urlparse import urlparse 226 227 # Under urllib.parse on Python 3: 228 from urllib import urlencode, quote 229 230 # Under urllib.error on Python 3: 231 from urllib2 import HTTPError 232 233 234 if sys.platform == "win32": 235 # Can't use commands.getoutput on Python 2, Unix only/broken: 236 # http://bugs.python.org/issue15073 237 # Can't use subprocess.getoutput on Python 3, Unix only/broken: 238 # http://bugs.python.org/issue10197
239 - def getoutput(cmd):
240 import subprocess 241 child = subprocess.Popen(cmd, 242 stdin=subprocess.PIPE, 243 stdout=subprocess.PIPE, 244 stderr=subprocess.STDOUT, 245 universal_newlines=True, 246 shell=False) 247 stdout, stderr = child.communicate() 248 # Remove trailing \n to match the Unix function, 249 return stdout.rstrip("\n")
250 elif sys.version_info[0] >= 3: 251 # Use subprocess.getoutput on Python 3, 252 from subprocess import getoutput 253 else: 254 # Use commands.getoutput on Python 2, 255 from commands import getoutput 256