Mercurial > ~astiob > upreckon > hgweb
annotate compat.py @ 69:c0f1b87013ad
Fixed a crash on Python 3 on POSIX
author | Oleg Oshmyan <chortos@inbox.lv> |
---|---|
date | Mon, 03 Jan 2011 01:07:02 +0200 |
parents | e00ab6d1f0ba |
children | b9d5857f7b9a |
rev | line source |
---|---|
21 | 1 #! /usr/bin/env python |
16 | 2 # Copyright (c) 2010 Chortos-2 <chortos@inbox.lv> |
3 | |
21 | 4 # A compatibility layer for Python 2.5+. This is what lets test.py |
5 # run on all versions of Python starting with 2.5, including Python 3. | |
6 | |
7 # A few notes regarding some compatibility-driven peculiarities | |
8 # in the use of the language that can be seen in all modules: | |
9 # | |
10 # * Except statements never specify target; instead, when needed, | |
11 # the exception is taken from sys.exc_info(). Blame the incompatible | |
12 # syntaxes of the except clause in Python 2.5 and Python 3 and the lack | |
13 # of preprocessor macros in Python of any version ;P. | |
14 # | |
15 # * Keyword-only parameters are never used, even for parameters | |
16 # that should never be given in as arguments. The reason is | |
17 # the laziness of some Python developers who have failed to finish | |
18 # implementing them in Python 2 even though they had several years | |
19 # of time and multiple version releases to sneak them in. | |
20 # | |
21 # * Abstract classes are only implemented for Python 2.6 and 2.7. | |
22 # ABC's require the abc module and the specification of metaclasses, | |
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 | |
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. | |
27 | |
67
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
28 # Some code was adapted from Python 2.7.1 and its documentation. |
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
29 # This code is clearly marked as such in preceding comments and is |
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
30 # covered by copyright as follows: |
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
31 # |
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
32 # Copyright (c) 2001-2010 Python Software Foundation; all rights reserved. |
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
33 # |
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
34 # The code is used according to the PSF License Agreement |
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
35 # for Python 2.7.1, whose full text is available from your local |
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
36 # installation of Python (enter 'license()' in the interactive |
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
37 # interpreter) or from the Web at the following URL: |
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
38 # |
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
39 # http://docs.python.org/2.7.1/license.html#terms-and-conditions-for-accessing-or-otherwise-using-python |
e0f8b28e15b5
Added a copyright & licensing notice about code borrowed from Python itself
Oleg Oshmyan <chortos@inbox.lv>
parents:
50
diff
changeset
|
40 |
27 | 41 try: |
42 import builtins | |
43 except ImportError: | |
44 import __builtin__ as builtins | |
25
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
45 |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
46 __all__ = ('say', 'basestring', 'range', 'map', 'zip', 'filter', 'items', |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
47 'keys', 'values', 'zip_longest', 'callable', |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
48 'ABCMeta', 'abstractmethod', 'CompatBuiltins') |
21 | 49 |
16 | 50 try: |
51 # Python 3 | |
52 exec('say = print') | |
53 except SyntaxError: | |
54 try: | |
55 # Python 2.6/2.7 | |
21 | 56 # An alternative is exec('from __future__ import print_function; say = print'); |
57 # if problems arise with the current line, one should try replacing it | |
58 # with this one with the future import before abandoning the idea altogether | |
27 | 59 say = getattr(builtins, 'print') |
16 | 60 except Exception: |
61 # Python 2.5 | |
62 import sys | |
63 # This should fully emulate the print function of Python 2.6 in Python 2.3+ | |
21 | 64 # The error messages are taken from Python 2.6 |
65 # The name bindings at the bottom of this file are in effect | |
16 | 66 def saytypeerror(value, name): |
21 | 67 return TypeError(' '.join((name, 'must be None, str or unicode, not', type(value).__name__))) |
16 | 68 def say(*values, **kwargs): |
69 sep = kwargs.pop('sep' , None) | |
70 end = kwargs.pop('end' , None) | |
71 file = kwargs.pop('file', None) | |
72 if kwargs: raise TypeError("'%s' is an invalid keyword argument for this function" % kwargs.popitem()[0]) | |
73 if sep is None: sep = ' ' | |
74 if end is None: end = '\n' | |
75 if file is None: file = sys.stdout | |
76 if not isinstance(sep, basestring): raise saytypeerror(sep, 'sep') | |
77 if not isinstance(end, basestring): raise saytypeerror(end, 'end') | |
21 | 78 file.write(sep.join(map(str, values)) + end) |
16 | 79 |
34
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
80 try: |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
81 from os.path import relpath |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
82 except ImportError: |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
83 # Python 2.5 |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
84 import os.path as _path |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
85 |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
86 # Adapted from Python 2.7.1 |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
87 |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
88 if hasattr(_path, 'splitunc'): |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
89 def _abspath_split(path): |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
90 abs = _path.abspath(_path.normpath(path)) |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
91 prefix, rest = _path.splitunc(abs) |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
92 is_unc = bool(prefix) |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
93 if not is_unc: |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
94 prefix, rest = _path.splitdrive(abs) |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
95 return is_unc, prefix, [x for x in rest.split(_path.sep) if x] |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
96 else: |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
97 def _abspath_split(path): |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
98 prefix, rest = _path.splitdrive(_path.abspath(_path.normpath(path))) |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
99 return False, prefix, [x for x in rest.split(_path.sep) if x] |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
100 |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
101 def relpath(path, start=_path.curdir): |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
102 """Return a relative version of a path""" |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
103 |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
104 if not path: |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
105 raise ValueError("no path specified") |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
106 |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
107 start_is_unc, start_prefix, start_list = _abspath_split(start) |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
108 path_is_unc, path_prefix, path_list = _abspath_split(path) |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
109 |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
110 if path_is_unc ^ start_is_unc: |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
111 raise ValueError("Cannot mix UNC and non-UNC paths (%s and %s)" |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
112 % (path, start)) |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
113 if path_prefix.lower() != start_prefix.lower(): |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
114 if path_is_unc: |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
115 raise ValueError("path is on UNC root %s, start on UNC root %s" |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
116 % (path_prefix, start_prefix)) |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
117 else: |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
118 raise ValueError("path is on drive %s, start on drive %s" |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
119 % (path_prefix, start_prefix)) |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
120 # Work out how much of the filepath is shared by start and path. |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
121 i = 0 |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
122 for e1, e2 in zip(start_list, path_list): |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
123 if e1.lower() != e2.lower(): |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
124 break |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
125 i += 1 |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
126 |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
127 rel_list = [_path.pardir] * (len(start_list)-i) + path_list[i:] |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
128 if not rel_list: |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
129 return _path.curdir |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
130 return _path.join(*rel_list) |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
131 |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
132 _path.relpath = relpath |
8fec38b0dd6e
A os.path.relpath implementation for Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
31
diff
changeset
|
133 |
16 | 134 def import_urllib(): |
135 try: | |
136 # Python 3 | |
137 import urllib.request | |
138 return urllib.request, lambda url: urllib.request.urlopen(url).read().decode() | |
139 except ImportError: | |
140 # Python 2 | |
141 import urllib | |
21 | 142 return urllib, lambda url: urllib.urlopen(url).read() |
143 | |
144 try: | |
145 from abc import ABCMeta, abstractmethod | |
146 except ImportError: | |
147 ABCMeta, abstractmethod = None, lambda x: x | |
148 | |
149 # In all of the following, the try clause is for Python 2 and the except | |
150 # clause is for Python 3. More checks are performed than needed | |
151 # for standard builds of Python to ensure as much as possible works | |
152 # on custom builds. | |
153 try: | |
154 basestring = basestring | |
155 except NameError: | |
156 basestring = str | |
157 | |
158 try: | |
159 range = xrange | |
160 except NameError: | |
161 range = range | |
162 | |
163 try: | |
25
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
164 callable = callable |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
165 except NameError: |
68
e00ab6d1f0ba
Corrected the implementation of callable() for Python 3.0 and 3.1
Oleg Oshmyan <chortos@inbox.lv>
parents:
67
diff
changeset
|
166 from collections import Callable |
e00ab6d1f0ba
Corrected the implementation of callable() for Python 3.0 and 3.1
Oleg Oshmyan <chortos@inbox.lv>
parents:
67
diff
changeset
|
167 callable = lambda obj: isinstance(obj, Callable) |
25
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
168 |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
169 try: |
35
23aa8da5be5f
compat.py now emulates the next() built-in in Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
34
diff
changeset
|
170 next = next |
23aa8da5be5f
compat.py now emulates the next() built-in in Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
34
diff
changeset
|
171 except NameError: |
23aa8da5be5f
compat.py now emulates the next() built-in in Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
34
diff
changeset
|
172 next = lambda obj: obj.next() |
23aa8da5be5f
compat.py now emulates the next() built-in in Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
34
diff
changeset
|
173 |
23aa8da5be5f
compat.py now emulates the next() built-in in Python 2.5
Oleg Oshmyan <chortos@inbox.lv>
parents:
34
diff
changeset
|
174 try: |
21 | 175 from itertools import imap as map |
176 except ImportError: | |
177 map = map | |
178 | |
179 try: | |
180 from itertools import izip as zip | |
181 except ImportError: | |
182 zip = zip | |
183 | |
184 try: | |
185 from itertools import ifilter as filter | |
186 except ImportError: | |
187 filter = filter | |
188 | |
189 items = dict.iteritems if hasattr(dict, 'iteritems') else dict.items | |
190 keys = dict.iterkeys if hasattr(dict, 'iterkeys') else dict.keys | |
191 values = dict.itervalues if hasattr(dict, 'itervalues') else dict.values | |
192 | |
25
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
193 try: |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
194 # Python 3 |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
195 from itertools import zip_longest |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
196 except ImportError: |
31 | 197 try: |
198 # Python 2.6/2.7 | |
199 from itertools import izip_longest as zip_longest | |
200 except ImportError: | |
201 # Python 2.5 | |
202 from itertools import chain, repeat | |
203 # Adapted from the documentation of itertools.izip_longest | |
204 def zip_longest(*args, **kwargs): | |
205 fillvalue = kwargs.get('fillvalue') | |
206 def sentinel(counter=([fillvalue]*(len(args)-1)).pop): | |
207 yield counter() | |
208 fillers = repeat(fillvalue) | |
209 iters = [chain(it, sentinel(), fillers) for it in args] | |
210 try: | |
211 for tup in zip(*iters): | |
212 yield tup | |
213 except IndexError: | |
214 pass | |
25
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
215 |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
216 # Automatically import * from this module into testconf.py's |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
217 class CompatBuiltins(object): |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
218 __slots__ = 'originals' |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
219 def __init__(self): |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
220 self.originals = {} |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
221 def __enter__(self): |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
222 g = globals() |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
223 for name in __all__: |
27 | 224 if hasattr(builtins, name): |
225 self.originals[name] = getattr(builtins, name) | |
226 setattr(builtins, name, g[name]) | |
25
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
227 def __exit__(self, exc_type, exc_val, exc_tb): |
b500e117080e
Bug fixes and overhead reduction
Oleg Oshmyan <chortos@inbox.lv>
parents:
22
diff
changeset
|
228 for name in self.originals: |
27 | 229 setattr(builtins, name, self.originals[name]) |
21 | 230 |
22 | 231 # Support simple testconf.py's written for test.py 1.x |
27 | 232 builtins.xrange = range |