comparison 2.00/compat.py @ 25:b500e117080e

Bug fixes and overhead reduction Added the --problem/-p option. (WARNING: not the same as the -p option of test.py 1.x.) The problem names supplied are not validated. Added zip_longest to compat.py. Experimental: problem names are now _always_ printed for multi-problem sets. Overhead: Escape presses are now checked only once every .15 seconds (at least kbhit() on Windows is very slow). Overhead: sleep(0) is now called in the time-control-and-Escape-watching loop (at least on Windows, it immediately transfers control to some waiting thread). Bug fix: compat.py now overwrites built-ins only while including testconfs (--help was broken in Python 2). Bug fix: ReadDeleting in config.py now closes the file it opens (especially important on Windows, where open files cannot be deleted). Bug fix: added callable to compat.py (it is absent from Python 3). Bug fix: the default (built-in) output validator now properly handles unwanted trailing data. Bug fix: testconfs in custom archives no more raise NameError. Bug fix: if a validator program cannot be launched, CannotStartValidator is now raised instead of the fatal OSError.
author Oleg Oshmyan <chortos@inbox.lv>
date Thu, 23 Sep 2010 23:05:58 +0000
parents f07b7a431ea6
children dc4be35d17e0
comparison
equal deleted inserted replaced
24:c23d81f4a1a3 25:b500e117080e
23 # but in Python 2.5, the abc module does not exist, while in Python 3, 23 # but in Python 2.5, the abc module does not exist, while in Python 3,
24 # metaclasses are specified using a syntax totally incompatible 24 # metaclasses are specified using a syntax totally incompatible
25 # with Python 2 and not usable conditionally via exec() and such 25 # with Python 2 and not usable conditionally via exec() and such
26 # because it is a detail of the syntax of the class statement itself. 26 # because it is a detail of the syntax of the class statement itself.
27 27
28 __all__ = ('say', 'basestring', 'range', 'map', 'zip', 'filter', 28 import __builtin__
29 'items', 'keys', 'values', 'ABCMeta', 'abstractmethod') 29
30 __all__ = ('say', 'basestring', 'range', 'map', 'zip', 'filter', 'items',
31 'keys', 'values', 'zip_longest', 'callable',
32 'ABCMeta', 'abstractmethod', 'CompatBuiltins')
30 33
31 try: 34 try:
32 # Python 3 35 # Python 3
33 exec('say = print') 36 exec('say = print')
34 except SyntaxError: 37 except SyntaxError:
86 range = xrange 89 range = xrange
87 except NameError: 90 except NameError:
88 range = range 91 range = range
89 92
90 try: 93 try:
94 callable = callable
95 except NameError:
96 callable = lambda obj: hasattr(obj, '__call__')
97
98 try:
91 from itertools import imap as map 99 from itertools import imap as map
92 except ImportError: 100 except ImportError:
93 map = map 101 map = map
94 102
95 try: 103 try:
104 112
105 items = dict.iteritems if hasattr(dict, 'iteritems') else dict.items 113 items = dict.iteritems if hasattr(dict, 'iteritems') else dict.items
106 keys = dict.iterkeys if hasattr(dict, 'iterkeys') else dict.keys 114 keys = dict.iterkeys if hasattr(dict, 'iterkeys') else dict.keys
107 values = dict.itervalues if hasattr(dict, 'itervalues') else dict.values 115 values = dict.itervalues if hasattr(dict, 'itervalues') else dict.values
108 116
109 for name in __all__: 117 try:
110 __builtins__[name] = globals()[name] 118 # Python 3
119 from itertools import zip_longest
120 except ImportError:
121 # Python 2.6/2.7
122 from itertools import izip_longest as zip_longest
123 except ImportError:
124 # Python 2.5
125 from itertools import chain, repeat
126 # Adapted from the documentation of itertools.izip_longest
127 def zip_longest(*args, **kwargs):
128 fillvalue = kwargs.get('fillvalue')
129 def sentinel(counter=([fillvalue]*(len(args)-1)).pop):
130 yield counter()
131 fillers = repeat(fillvalue)
132 iters = [chain(it, sentinel(), fillers) for it in args]
133 try:
134 for tup in zip(*iters):
135 yield tup
136 except IndexError:
137 pass
138
139 # Automatically import * from this module into testconf.py's
140 class CompatBuiltins(object):
141 __slots__ = 'originals'
142 def __init__(self):
143 self.originals = {}
144 def __enter__(self):
145 g = globals()
146 for name in __all__:
147 if hasattr(__builtin__, name):
148 self.originals[name] = getattr(__builtin__, name)
149 setattr(__builtin__, name, g[name])
150 def __exit__(self, exc_type, exc_val, exc_tb):
151 for name in self.originals:
152 setattr(__builtin__, name, self.originals[name])
111 153
112 # Support simple testconf.py's written for test.py 1.x 154 # Support simple testconf.py's written for test.py 1.x
113 __builtins__['xrange'] = range 155 __builtin__.xrange = range