[pypy-commit] pypy py3.3: Handle optimize=1 in calls to compile builtin function (remove asserts).
kvas
noreply at buildbot.pypy.org
Sun Jul 27 11:54:53 CEST 2014
Author: Vasily Kuznetsov <kvas.it at gmail.com>
Branch: py3.3
Changeset: r72553:52aa5e85cfdf
Date: 2014-07-27 11:53 +0200
http://bitbucket.org/pypy/pypy/changeset/52aa5e85cfdf/
Log: Handle optimize=1 in calls to compile builtin function (remove
asserts).
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -435,9 +435,12 @@
self.error("illegal expression for augmented assignment", assign)
def visit_Assert(self, asrt):
+ if self.compile_info.optimize >= 1:
+ return
self.update_position(asrt.lineno)
end = self.new_block()
- self.emit_jump(ops.JUMP_IF_NOT_DEBUG, end)
+ if self.compile_info.optimize != 0:
+ self.emit_jump(ops.JUMP_IF_NOT_DEBUG, end)
asrt.test.accept_jump_if(self, True, end)
self.emit_op_name(ops.LOAD_GLOBAL, self.names, "AssertionError")
if asrt.msg:
diff --git a/pypy/interpreter/pycompiler.py b/pypy/interpreter/pycompiler.py
--- a/pypy/interpreter/pycompiler.py
+++ b/pypy/interpreter/pycompiler.py
@@ -106,7 +106,7 @@
self.additional_rules = {}
self.compiler_flags = self.future_flags.allowed_flags
- def compile_ast(self, node, filename, mode, flags):
+ def compile_ast(self, node, filename, mode, flags, optimize=-1):
if mode == 'eval':
check = isinstance(node, ast.Expression)
elif mode == 'exec':
@@ -123,7 +123,8 @@
f_flags, f_lineno, f_col = fut
future_pos = f_lineno, f_col
flags |= f_flags
- info = pyparse.CompileInfo(filename, mode, flags, future_pos)
+ info = pyparse.CompileInfo(filename, mode, flags, future_pos,
+ optimize=optimize)
return self._compile_ast(node, info)
def _compile_ast(self, node, info):
@@ -163,8 +164,9 @@
e.wrap_info(space))
return mod
- def compile(self, source, filename, mode, flags, hidden_applevel=False):
+ def compile(self, source, filename, mode, flags, hidden_applevel=False,
+ optimize=-1):
info = pyparse.CompileInfo(filename, mode, flags,
- hidden_applevel=hidden_applevel)
+ hidden_applevel=hidden_applevel, optimize=optimize)
mod = self._compile_to_ast(source, info)
return self._compile_ast(mod, info)
diff --git a/pypy/interpreter/pyparser/pyparse.py b/pypy/interpreter/pyparser/pyparse.py
--- a/pypy/interpreter/pyparser/pyparse.py
+++ b/pypy/interpreter/pyparser/pyparse.py
@@ -69,15 +69,21 @@
import.
* hidden_applevel: Will this code unit and sub units be hidden at the
applevel?
+ * optimize: optimization level:
+ -1 = same as interpreter,
+ 0 = no optmiziation,
+ 1 = remove asserts,
+ 2 = remove docstrings.
"""
def __init__(self, filename, mode="exec", flags=0, future_pos=(0, 0),
- hidden_applevel=False):
+ hidden_applevel=False, optimize=-1):
rstring.check_str0(filename)
self.filename = filename
self.mode = mode
self.encoding = None
self.flags = flags
+ self.optimize = optimize
self.last_future_import = future_pos
self.hidden_applevel = hidden_applevel
diff --git a/pypy/module/__builtin__/compiling.py b/pypy/module/__builtin__/compiling.py
--- a/pypy/module/__builtin__/compiling.py
+++ b/pypy/module/__builtin__/compiling.py
@@ -43,13 +43,12 @@
space.w_ValueError,
space.wrap("compile() arg 3 must be 'exec', 'eval' or 'single'"))
- # XXX: optimize flag is not used
-
if space.isinstance_w(w_source, space.gettypeobject(ast.AST.typedef)):
ast_node = space.interp_w(ast.mod, w_source)
ast_node.sync_app_attrs(space)
ec.compiler.validate_ast(ast_node)
- code = ec.compiler.compile_ast(ast_node, filename, mode, flags)
+ code = ec.compiler.compile_ast(ast_node, filename, mode, flags,
+ optimize=optimize)
return space.wrap(code)
flags |= consts.PyCF_SOURCE_IS_UTF8
@@ -59,7 +58,8 @@
if flags & consts.PyCF_ONLY_AST:
code = ec.compiler.compile_to_ast(source, filename, mode, flags)
else:
- code = ec.compiler.compile(source, filename, mode, flags)
+ code = ec.compiler.compile(source, filename, mode, flags,
+ optimize=optimize)
return space.wrap(code)
diff --git a/pypy/module/__builtin__/test/test_compile.py b/pypy/module/__builtin__/test/test_compile.py
new file mode 100644
--- /dev/null
+++ b/pypy/module/__builtin__/test/test_compile.py
@@ -0,0 +1,58 @@
+class AppTestCompile:
+
+ # TODO: This test still fails for now because the docstrings are not
+ # removed with optimize=2.
+ def untest_compile(self):
+ import ast
+
+ codestr = '''def f():
+ """doc"""
+ try:
+ assert False
+ except AssertionError:
+ return (True, f.__doc__)
+ else:
+ return (False, f.__doc__)
+ '''
+
+ def f(): """doc"""
+ values = [(-1, __debug__, f.__doc__),
+ (0, True, 'doc'),
+ (1, False, 'doc'),
+ (2, False, None)]
+
+ for optval, debugval, docstring in values:
+ # test both direct compilation and compilation via AST
+ codeobjs = []
+ codeobjs.append(
+ compile(codestr, "<test>", "exec", optimize=optval))
+ tree = ast.parse(codestr)
+ codeobjs.append(compile(tree, "<test>", "exec", optimize=optval))
+
+ for i, code in enumerate(codeobjs):
+ print(optval, debugval, docstring, i)
+ ns = {}
+ exec(code, ns)
+ rv = ns['f']()
+ assert rv == (debugval, docstring)
+
+ def test_assert_remove(self):
+ """Test just removal of the asserts with optimize=1."""
+ import ast
+
+ code = """def f():
+ assert False
+ """
+ tree = ast.parse(code)
+ for to_compile in [code, tree]:
+ compiled = compile(to_compile, "<test>", "exec", optimize=1)
+ ns = {}
+ exec(compiled, ns)
+ ns['f']()
+
+
+# TODO: Remove docstrings with optimize=2.
+# TODO: Check the value of __debug__ inside of the compiled block!
+# According to the documentation, it should follow the optimize flag.
+# TODO: It would also be good to test that with the assert is not removed and
+# is executed when -O flag is set but optimize=0.
More information about the pypy-commit
mailing list