diff 2.00/config.py @ 22:f07b7a431ea6

Further 2.00 work Testconfs in all supported kinds of archives should now work. Test runs are now cancelled by pressing Escape rather than Ctrl+C. Improved time control. Greatly improved temporary and helper file cleanup. The pause configuration variable can now be a callable and is now processed using subprocess rather than system().
author Oleg Oshmyan <chortos@inbox.lv>
date Wed, 22 Sep 2010 22:01:56 +0000
parents ec6f1a132109
children c23d81f4a1a3
line wrap: on
line diff
--- a/2.00/config.py	Fri Aug 06 15:39:29 2010 +0000
+++ b/2.00/config.py	Wed Sep 22 22:01:56 2010 +0000
@@ -19,7 +19,7 @@
 else:
 	zipimport = None
 
-import imp, os, sys
+import imp, os, sys, tempfile
 
 __all__ = 'load_problem', 'load_global', 'globalconf'
 
@@ -39,10 +39,10 @@
                     'maxexitcode': 0,
                     'inname': '',
                     'ansname': ''}
+defaults_global = {'tasknames': None,
+                   'force_zero_exitcode': True}
 patterns = ('inname', 'outname', 'ansname', 'testcaseinname',
             'testcaseoutname', 'dummyinname', 'dummyoutname')
-defaults_global = {'tasknames': None,
-                   'force_zero_exitcode': True}
 
 class Config(object):
 	__slots__ = 'modules', '__dict__'
@@ -59,6 +59,26 @@
 		# TODO: provide a message
 		raise AttributeError(name)
 
+# A helper context manager
+class ReadDeleting(object):
+	__slots__ = 'name'
+	
+	def __init__(self, name):
+		self.name = name
+	
+	def __enter__(self):
+		try:
+			return open(self.name, 'rU')
+		except:
+			try:
+				self.__exit__(None, None, None)
+			except:
+				pass
+			raise
+	
+	def __exit__(self, exc_type, exc_val, exc_tb):
+		os.remove(self.name)
+
 def load_problem(problem_name):
 	dwb = sys.dont_write_bytecode
 	sys.dont_write_bytecode = True
@@ -72,9 +92,18 @@
 		else:
 			del sys.modules['testconf']
 	if not module:
-		with metafile.open() as f:
-			module = imp.load_module('testconf', f, metafile.full_real_path, ('.py', 'r', imp.PY_SOURCE))
-			del sys.modules['testconf']
+		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.extract(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:
@@ -117,9 +146,18 @@
 		else:
 			del sys.modules['testconf']
 	if not module:
-		with metafile.open() as f:
-			module = imp.load_module('testconf', f, metafile.full_real_path, ('.py', 'r', imp.PY_SOURCE))
-			del sys.modules['testconf']
+		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.extract(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]))
 	global globalconf