diff 2.00/config.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 c23d81f4a1a3
children dc4be35d17e0
line wrap: on
line diff
--- a/2.00/config.py	Thu Sep 23 00:11:24 2010 +0000
+++ b/2.00/config.py	Thu Sep 23 23:05:58 2010 +0000
@@ -4,6 +4,7 @@
 from __future__ import division, with_statement
 
 try:
+	from compat import *
 	import files
 except ImportError:
 	import __main__
@@ -61,14 +62,15 @@
 
 # A helper context manager
 class ReadDeleting(object):
-	__slots__ = 'name'
+	__slots__ = 'name', 'file'
 	
 	def __init__(self, name):
 		self.name = name
 	
 	def __enter__(self):
 		try:
-			return open(self.name, 'rU')
+			self.file = open(self.name, 'rU')
+			return self.file
 		except:
 			try:
 				self.__exit__(None, None, None)
@@ -77,6 +79,7 @@
 			raise
 	
 	def __exit__(self, exc_type, exc_val, exc_tb):
+		self.file.close()
 		os.remove(self.name)
 
 def load_problem(problem_name):
@@ -84,26 +87,27 @@
 	sys.dont_write_bytecode = True
 	metafile = files.File('/'.join((problem_name, 'testconf.py')), True, 'configuration')
 	module = None
-	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:
+	with CompatBuiltins():
+		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 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.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:
@@ -139,26 +143,27 @@
 	sys.dont_write_bytecode = True
 	metafile = files.File('testconf.py', True, 'configuration')
 	module = None
-	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:
+	with CompatBuiltins():
+		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 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.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