comparison config.py @ 50:4ea7133ac25c

Converted 2.00 into the default branch
author Oleg Oshmyan <chortos@inbox.lv>
date Sun, 19 Dec 2010 23:25:13 +0200
parents 2.00/config.py@81f58c938ec5
children 7c6dba0b84f2
comparison
equal deleted inserted replaced
47:06f1683c8db9 50:4ea7133ac25c
1 #! /usr/bin/env python
2 # Copyright (c) 2010 Chortos-2 <chortos@inbox.lv>
3
4 from __future__ import division, with_statement
5
6 try:
7 from compat import *
8 import files
9 except ImportError:
10 import __main__
11 __main__.import_error(sys.exc_info()[1])
12 else:
13 from __main__ import options
14
15 if files.ZipArchive:
16 try:
17 import zipimport
18 except ImportError:
19 zipimport = None
20 else:
21 zipimport = None
22
23 import imp, os, sys, tempfile
24
25 __all__ = 'load_problem', 'load_global', 'globalconf'
26
27 defaults_problem = {'usegroups': False,
28 'maxtime': None,
29 'maxmemory': None,
30 'dummies': {},
31 'testsexcluded': (),
32 'padtests': 0,
33 'paddummies': 0,
34 'taskweight': 100,
35 'pointmap': {},
36 'stdio': False,
37 'dummyinname': '',
38 'dummyoutname': '',
39 'tester': None,
40 'maxexitcode': 0,
41 'inname': '',
42 'ansname': ''}
43 defaults_global = {'tasknames': None,
44 'force_zero_exitcode': True}
45 defaults_noerase = {'inname': '%.in',
46 'outname': '%.out',
47 'ansname': '%.ans'}
48 patterns = ('inname', 'outname', 'ansname', 'testcaseinname',
49 'testcaseoutname', 'dummyinname', 'dummyoutname')
50
51 class Config(object):
52 __slots__ = 'modules', '__dict__'
53
54 def __init__(self, *modules):
55 self.modules = modules
56
57 def __getattr__(self, name):
58 for module in self.modules:
59 try:
60 return getattr(module, name)
61 except AttributeError:
62 pass
63 # TODO: provide a message
64 raise AttributeError(name)
65
66 # A helper context manager
67 class ReadDeleting(object):
68 __slots__ = 'name', 'file'
69
70 def __init__(self, name):
71 self.name = name
72
73 def __enter__(self):
74 try:
75 self.file = open(self.name, 'rU')
76 return self.file
77 except:
78 try:
79 self.__exit__(None, None, None)
80 except:
81 pass
82 raise
83
84 def __exit__(self, exc_type, exc_val, exc_tb):
85 self.file.close()
86 os.remove(self.name)
87
88 def load_problem(problem_name):
89 dwb = sys.dont_write_bytecode
90 sys.dont_write_bytecode = True
91 metafile = files.File('/'.join((problem_name, 'testconf.py')), True, 'configuration')
92 module = None
93 with CompatBuiltins():
94 if zipimport and isinstance(metafile.archive, files.ZipArchive):
95 try:
96 module = zipimport.zipimporter(os.path.dirname(metafile.full_real_path)).load_module('testconf')
97 except zipimport.ZipImportError:
98 pass
99 else:
100 del sys.modules['testconf']
101 if not module:
102 try:
103 with metafile.open() as f:
104 module = imp.load_module('testconf', f, metafile.full_real_path, ('.py', 'r', imp.PY_SOURCE))
105 # Handle the case when f is not a true file object but imp requires one
106 except ValueError:
107 # FIXME: 2.5 lacks the delete parameter
108 with tempfile.NamedTemporaryFile(delete=False) as f:
109 inputdatafname = f.name
110 metafile.copy(inputdatafname)
111 with ReadDeleting(inputdatafname) as f:
112 module = imp.load_module('testconf', f, metafile.full_real_path, ('.py', 'r', imp.PY_SOURCE))
113 del sys.modules['testconf']
114 if hasattr(module, 'padwithzeroestolength'):
115 if not hasattr(module, 'padtests'):
116 try:
117 module.padtests = module.padwithzeroestolength[0]
118 except TypeError:
119 module.padtests = module.padwithzeroestolength
120 if not hasattr(module, 'paddummies'):
121 try:
122 module.paddummies = module.padwithzeroestolength[1]
123 except TypeError:
124 module.paddummies = module.padwithzeroestolength
125 for name in defaults_problem:
126 if not hasattr(globalconf, name):
127 setattr(module, name, getattr(module, name, defaults_problem[name]))
128 module = Config(module, globalconf)
129 if not module.dummyinname:
130 module.dummyinname = getattr(module, 'testcaseinname', module.dummyinname)
131 if not module.dummyoutname:
132 module.dummyoutname = getattr(module, 'testcaseoutname', module.dummyoutname)
133 if not hasattr(module, 'path'):
134 if hasattr(module, 'name'):
135 module.path = module.name
136 elif sys.platform != 'win32':
137 module.path = os.path.join(os.path.curdir, problem_name)
138 else:
139 module.path = problem_name
140 if options.no_maxtime:
141 module.maxtime = 0
142 sys.dont_write_bytecode = dwb
143 for name in patterns:
144 if hasattr(module, name):
145 setattr(module, name, getattr(module, name).replace('%', problem_name))
146 return module
147
148 def load_global():
149 dwb = sys.dont_write_bytecode
150 sys.dont_write_bytecode = True
151 metafile = files.File('testconf.py', True, 'configuration')
152 module = None
153 with CompatBuiltins():
154 if zipimport and isinstance(metafile.archive, files.ZipArchive):
155 try:
156 module = zipimport.zipimporter(os.path.dirname(metafile.full_real_path)).load_module('testconf')
157 except zipimport.ZipImportError:
158 pass
159 else:
160 del sys.modules['testconf']
161 if not module:
162 try:
163 with metafile.open() as f:
164 module = imp.load_module('testconf', f, metafile.full_real_path, ('.py', 'r', imp.PY_SOURCE))
165 # Handle the case when f is not a true file object but imp requires one
166 except ValueError:
167 # FIXME: 2.5 lacks the delete parameter
168 with tempfile.NamedTemporaryFile(delete=False) as f:
169 inputdatafname = f.name
170 metafile.copy(inputdatafname)
171 with ReadDeleting(inputdatafname) as f:
172 module = imp.load_module('testconf', f, metafile.full_real_path, ('.py', 'r', imp.PY_SOURCE))
173 del sys.modules['testconf']
174 for name in defaults_global:
175 setattr(module, name, getattr(module, name, defaults_global[name]))
176 if not options.erase:
177 for name in defaults_noerase:
178 setattr(module, name, getattr(module, name, defaults_noerase[name]))
179 global globalconf
180 globalconf = module
181 sys.dont_write_bytecode = dwb
182 return module