Mercurial > ~astiob > upreckon > hgweb
diff 2.00/compat.py @ 21:ec6f1a132109
A pretty usable version
Test groups and testconfs in non-ZIP archives or ZIP archives with comments are not yet supported.
author | Oleg Oshmyan <chortos@inbox.lv> |
---|---|
date | Fri, 06 Aug 2010 15:39:29 +0000 |
parents | f2279b7602d3 |
children | f07b7a431ea6 |
line wrap: on
line diff
--- a/2.00/compat.py Mon Jun 14 21:02:06 2010 +0000 +++ b/2.00/compat.py Fri Aug 06 15:39:29 2010 +0000 @@ -1,20 +1,51 @@ -#!/usr/bin/python +#! /usr/bin/env python # Copyright (c) 2010 Chortos-2 <chortos@inbox.lv> +# A compatibility layer for Python 2.5+. This is what lets test.py +# run on all versions of Python starting with 2.5, including Python 3. + +# A few notes regarding some compatibility-driven peculiarities +# in the use of the language that can be seen in all modules: +# +# * Except statements never specify target; instead, when needed, +# the exception is taken from sys.exc_info(). Blame the incompatible +# syntaxes of the except clause in Python 2.5 and Python 3 and the lack +# of preprocessor macros in Python of any version ;P. +# +# * Keyword-only parameters are never used, even for parameters +# that should never be given in as arguments. The reason is +# the laziness of some Python developers who have failed to finish +# implementing them in Python 2 even though they had several years +# of time and multiple version releases to sneak them in. +# +# * Abstract classes are only implemented for Python 2.6 and 2.7. +# ABC's require the abc module and the specification of metaclasses, +# but in Python 2.5, the abc module does not exist, while in Python 3, +# metaclasses are specified using a syntax totally incompatible +# with Python 2 and not usable conditionally via exec() and such +# because it is a detail of the syntax of the class statement itself. + +__all__ = ('say', 'basestring', 'range', 'map', 'zip', 'filter', + 'items', 'keys', 'values', 'ABCMeta', 'abstractmethod') + try: # Python 3 exec('say = print') except SyntaxError: try: # Python 2.6/2.7 - exec('say = __builtins__["print"]') + # An alternative is exec('from __future__ import print_function; say = print'); + # if problems arise with the current line, one should try replacing it + # with this one with the future import before abandoning the idea altogether + say = __builtins__['print'] except Exception: # Python 2.5 import sys # This should fully emulate the print function of Python 2.6 in Python 2.3+ - # The error messages are taken from Python 2.6/2.7 + # The error messages are taken from Python 2.6 + # The name bindings at the bottom of this file are in effect def saytypeerror(value, name): - return TypeError(name + ' must be None, str or unicode, not ' + type(value).__name__) + return TypeError(' '.join((name, 'must be None, str or unicode, not', type(value).__name__))) def say(*values, **kwargs): sep = kwargs.pop('sep' , None) end = kwargs.pop('end' , None) @@ -25,7 +56,7 @@ if file is None: file = sys.stdout if not isinstance(sep, basestring): raise saytypeerror(sep, 'sep') if not isinstance(end, basestring): raise saytypeerror(end, 'end') - file.write(sep.join((str(i) for i in values)) + end) + file.write(sep.join(map(str, values)) + end) def import_urllib(): try: @@ -35,4 +66,47 @@ except ImportError: # Python 2 import urllib - return urllib, lambda url: urllib.urlopen(url).read() \ No newline at end of file + return urllib, lambda url: urllib.urlopen(url).read() + +try: + from abc import ABCMeta, abstractmethod +except ImportError: + ABCMeta, abstractmethod = None, lambda x: x + +# In all of the following, the try clause is for Python 2 and the except +# clause is for Python 3. More checks are performed than needed +# for standard builds of Python to ensure as much as possible works +# on custom builds. +try: + basestring = basestring +except NameError: + basestring = str + +try: + range = xrange +except NameError: + range = range + +try: + from itertools import imap as map +except ImportError: + map = map + +try: + from itertools import izip as zip +except ImportError: + zip = zip + +try: + from itertools import ifilter as filter +except ImportError: + filter = filter + +items = dict.iteritems if hasattr(dict, 'iteritems') else dict.items +keys = dict.iterkeys if hasattr(dict, 'iterkeys') else dict.keys +values = dict.itervalues if hasattr(dict, 'itervalues') else dict.values + +for name in __all__: + __builtins__[name] = globals()[name] + +__builtins__['xrange'] = range \ No newline at end of file