"""
Compatibility tools for differences between Python 2 and 3
"""
import functools
import itertools
import sys
import urllib
PY3 = (sys.version_info[0] >= 3)
PY3_2 = sys.version_info[:2] == (3, 2)
try:
import __builtin__ as builtins
# not writeable when instantiated with string, doesn't handle unicode well
from cStringIO import StringIO as cStringIO
# always writeable
from StringIO import StringIO
BytesIO = StringIO
import cPickle
pickle = cPickle
import urllib2
import urlparse
except ImportError:
import builtins
from io import StringIO, BytesIO
cStringIO = StringIO
import pickle as cPickle
pickle = cPickle
import urllib.request
import urllib.parse
from urllib.request import HTTPError, urlretrieve
if PY3:
import io
bytes = bytes
str = str
asunicode = lambda x, _ : str(x)
def asbytes(s):
if isinstance(s, bytes):
return s
return s.encode('latin1')
def asstr(s):
if isinstance(s, str):
return s
return s.decode('latin1')
def asstr2(s): #added JP, not in numpy version
if isinstance(s, str):
return s
elif isinstance(s, bytes):
return s.decode('latin1')
else:
return str(s)
def isfileobj(f):
return isinstance(f, io.FileIO)
def open_latin1(filename, mode='r'):
return open(filename, mode=mode, encoding='iso-8859-1')
strchar = 'U'
# have to explicitly put builtins into the namespace
range = range
map = map
zip = zip
filter = filter
reduce = functools.reduce
long = int
unichr = chr
zip_longest = itertools.zip_longest
# list-producing versions of the major Python iterating functions
def lrange(*args, **kwargs):
return list(range(*args, **kwargs))
def lzip(*args, **kwargs):
return list(zip(*args, **kwargs))
def lmap(*args, **kwargs):
return list(map(*args, **kwargs))
def lfilter(*args, **kwargs):
return list(filter(*args, **kwargs))
urlopen = urllib.request.urlopen
urljoin = urllib.parse.urljoin
urlretrieve = urllib.request.urlretrieve
urlencode = urllib.parse.urlencode
string_types = str
input = input
else:
bytes = str
str = str
asbytes = str
asstr = str
asstr2 = str
strchar = 'S'
def isfileobj(f):
return isinstance(f, file)
def asunicode(s, encoding='ascii'):
if isinstance(s, unicode):
return s
return s.decode(encoding)
def open_latin1(filename, mode='r'):
return open(filename, mode=mode)
# import iterator versions of these functions
range = xrange
zip = itertools.izip
filter = itertools.ifilter
map = itertools.imap
reduce = reduce
long = long
unichr = unichr
zip_longest = itertools.izip_longest
# Python 2-builtin ranges produce lists
lrange = builtins.range
lzip = builtins.zip
lmap = builtins.map
lfilter = builtins.filter
urlopen = urllib2.urlopen
urljoin = urlparse.urljoin
urlencode = urllib.urlencode
HTTPError = urllib2.HTTPError
string_types = basestring
input = raw_input
def getexception():
return sys.exc_info()[1]
def asbytes_nested(x):
if hasattr(x, '__iter__') and not isinstance(x, (bytes, str)):
return [asbytes_nested(y) for y in x]
else:
return asbytes(x)
def asunicode_nested(x):
if hasattr(x, '__iter__') and not isinstance(x, (bytes, str)):
return [asunicode_nested(y) for y in x]
else:
return asunicode(x)
try:
advance_iterator = next
except NameError:
def advance_iterator(it):
return it.next()
next = advance_iterator
try:
callable = callable
except NameError:
def callable(obj):
return any("__call__" in klass.__dict__ for klass in type(obj).__mro__)
[docs]def iteritems(obj, **kwargs):
"""replacement for six's iteritems for Python2/3 compat
uses 'iteritems' if available and otherwise uses 'items'.
Passes kwargs to method.
"""
func = getattr(obj, "iteritems", None)
if not func:
func = obj.items
return func(**kwargs)
[docs]def iterkeys(obj, **kwargs):
func = getattr(obj, "iterkeys", None)
if not func:
func = obj.keys
return func(**kwargs)
[docs]def itervalues(obj, **kwargs):
func = getattr(obj, "itervalues", None)
if not func:
func = obj.values
return func(**kwargs)
[docs]def get_function_name(func):
try:
return func.im_func.func_name
except AttributeError:
#Python 3
return func.__name__
[docs]def get_class(func):
try:
return func.im_class
except AttributeError:
#Python 3
return func.__self__.__class__
try:
combinations = itertools.combinations
except:
# Python 2.6 only
def combinations(iterable, r):
# combinations('ABCD', 2) --> AB AC AD BC BD CD
# combinations(lrange(4), 3) --> 012 013 023 123
pool = tuple(iterable)
n = len(pool)
if r > n:
return
indices = lrange(r)
yield tuple(pool[i] for i in indices)
while True:
for i in reversed(lrange(r)):
if indices[i] != i + n - r:
break
else:
return
indices[i] += 1
for j in range(i+1, r):
indices[j] = indices[j-1] + 1
yield tuple(pool[i] for i in indices)