def test_help(self): config = {} out = StringIO() sandbox = ConfigureSandbox(config, {}, ['configure', '--help'], out, out) sandbox.run(mozpath.join(test_data_path, 'moz.configure')) self.assertEquals({}, config) self.maxDiff = None self.assertEquals( 'Usage: configure [options]\n' '\n' 'Options: [defaults in brackets after descriptions]\n' ' --help print this message\n' ' --enable-simple Enable simple\n' ' --enable-with-env Enable with env\n' ' --enable-values Enable values\n' ' --without-thing Build without thing\n' ' --with-stuff Build with stuff\n' ' --option Option\n' ' --with-returned-default Returned default [not-simple]\n' ' --returned-choices Choices\n' ' --enable-imports-in-template\n' ' Imports in template\n' ' --enable-include Include\n' ' --with-imports Imports\n' '\n' 'Environment variables:\n' ' CC C Compiler\n', out.getvalue() )
def test_help(self): config = {} out = StringIO() sandbox = ConfigureSandbox(config, {}, ['configure', '--help'], out, out) sandbox.run(mozpath.join(test_data_path, 'moz.configure')) self.assertEquals({}, config) self.maxDiff = None self.assertEquals( 'Usage: configure [options]\n' '\n' 'Options: [defaults in brackets after descriptions]\n' ' --help print this message\n' ' --enable-simple Enable simple\n' ' --enable-with-env Enable with env\n' ' --enable-values Enable values\n' ' --without-thing Build without thing\n' ' --with-stuff Build with stuff\n' ' --option Option\n' ' --with-returned-default Returned default [not-simple]\n' ' --returned-choices Choices\n' ' --enable-imports-in-template\n' ' Imports in template\n' ' --enable-include Include\n' ' --with-imports Imports\n' '\n' 'Environment variables:\n' ' CC C Compiler\n', out.getvalue())
def test(val, msg): out = StringIO() sandbox = ConfigureSandbox({}, stdout=out, stderr=out) base_dir = os.path.join(topsrcdir, "build", "moz.configure") sandbox.include_file(os.path.join(base_dir, "checks.configure")) exec_(to_exec, sandbox) sandbox["foo"](val) self.assertEqual(out.getvalue(), msg)
def get_result(self, args=[], environ={}, configure="moz.configure", prog="/bin/configure"): config = {} out = StringIO() sandbox = ConfigureSandbox(config, environ, [prog] + args, out, out) sandbox.run(mozpath.join(test_data_path, configure)) return config, out.getvalue()
def get_result(self, args=[], environ={}, prog='/bin/configure'): config = {} out = StringIO() sandbox = ConfigureSandbox(config, environ, [prog] + args, out, out) sandbox.run(mozpath.join(test_data_path, 'moz.configure')) return config, out.getvalue()
def main(argv): config = {} sandbox = ConfigureSandbox(config, os.environ, argv) sandbox.run(os.path.join(os.path.dirname(__file__), 'moz.configure')) if sandbox._help: return 0 return config_status(config)
def test_decorators(self): config = {} out = StringIO() sandbox = ConfigureSandbox(config, {}, [], out, out) sandbox.exec_file(mozpath.join(test_data_path, "decorators.configure")) self.assertNotIn("FOO", sandbox) self.assertNotIn("BAR", sandbox) self.assertNotIn("QUX", sandbox)
def test_decorators(self): config = {} out = StringIO() sandbox = ConfigureSandbox(config, {}, [], out, out) sandbox.include_file(mozpath.join(test_data_path, 'decorators.configure')) self.assertNotIn('FOO', sandbox) self.assertNotIn('BAR', sandbox) self.assertNotIn('QUX', sandbox)
def test_decorators(self): config = {} out = StringIO() sandbox = ConfigureSandbox(config, {}, [], out, out) sandbox.exec_file(mozpath.join(test_data_path, 'decorators.configure')) self.assertNotIn('FOO', sandbox) self.assertNotIn('BAR', sandbox) self.assertNotIn('QUX', sandbox)
def get_config(self, options=[], env={}, configure='moz.configure', prog='/bin/configure'): config = {} out = StringIO() sandbox = ConfigureSandbox(config, env, [prog] + options, out, out) sandbox.run(mozpath.join(test_data_path, configure)) if '--help' not in options: self.assertEquals('', out.getvalue()) return config
def main(argv): config = {} sandbox = ConfigureSandbox(config, os.environ, argv) sandbox.run(os.path.join(os.path.dirname(__file__), 'moz.configure')) if sandbox._help: return 0 # Sanitize config data to feed config.status sanitized_config = {} sanitized_config['substs'] = { k: v for k, v in config.iteritems() if k not in ('DEFINES', 'non_global_defines', 'TOPSRCDIR', 'TOPOBJDIR') } sanitized_config['defines'] = config['DEFINES'] sanitized_config['non_global_defines'] = config['non_global_defines'] sanitized_config['topsrcdir'] = config['TOPSRCDIR'] sanitized_config['topobjdir'] = config['TOPOBJDIR'] # Create config.status. Eventually, we'll want to just do the work it does # here, when we're able to skip configure tests/use cached results/not rely # on autoconf. print("Creating config.status", file=sys.stderr) encoding = 'mbcs' if sys.platform == 'win32' else 'utf-8' with codecs.open('config.status', 'w', encoding) as fh: fh.write('#!%s\n' % config['PYTHON']) fh.write('# coding=%s\n' % encoding) for k, v in sanitized_config.iteritems(): fh.write('%s = ' % k) json.dump(v, fh, sort_keys=True, indent=4, ensure_ascii=False) fh.write('\n') fh.write("__all__ = ['topobjdir', 'topsrcdir', 'defines', " "'non_global_defines', 'substs']") if not config.get('BUILDING_JS') or config.get('JS_STANDALONE'): fh.write(''' if __name__ == '__main__': args = dict([(name, globals()[name]) for name in __all__]) from mozbuild.config_status import config_status config_status(**args) ''') # Other things than us are going to run this file, so we need to give it # executable permissions. os.chmod('config.status', 0755) if not config.get('BUILDING_JS') or config.get('JS_STANDALONE'): if not config.get('JS_STANDALONE'): os.environ['WRITE_MOZINFO'] = '1' # Until we have access to the virtualenv from this script, execute # config.status externally, with the virtualenv python. return subprocess.call([config['PYTHON'], 'config.status']) return 0
def main(argv): config = {} sandbox = ConfigureSandbox(config, os.environ, argv) if os.environ.get('MOZ_CONFIGURE_TRACE'): sandbox._logger.setLevel(TRACE) sandbox.run(os.path.join(os.path.dirname(__file__), 'moz.configure')) if sandbox._help: return 0 return config_status(config)
def main(argv): _activate_build_virtualenv() config = {} if "OLD_CONFIGURE" not in os.environ: os.environ["OLD_CONFIGURE"] = os.path.join(base_dir, "old-configure") sandbox = ConfigureSandbox(config, os.environ, argv) clobber_file = "CLOBBER" if not os.path.exists(clobber_file): # Simply touch the file. with open(clobber_file, "a"): pass if os.environ.get("MOZ_CONFIGURE_TRACE"): sandbox._logger.setLevel(TRACE) sandbox.run(os.path.join(os.path.dirname(__file__), "moz.configure")) if sandbox._help: return 0 logging.getLogger("moz.configure").info("Creating config.status") old_js_configure_substs = config.pop("OLD_JS_CONFIGURE_SUBSTS", None) old_js_configure_defines = config.pop("OLD_JS_CONFIGURE_DEFINES", None) if old_js_configure_substs or old_js_configure_defines: js_config = config.copy() pwd = os.getcwd() try: try: os.makedirs("js/src") except OSError as e: if e.errno != errno.EEXIST: raise os.chdir("js/src") js_config["OLD_CONFIGURE_SUBSTS"] = old_js_configure_substs js_config["OLD_CONFIGURE_DEFINES"] = old_js_configure_defines # The build system frontend expects $objdir/js/src/config.status # to have $objdir/js/src as topobjdir. # We want forward slashes on all platforms. js_config["TOPOBJDIR"] += "/js/src" config_status(js_config, execute=False) finally: os.chdir(pwd) return config_status(config)
def main(argv): config = {} sandbox = ConfigureSandbox(config, os.environ, argv) clobber_file = 'CLOBBER' if not os.path.exists(clobber_file): # Simply touch the file. with open(clobber_file, 'a'): pass if os.environ.get('MOZ_CONFIGURE_TRACE'): sandbox._logger.setLevel(TRACE) sandbox.run(os.path.join(os.path.dirname(__file__), 'moz.configure')) if sandbox._help: return 0 logging.getLogger('moz.configure').info('Creating config.status') old_js_configure_substs = config.pop('OLD_JS_CONFIGURE_SUBSTS', None) old_js_configure_defines = config.pop('OLD_JS_CONFIGURE_DEFINES', None) if old_js_configure_substs or old_js_configure_defines: js_config = config.copy() pwd = os.getcwd() try: try: os.makedirs('js/src') except OSError as e: if e.errno != errno.EEXIST: raise os.chdir('js/src') js_config['OLD_CONFIGURE_SUBSTS'] = old_js_configure_substs js_config['OLD_CONFIGURE_DEFINES'] = old_js_configure_defines # The build system frontend expects $objdir/js/src/config.status # to have $objdir/js/src as topobjdir. # We want forward slashes on all platforms. js_config['TOPOBJDIR'] += '/js/src' config_status(js_config, execute=False) finally: os.chdir(pwd) return config_status(config)
def get_value_for(self, key, args=[], environ={}, mozconfig=''): os.chdir(topobjdir) config = {} out = StringIO() fh, mozconfig_path = tempfile.mkstemp() os.write(fh, mozconfig) os.close(fh) try: environ = dict(environ, OLD_CONFIGURE=os.path.join(topsrcdir, 'configure'), MOZCONFIG=mozconfig_path) sandbox = ConfigureSandbox(config, environ, ['configure'] + args, out, out) sandbox.include_file(os.path.join(topsrcdir, 'moz.configure')) # Add a fake old-configure option sandbox.option_impl('--with-foo', nargs='*', help='Help missing for old configure options') return sandbox._value_for(sandbox[key]) finally: os.remove(mozconfig_path)
def main(argv): config = {} sandbox = ConfigureSandbox(config, os.environ, argv) clobber_file = 'CLOBBER' if not os.path.exists(clobber_file): # Simply touch the file. with open(clobber_file, 'a'): pass if os.environ.get('MOZ_CONFIGURE_TRACE'): sandbox._logger.setLevel(TRACE) sandbox.run(os.path.join(os.path.dirname(__file__), 'moz.configure')) if sandbox._help: return 0 return config_status(config)
def test_non_ascii_subprocess_output(self): out = StringIO() sandbox = ConfigureSandbox({}, {}, ['configure'], out, out) sandbox.include_file(mozpath.join(topsrcdir, 'build', 'moz.configure', 'util.configure')) sandbox.include_file(mozpath.join(topsrcdir, 'python', 'mozbuild', 'mozbuild', 'test', 'configure', 'data', 'subprocess.configure')) status = 0 try: sandbox.run() except SystemExit as e: status = e.code self.assertEquals(status, 0) quote_char = "'" if getpreferredencoding().lower() == 'utf-8': quote_char = '\u00B4'.encode('utf-8') self.assertEquals(out.getvalue().strip(), quote_char)
def test_non_ascii_subprocess_output(self): out = StringIO() sandbox = ConfigureSandbox({}, {}, [], out, out) sandbox.include_file(mozpath.join(topsrcdir, 'build', 'moz.configure', 'util.configure')) sandbox.include_file(mozpath.join(topsrcdir, 'python', 'mozbuild', 'mozbuild', 'test', 'configure', 'data', 'subprocess.configure')) status = 0 try: sandbox.run() except SystemExit as e: status = e.code self.assertEquals(status, 0) quote_char = "'" if getpreferredencoding().lower() == 'utf-8': quote_char = '\u00B4'.encode('utf-8') self.assertEquals(out.getvalue().strip(), quote_char)
def get_value_for(self, key, args=[], environ={}, mozconfig=""): os.chdir(topobjdir) config = {} out = StringIO() fh, mozconfig_path = tempfile.mkstemp() os.write(fh, mozconfig) os.close(fh) try: environ = dict(environ, OLD_CONFIGURE=os.path.join(topsrcdir, "configure"), MOZCONFIG=mozconfig_path) sandbox = ConfigureSandbox(config, environ, ["configure"] + args, out, out) sandbox.include_file(os.path.join(topsrcdir, "moz.configure")) # Add a fake old-configure option sandbox.option_impl("--with-foo", nargs="*", help="Help missing for old configure options") return sandbox._value_for(sandbox[key]) finally: os.remove(mozconfig_path)
def test_imports(self): config = {} out = StringIO() sandbox = ConfigureSandbox(config, {}, [], out, out) with self.assertRaises(ImportError): exec_(textwrap.dedent(''' @template def foo(): import sys foo()'''), sandbox ) exec_(textwrap.dedent(''' @template @imports('sys') def foo(): return sys'''), sandbox ) self.assertIs(sandbox['foo'](), sys) exec_(textwrap.dedent(''' @template @imports(_from='os', _import='path') def foo(): return path'''), sandbox ) self.assertIs(sandbox['foo'](), os.path) exec_(textwrap.dedent(''' @template @imports(_from='os', _import='path', _as='os_path') def foo(): return os_path'''), sandbox ) self.assertIs(sandbox['foo'](), os.path) exec_(textwrap.dedent(''' @template @imports('__builtin__') def foo(): return __builtin__'''), sandbox ) import __builtin__ self.assertIs(sandbox['foo'](), __builtin__) exec_(textwrap.dedent(''' @template @imports(_from='__builtin__', _import='open') def foo(): return open('%s')''' % os.devnull), sandbox ) f = sandbox['foo']() self.assertEquals(f.name, os.devnull) f.close() # This unlocks the sandbox exec_(textwrap.dedent(''' @template @imports(_import='__builtin__', _as='__builtins__') def foo(): import sys return sys'''), sandbox ) self.assertIs(sandbox['foo'](), sys) exec_(textwrap.dedent(''' @template @imports('__sandbox__') def foo(): return __sandbox__'''), sandbox ) self.assertIs(sandbox['foo'](), sandbox) exec_(textwrap.dedent(''' @template @imports(_import='__sandbox__', _as='s') def foo(): return s'''), sandbox ) self.assertIs(sandbox['foo'](), sandbox) # Nothing leaked from the function being executed self.assertEquals(sandbox.keys(), ['__builtins__', 'foo']) self.assertEquals(sandbox['__builtins__'], ConfigureSandbox.BUILTINS) exec_(textwrap.dedent(''' @template @imports('sys') def foo(): @depends(when=True) def bar(): return sys return bar bar = foo()'''), sandbox ) with self.assertRaises(NameError) as e: sandbox._depends[sandbox['bar']].result self.assertEquals(e.exception.message, "global name 'sys' is not defined")
def test_checking(self): out = StringIO() sandbox = ConfigureSandbox({}, stdout=out, stderr=out) base_dir = os.path.join(topsrcdir, 'build', 'moz.configure') sandbox.include_file(os.path.join(base_dir, 'checks.configure')) exec_(textwrap.dedent(''' @checking('for a thing') def foo(value): return value '''), sandbox) foo = sandbox['foo'] foo(True) self.assertEqual(out.getvalue(), 'checking for a thing... yes\n') out.truncate(0) foo(False) self.assertEqual(out.getvalue(), 'checking for a thing... no\n') out.truncate(0) foo(42) self.assertEqual(out.getvalue(), 'checking for a thing... 42\n') out.truncate(0) foo('foo') self.assertEqual(out.getvalue(), 'checking for a thing... foo\n') out.truncate(0) data = ['foo', 'bar'] foo(data) self.assertEqual(out.getvalue(), 'checking for a thing... %r\n' % data) # When the function given to checking does nothing interesting, the # behavior is not altered exec_(textwrap.dedent(''' @checking('for a thing', lambda x: x) def foo(value): return value '''), sandbox) foo = sandbox['foo'] out.truncate(0) foo(True) self.assertEqual(out.getvalue(), 'checking for a thing... yes\n') out.truncate(0) foo(False) self.assertEqual(out.getvalue(), 'checking for a thing... no\n') out.truncate(0) foo(42) self.assertEqual(out.getvalue(), 'checking for a thing... 42\n') out.truncate(0) foo('foo') self.assertEqual(out.getvalue(), 'checking for a thing... foo\n') out.truncate(0) data = ['foo', 'bar'] foo(data) self.assertEqual(out.getvalue(), 'checking for a thing... %r\n' % data) exec_(textwrap.dedent(''' def munge(x): if not x: return 'not found' if isinstance(x, (str, bool, int)): return x return ' '.join(x) @checking('for a thing', munge) def foo(value): return value '''), sandbox) foo = sandbox['foo'] out.truncate(0) foo(True) self.assertEqual(out.getvalue(), 'checking for a thing... yes\n') out.truncate(0) foo(False) self.assertEqual(out.getvalue(), 'checking for a thing... not found\n') out.truncate(0) foo(42) self.assertEqual(out.getvalue(), 'checking for a thing... 42\n') out.truncate(0) foo('foo') self.assertEqual(out.getvalue(), 'checking for a thing... foo\n') out.truncate(0) foo(['foo', 'bar']) self.assertEqual(out.getvalue(), 'checking for a thing... foo bar\n')
def test_checking(self): out = StringIO() sandbox = ConfigureSandbox({}, stdout=out, stderr=out) base_dir = os.path.join(topsrcdir, 'build', 'moz.configure') sandbox.include_file(os.path.join(base_dir, 'checks.configure')) exec_( textwrap.dedent(''' @checking('for a thing') def foo(value): return value '''), sandbox) foo = sandbox['foo'] foo(True) self.assertEqual(out.getvalue(), 'checking for a thing... yes\n') out.truncate(0) foo(False) self.assertEqual(out.getvalue(), 'checking for a thing... no\n') out.truncate(0) foo(42) self.assertEqual(out.getvalue(), 'checking for a thing... 42\n') out.truncate(0) foo('foo') self.assertEqual(out.getvalue(), 'checking for a thing... foo\n') out.truncate(0) data = ['foo', 'bar'] foo(data) self.assertEqual(out.getvalue(), 'checking for a thing... %r\n' % data) # When the function given to checking does nothing interesting, the # behavior is not altered exec_( textwrap.dedent(''' @checking('for a thing', lambda x: x) def foo(value): return value '''), sandbox) foo = sandbox['foo'] out.truncate(0) foo(True) self.assertEqual(out.getvalue(), 'checking for a thing... yes\n') out.truncate(0) foo(False) self.assertEqual(out.getvalue(), 'checking for a thing... no\n') out.truncate(0) foo(42) self.assertEqual(out.getvalue(), 'checking for a thing... 42\n') out.truncate(0) foo('foo') self.assertEqual(out.getvalue(), 'checking for a thing... foo\n') out.truncate(0) data = ['foo', 'bar'] foo(data) self.assertEqual(out.getvalue(), 'checking for a thing... %r\n' % data) exec_( textwrap.dedent(''' def munge(x): if not x: return 'not found' if isinstance(x, (str, bool, int)): return x return ' '.join(x) @checking('for a thing', munge) def foo(value): return value '''), sandbox) foo = sandbox['foo'] out.truncate(0) foo(True) self.assertEqual(out.getvalue(), 'checking for a thing... yes\n') out.truncate(0) foo(False) self.assertEqual(out.getvalue(), 'checking for a thing... not found\n') out.truncate(0) foo(42) self.assertEqual(out.getvalue(), 'checking for a thing... 42\n') out.truncate(0) foo('foo') self.assertEqual(out.getvalue(), 'checking for a thing... foo\n') out.truncate(0) foo(['foo', 'bar']) self.assertEqual(out.getvalue(), 'checking for a thing... foo bar\n')
def test_imports(self): config = {} out = StringIO() sandbox = ConfigureSandbox(config, {}, ['configure'], out, out) with self.assertRaises(ImportError): exec_( textwrap.dedent(''' @template def foo(): import sys foo()'''), sandbox) exec_( textwrap.dedent(''' @template @imports('sys') def foo(): return sys'''), sandbox) self.assertIs(sandbox['foo'](), sys) exec_( textwrap.dedent(''' @template @imports(_from='os', _import='path') def foo(): return path'''), sandbox) self.assertIs(sandbox['foo'](), os.path) exec_( textwrap.dedent(''' @template @imports(_from='os', _import='path', _as='os_path') def foo(): return os_path'''), sandbox) self.assertIs(sandbox['foo'](), os.path) exec_( textwrap.dedent(''' @template @imports('__builtin__') def foo(): return __builtin__'''), sandbox) import __builtin__ self.assertIs(sandbox['foo'](), __builtin__) exec_( textwrap.dedent(''' @template @imports(_from='__builtin__', _import='open') def foo(): return open('%s')''' % os.devnull), sandbox) f = sandbox['foo']() self.assertEquals(f.name, os.devnull) f.close() # This unlocks the sandbox exec_( textwrap.dedent(''' @template @imports(_import='__builtin__', _as='__builtins__') def foo(): import sys return sys'''), sandbox) self.assertIs(sandbox['foo'](), sys) exec_( textwrap.dedent(''' @template @imports('__sandbox__') def foo(): return __sandbox__'''), sandbox) self.assertIs(sandbox['foo'](), sandbox) exec_( textwrap.dedent(''' @template @imports(_import='__sandbox__', _as='s') def foo(): return s'''), sandbox) self.assertIs(sandbox['foo'](), sandbox) # Nothing leaked from the function being executed self.assertEquals(sandbox.keys(), ['__builtins__', 'foo']) self.assertEquals(sandbox['__builtins__'], ConfigureSandbox.BUILTINS) exec_( textwrap.dedent(''' @template @imports('sys') def foo(): @depends(when=True) def bar(): return sys return bar bar = foo()'''), sandbox) with self.assertRaises(NameError) as e: sandbox._depends[sandbox['bar']].result() self.assertEquals(e.exception.message, "global name 'sys' is not defined")
def test_imports(self): config = {} out = StringIO() sandbox = ConfigureSandbox(config, {}, [], out, out) with self.assertRaises(ImportError): exec( textwrap.dedent( """ @template def foo(): import sys foo()""" ), sandbox, ) exec( textwrap.dedent( """ @template @imports('sys') def foo(): return sys""" ), sandbox, ) self.assertIs(sandbox["foo"](), sys) exec( textwrap.dedent( """ @template @imports(_from='os', _import='path') def foo(): return path""" ), sandbox, ) self.assertIs(sandbox["foo"](), os.path) exec( textwrap.dedent( """ @template @imports(_from='os', _import='path', _as='os_path') def foo(): return os_path""" ), sandbox, ) self.assertIs(sandbox["foo"](), os.path) exec( textwrap.dedent( """ @template @imports('__builtin__') def foo(): return __builtin__""" ), sandbox, ) import __builtin__ self.assertIs(sandbox["foo"](), __builtin__) exec( textwrap.dedent( """ @template @imports(_from='__builtin__', _import='open') def foo(): return open('%s')""" % os.devnull ), sandbox, ) f = sandbox["foo"]() self.assertEquals(f.name, os.devnull) f.close() # This unlocks the sandbox exec( textwrap.dedent( """ @template @imports(_import='__builtin__', _as='__builtins__') def foo(): import sys return sys""" ), sandbox, ) self.assertIs(sandbox["foo"](), sys) exec( textwrap.dedent( """ @template @imports('__sandbox__') def foo(): return __sandbox__""" ), sandbox, ) self.assertIs(sandbox["foo"](), sandbox) exec( textwrap.dedent( """ @template @imports(_import='__sandbox__', _as='s') def foo(): return s""" ), sandbox, ) self.assertIs(sandbox["foo"](), sandbox) # Nothing leaked from the function being executed self.assertEquals(sandbox.keys(), ["__builtins__", "foo"]) self.assertEquals(sandbox["__builtins__"], ConfigureSandbox.BUILTINS)
def test_imports(self): config = {} out = StringIO() sandbox = ConfigureSandbox(config, {}, [], out, out) with self.assertRaises(ImportError): exec( textwrap.dedent(''' @template def foo(): import sys foo()'''), sandbox) exec( textwrap.dedent(''' @template @imports('sys') def foo(): return sys'''), sandbox) self.assertIs(sandbox['foo'](), sys) exec( textwrap.dedent(''' @template @imports(_from='os', _import='path') def foo(): return path'''), sandbox) self.assertIs(sandbox['foo'](), os.path) exec( textwrap.dedent(''' @template @imports(_from='os', _import='path', _as='os_path') def foo(): return os_path'''), sandbox) self.assertIs(sandbox['foo'](), os.path) exec( textwrap.dedent(''' @template @imports('__builtin__') def foo(): return __builtin__'''), sandbox) import __builtin__ self.assertIs(sandbox['foo'](), __builtin__) exec( textwrap.dedent(''' @template @imports(_from='__builtin__', _import='open') def foo(): return open('%s')''' % os.devnull), sandbox) f = sandbox['foo']() self.assertEquals(f.name, os.devnull) f.close() # This unlocks the sandbox exec( textwrap.dedent(''' @template @imports(_import='__builtin__', _as='__builtins__') def foo(): import sys return sys'''), sandbox) self.assertIs(sandbox['foo'](), sys) exec( textwrap.dedent(''' @template @imports('__sandbox__') def foo(): return __sandbox__'''), sandbox) self.assertIs(sandbox['foo'](), sandbox) exec( textwrap.dedent(''' @template @imports(_import='__sandbox__', _as='s') def foo(): return s'''), sandbox) self.assertIs(sandbox['foo'](), sandbox) # Nothing leaked from the function being executed self.assertEquals(sandbox.keys(), ['__builtins__', 'foo']) self.assertEquals(sandbox['__builtins__'], ConfigureSandbox.BUILTINS)