1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
'''
testcode2.compatibility
-----------------------
Functions for compatibility with different versions of python.
testcode2 is developed using python 3.2; these statements exist to enable
testcode to function transparently (i.e. without using 2to3) on python 2.4
onwards.
Rather than using conditional statements in the main source code, instead place
the required statements in this module and then use (e.g.)
import testcode2.compatibility as compat
var = compat.compat_set([1,2,3,1])
in the main source code.
:copyright: (c) 2012 James Spencer.
:license: modified BSD; see LICENSE for more details.
'''
import sys
### python 2.4 ###
# Import from the sets module if sets are not part of the language.
try:
compat_set = set
except NameError:
from sets import Set as compat_set
# Any and all don't exist in python <2.5. Define our own in pure python.
try:
compat_all = all
except NameError:
def compat_all(iterable):
'''all(iterable) -> bool
Return True if bool(x) is True for all values x in the iterable.
'''
for val in iterable:
if not val:
return False
return True
try:
compat_any = any
except NameError:
def compat_any(iterable):
'''any(iterable) -> bool
Return True if bool(x) is True for any x in the iterable.
'''
for val in iterable:
if val:
return True
try:
import functools
except ImportError:
import testcode2._functools_dummy as functools
### python 2.4, python 2.5 ###
# math.isnan was introduced in python 2.6, so need a workaround for 2.4 and 2.5.
try:
from math import isnan
except ImportError:
def isnan(val):
'''Return True if x is a NaN (not a number), and False otherwise.
:param float val: number.
Replacement for math.isnan for python <2.6.
This is not guaranteed to be portable, but does work under Linux.
'''
return type(val) is float and val != val
try:
# python >=2.6
from ast import literal_eval
except ImportError:
# python 2.4, 2.5
from compiler import parse
from compiler import ast
def literal_eval(node_or_string):
"""Safely evaluate a node/string containing a Python expression.
Thestring or node provided may only consist of the following Python literal
structures: strings, numbers, tuples, lists, dicts, booleans, and None.
Essentially a backport of the literal_eval function in python 2.6 onwards.
From: http://mail.python.org/pipermail/python-list/2009-September/1219992.html
"""
_safe_names = {'None': None, 'True': True, 'False': False}
if isinstance(node_or_string, str):
node_or_string = parse(node_or_string, mode='eval')
if isinstance(node_or_string, ast.Expression):
node_or_string = node_or_string.node
def _convert(node):
'''Convert node/string to expression.'''
if isinstance(node, ast.Const) and isinstance(node.value,
(str, int, float, complex)):
return node.value
elif isinstance(node, ast.Tuple):
return tuple(_convert(element) for element in node.nodes)
elif isinstance(node, ast.List):
return list(_convert(element) for element in node.nodes)
elif isinstance(node, ast.Dict):
return dict((_convert(k), _convert(v)) for k, v
in node.items)
elif isinstance(node, ast.Name):
if node.name in _safe_names:
return _safe_names[node.name]
elif isinstance(node, ast.UnarySub):
return -_convert(node.expr)
raise ValueError('malformed string')
return _convert(node_or_string)
# os.path.relpath was introduced in python 2.6.
try:
from os.path import relpath
except ImportError:
import os.path
def relpath(path, start=os.path.curdir):
"""Return a relative version of a path"""
if not path:
raise ValueError("no path specified")
filter_null = lambda lll: [x for x in lll if x]
start_list = filter_null(os.path.abspath(start).split(os.path.sep))
path_list = filter_null(os.path.abspath(path).split(os.path.sep))
common = len(os.path.commonprefix([start_list, path_list]))
rel_list = [os.pardir] * (len(start_list)-common) + path_list[common:]
if not rel_list:
return os.path.curdir
return os.path.join(*rel_list)
### python 2 ###
try:
import configparser
except ImportError:
import configparser as configparser
try:
compat_input = raw_input
except NameError:
compat_input = input
try:
maxint = sys.maxsize
except AttributeError:
maxint = sys.maxsize
|