mirror of https://gitlab.com/QEF/q-e.git
160 lines
4.7 KiB
Python
160 lines
4.7 KiB
Python
'''
|
|
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, basestring):
|
|
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,
|
|
(basestring, int, float, long, 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.maxint
|
|
except AttributeError:
|
|
maxint = sys.maxsize
|