changeset 70:b9d5857f7b9a

Better emulation of built-ins for testconf Bug fix: next is now in compat.__all__. Members of compat that do not correspond to built-ins or members of itertools are no longer added to built-ins while loading testconf. xrange is now added to built-ins only while loading testconf and only in legacy mode. testconf can now access the original built-ins through the CompatBuiltins context manager which is now exposed as config.builtins. Bug fix: the default string encoding is no longer relied upon.
author Oleg Oshmyan <chortos@inbox.lv>
date Mon, 03 Jan 2011 01:27:56 +0200
parents c0f1b87013ad
children 1bee3a0beeb5
files compat.py config.py upreckon-vcs
diffstat 3 files changed, 37 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/compat.py	Mon Jan 03 01:07:02 2011 +0200
+++ b/compat.py	Mon Jan 03 01:27:56 2011 +0200
@@ -43,9 +43,9 @@
 except ImportError:
 	import __builtin__ as builtins
 
-__all__ = ('say', 'basestring', 'range', 'map', 'zip', 'filter', 'items',
-           'keys', 'values', 'zip_longest', 'callable',
-           'ABCMeta', 'abstractmethod', 'CompatBuiltins')
+pseudobuiltins = ('say', 'basestring', 'range', 'map', 'zip', 'filter', 'next',
+                  'items', 'keys', 'values', 'zip_longest', 'callable')
+__all__ = pseudobuiltins + ('ABCMeta', 'abstractmethod', 'CompatBuiltins')
 
 try:
 	# Python 3
@@ -135,7 +135,7 @@
 	try:
 		# Python 3
 		import urllib.request
-		return urllib.request, lambda url: urllib.request.urlopen(url).read().decode()
+		return urllib.request, lambda url: urllib.request.urlopen(url).read().decode('ascii')
 	except ImportError:
 		# Python 2
 		import urllib
@@ -146,19 +146,16 @@
 except ImportError:
 	ABCMeta, abstractmethod = None, lambda x: x
 
-# In all of the following, the try clause is for Python 2 and the except
-# clause is for Python 3. More checks are performed than needed
-# for standard builds of Python to ensure as much as possible works
-# on custom builds.
 try:
 	basestring = basestring
 except NameError:
 	basestring = str
 
+# xrange is set to support simple testconf.py's written for test.py 1.x
 try:
-	range = xrange
+	xrange = range = xrange
 except NameError:
-	range = range
+	xrange = range = range
 
 try:
 	callable = callable
@@ -186,9 +183,20 @@
 except ImportError:
 	filter = filter
 
-items = dict.iteritems if hasattr(dict, 'iteritems') else dict.items
-keys = dict.iterkeys if hasattr(dict, 'iterkeys') else dict.keys
-values = dict.itervalues if hasattr(dict, 'itervalues') else dict.values
+try:
+	items = dict.iteritems
+except AttributeError:
+	items = dict.items
+
+try:
+	keys = dict.iterkeys
+except AttributeError:
+	keys = dict.keys
+
+try:
+	values = dict.itervalues
+except AttributeError:
+	values = dict.values
 
 try:
 	# Python 3
@@ -216,17 +224,16 @@
 # Automatically import * from this module into testconf.py's
 class CompatBuiltins(object):
 	__slots__ = 'originals'
-	def __init__(self):
-		self.originals = {}
+	globals = globals()
 	def __enter__(self):
-		g = globals()
-		for name in __all__:
-			if hasattr(builtins, name):
+		self.originals = {}
+		for name in pseudobuiltins:
+			try:
 				self.originals[name] = getattr(builtins, name)
-			setattr(builtins, name, g[name])
+			except AttributeError:
+				pass
+			setattr(builtins, name, self.globals[name])
+		return self
 	def __exit__(self, exc_type, exc_val, exc_tb):
 		for name in self.originals:
-			setattr(builtins, name, self.originals[name])
-
-# Support simple testconf.py's written for test.py 1.x
-builtins.xrange = range
\ No newline at end of file
+			setattr(builtins, name, self.originals[name])
\ No newline at end of file
--- a/config.py	Mon Jan 03 01:07:02 2011 +0200
+++ b/config.py	Mon Jan 03 01:27:56 2011 +0200
@@ -86,11 +86,12 @@
 		os.remove(self.name)
 
 def load_problem(problem_name):
+	global builtins
 	dwb = sys.dont_write_bytecode
 	sys.dont_write_bytecode = True
 	metafile = files.File('/'.join((problem_name, 'testconf.py')), True, 'configuration')
 	module = None
-	with CompatBuiltins():
+	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')
@@ -154,11 +155,12 @@
 	return module
 
 def load_global():
+	global builtins
 	dwb = sys.dont_write_bytecode
 	sys.dont_write_bytecode = True
 	metafile = files.File('testconf.py', True, 'configuration')
 	module = None
-	with CompatBuiltins():
+	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')
--- a/upreckon-vcs	Mon Jan 03 01:07:02 2011 +0200
+++ b/upreckon-vcs	Mon Jan 03 01:27:56 2011 +0200
@@ -61,6 +61,9 @@
 
 import config, itertools, os, subprocess, sys, time
 
+if options.legacy:
+	compat.pseudobuiltins += 'xrange',
+
 if options.autotime:
 	# This is really a dirty hack that assumes that sleep() does not spend
 	# the CPU time of the current process and that if clock() measures