Mercurial > ~astiob > upreckon > hgweb
view config.py @ 83:37c4ad87583c
Several small fixes
Bug fix: testconf.py bytecode is written on Python 2.5. It is not written
on newer versions of Python, but Python 2.5 lacks the facility to disable
writing it; before this fix, the code just raised an unhandled exception.
Bug fix: callable validators no longer require the outfile configuration
variable to be set.
Bug fix: the pause configuration variable (if not callable) is run in a
shell just like it did in test.py v1; in particular, auto-detected values
of the pause configuration variable now work again.
Extras: *.{class,orig} added to .hgignore; Sublime Text 1 project file
removed as I am using Sublime Text 2 now.
author | Oleg Oshmyan <chortos@inbox.lv> |
---|---|
date | Thu, 24 Feb 2011 00:10:19 +0000 |
parents | 06356af50bf9 |
children | cd347cfca272 |
line wrap: on
line source
#! /usr/bin/env python # Copyright (c) 2010-2011 Chortos-2 <chortos@inbox.lv> from __future__ import division, with_statement try: from compat import * import files except ImportError: import __main__ __main__.import_error(sys.exc_info()[1]) else: from __main__ import options if files.ZipArchive: try: import zipimport except ImportError: zipimport = None else: zipimport = None import imp, os, sys, tempfile __all__ = 'load_problem', 'load_global', 'globalconf' defaults_problem = {'kind': 'batch', 'usegroups': False, 'maxcputime': None, 'maxwalltime': None, 'maxmemory': None, 'dummies': {}, 'testsexcluded': (), 'padtests': 0, 'paddummies': 0, 'taskweight': 100, 'groupweight': {}, 'pointmap': {}, 'stdio': False, 'dummyinname': '', 'dummyoutname': '', 'tester': None, 'maxexitcode': 0, 'inname': '', 'ansname': ''} defaults_global = {'problems': None, 'force_zero_exitcode': True} defaults_noerase = {'inname': '%.in', 'outname': '%.out', 'ansname': '%.ans'} patterns = ('inname', 'outname', 'ansname', 'testcaseinname', 'testcaseoutname', 'dummyinname', 'dummyoutname') class Config(object): __slots__ = 'modules', '__dict__' def __init__(self, *modules): self.modules = modules def __getattr__(self, name): for module in self.modules: try: return getattr(module, name) except AttributeError: pass # TODO: provide a message raise AttributeError(name) # A helper context manager class ReadDeleting(object): __slots__ = 'name', 'file' def __init__(self, name): self.name = name def __enter__(self): try: self.file = open(self.name, 'rU') return self.file except: try: self.__exit__(None, None, None) except: pass raise def __exit__(self, exc_type, exc_val, exc_tb): self.file.close() os.remove(self.name) def load_problem(problem_name): global builtins try: dwb = sys.dont_write_bytecode sys.dont_write_bytecode = True except AttributeError: pass metafile = files.File('/'.join((problem_name, 'testconf.py')), True, 'configuration') module = None with CompatBuiltins() as builtins: if zipimport and isinstance(metafile.archive, files.ZipArchive): try: module = zipimport.zipimporter(os.path.dirname(metafile.full_real_path)).load_module('testconf') except zipimport.ZipImportError: pass else: del sys.modules['testconf'] if not module: try: with metafile.open() as f: module = imp.load_module('testconf', f, metafile.full_real_path, ('.py', 'r', imp.PY_SOURCE)) # Handle the case when f is not a true file object but imp requires one except ValueError: # FIXME: 2.5 lacks the delete parameter with tempfile.NamedTemporaryFile(delete=False) as f: inputdatafname = f.name metafile.copy(inputdatafname) with ReadDeleting(inputdatafname) as f: module = imp.load_module('testconf', f, metafile.full_real_path, ('.py', 'r', imp.PY_SOURCE)) del sys.modules['testconf'] if hasattr(module, 'padwithzeroestolength'): if not hasattr(module, 'padtests'): try: module.padtests = module.padwithzeroestolength[0] except TypeError: module.padtests = module.padwithzeroestolength if not hasattr(module, 'paddummies'): try: module.paddummies = module.padwithzeroestolength[1] except TypeError: module.paddummies = module.padwithzeroestolength for name in defaults_problem: if not hasattr(globalconf, name): setattr(module, name, getattr(module, name, defaults_problem[name])) module = Config(module, globalconf) if not module.dummyinname: module.dummyinname = getattr(module, 'testcaseinname', module.dummyinname) if not module.dummyoutname: module.dummyoutname = getattr(module, 'testcaseoutname', module.dummyoutname) if not hasattr(module, 'path'): if hasattr(module, 'name'): module.path = module.name elif sys.platform != 'win32': module.path = os.path.join(os.path.curdir, problem_name) else: module.path = problem_name for name in 'pointmap', 'groupweight': oldmap = getattr(module, name) if isinstance(oldmap, dict): newmap = {} for key in oldmap: if not options.legacy and isinstance(key, basestring): newmap[key] = oldmap[key] else: try: for k in key: newmap[k] = oldmap[key] except TypeError: newmap[key] = oldmap[key] setattr(module, name, newmap) if options.no_maxtime: module.maxcputime = module.maxwalltime = 0 try: sys.dont_write_bytecode = dwb except NameError: pass for name in patterns: if hasattr(module, name): setattr(module, name, getattr(module, name).replace('%', problem_name)) return module def load_global(): global builtins try: dwb = sys.dont_write_bytecode sys.dont_write_bytecode = True except AttributeError: pass metafile = files.File('testconf.py', True, 'configuration') module = None with CompatBuiltins() as builtins: if zipimport and isinstance(metafile.archive, files.ZipArchive): try: module = zipimport.zipimporter(os.path.dirname(metafile.full_real_path)).load_module('testconf') except zipimport.ZipImportError: pass else: del sys.modules['testconf'] if not module: try: with metafile.open() as f: module = imp.load_module('testconf', f, metafile.full_real_path, ('.py', 'r', imp.PY_SOURCE)) # Handle the case when f is not a true file object but imp requires one except ValueError: # FIXME: 2.5 lacks the delete parameter with tempfile.NamedTemporaryFile(delete=False) as f: inputdatafname = f.name metafile.copy(inputdatafname) with ReadDeleting(inputdatafname) as f: module = imp.load_module('testconf', f, metafile.full_real_path, ('.py', 'r', imp.PY_SOURCE)) del sys.modules['testconf'] for name in defaults_global: setattr(module, name, getattr(module, name, defaults_global[name])) if not options.erase: for name in defaults_noerase: setattr(module, name, getattr(module, name, defaults_noerase[name])) if hasattr(module, 'tasknames'): module.problems = module.tasknames global globalconf globalconf = module try: sys.dont_write_bytecode = dwb except NameError: pass return module