Author: Tyler Wade <[email protected]>
Branch:
Changeset: r64749:711d2a861680
Date: 2013-04-26 17:31 -0500
http://bitbucket.org/pypy/pypy/changeset/711d2a861680/
Log: Add support for -OO flag
diff --git a/lib_pypy/_pypy_irc_topic.py b/lib_pypy/_pypy_irc_topic.py
--- a/lib_pypy/_pypy_irc_topic.py
+++ b/lib_pypy/_pypy_irc_topic.py
@@ -1,4 +1,4 @@
-"""eclguba: flagnk naq frznagvpf bs clguba, fcrrq bs p, erfgevpgvbaf bs wnin
naq pbzcvyre reebe zrffntrf nf crargenoyr nf ZHZCF
+__doc__ = """eclguba: flagnk naq frznagvpf bs clguba, fcrrq bs p, erfgevpgvbaf
bs wnin naq pbzcvyre reebe zrffntrf nf crargenoyr nf ZHZCF
pglcrf unf n fcva bs 1/3
' ' vf n fcnpr gbb
Clguba 2.k rfg cerfdhr zbeg, ivir Clguba!
diff --git a/pypy/bin/pyinteractive.py b/pypy/bin/pyinteractive.py
--- a/pypy/bin/pyinteractive.py
+++ b/pypy/bin/pyinteractive.py
@@ -27,7 +27,7 @@
BoolOption("completer", "use readline commandline completer",
default=False, cmdline="-C"),
BoolOption("optimize",
- "dummy optimization flag for compatibility with CPython",
+ "remove docstrings when importing modules (like CPython -OO)",
default=False, cmdline="-O"),
BoolOption("no_site_import", "do not 'import site' on initialization",
default=False, cmdline="-S"),
@@ -90,6 +90,14 @@
space = option.make_objspace(config)
+ if interactiveconfig.optimize:
+ flags = space.sys.get('flags').getitems_copy()
+ #change optimize flag's value
+ flags[6] = space.wrap(2)
+ flags = type(space.sys.get('flags'))(flags)
+ flags.user_setup(space, space.sys.get('flags').w__class__)
+ space.sys.w_dict.setitem(space.wrap('flags'), flags)
+
space._starttime = starttime
space.setitem(space.sys.w_dict, space.wrap('executable'),
space.wrap(argv[0]))
diff --git a/pypy/doc/man/pypy.1.rst b/pypy/doc/man/pypy.1.rst
--- a/pypy/doc/man/pypy.1.rst
+++ b/pypy/doc/man/pypy.1.rst
@@ -18,6 +18,9 @@
-O
Dummy optimization flag for compatibility with C Python.
+-OO
+ Remove docstrings when importing modules (like CPython -OO).
+
-c *cmd*
Program passed in as CMD (terminates option list).
diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -5,6 +5,7 @@
options:
-i inspect interactively after running script
-O dummy optimization flag for compatibility with C Python
+ -OO remove docstrings when importing modules (like CPython -OO)
-c cmd program passed in as CMD (terminates option list)
-S do not 'import site' on initialization
-u unbuffered binary stdout and stderr
diff --git a/pypy/interpreter/astcompiler/assemble.py
b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -245,6 +245,8 @@
if w_len is None:
w_len = space.len(self.w_consts)
space.setitem(self.w_consts, w_key, w_len)
+ if space.int_w(w_len) == 0:
+ self.scope.doc_removable = False
return space.int_w(w_len)
def _make_key(self, obj):
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
@@ -255,6 +255,7 @@
start = 1
doc_expr.walkabout(self)
self.name_op("__doc__", ast.Store)
+ self.scope.doc_removable = True
for i in range(start, len(body)):
body[i].walkabout(self)
return True
@@ -1189,7 +1190,10 @@
tree.walkabout(self)
def _get_code_flags(self):
- return 0
+ flags = 0
+ if self.scope.doc_removable:
+ flags |= consts.CO_KILL_DOCSTRING
+ return flags
class AbstractFunctionCodeGenerator(PythonCodeGenerator):
@@ -1216,6 +1220,8 @@
flags |= consts.CO_VARARGS
if scope.has_keywords_arg:
flags |= consts.CO_VARKEYWORDS
+ if scope.doc_removable:
+ flags |= consts.CO_KILL_DOCSTRING
if not self.cell_vars and not self.free_vars:
flags |= consts.CO_NOFREE
return PythonCodeGenerator._get_code_flags(self) | flags
@@ -1232,6 +1238,7 @@
doc_expr = None
if doc_expr is not None:
self.add_const(doc_expr.s)
+ self.scope.doc_removable = True
start = 1
else:
self.add_const(self.space.w_None)
@@ -1294,3 +1301,9 @@
self._handle_body(cls.body)
self.emit_op(ops.LOAD_LOCALS)
self.emit_op(ops.RETURN_VALUE)
+
+ def _get_code_flags(self):
+ flags = 0
+ if self.scope.doc_removable:
+ flags |= consts.CO_KILL_DOCSTRING
+ return PythonCodeGenerator._get_code_flags(self) | flags
diff --git a/pypy/interpreter/astcompiler/consts.py
b/pypy/interpreter/astcompiler/consts.py
--- a/pypy/interpreter/astcompiler/consts.py
+++ b/pypy/interpreter/astcompiler/consts.py
@@ -15,6 +15,8 @@
CO_FUTURE_WITH_STATEMENT = 0x8000
CO_FUTURE_PRINT_FUNCTION = 0x10000
CO_FUTURE_UNICODE_LITERALS = 0x20000
+#pypy specific:
+CO_KILL_DOCSTRING = 0x100000
PyCF_SOURCE_IS_UTF8 = 0x0100
PyCF_DONT_IMPLY_DEDENT = 0x0200
diff --git a/pypy/interpreter/astcompiler/symtable.py
b/pypy/interpreter/astcompiler/symtable.py
--- a/pypy/interpreter/astcompiler/symtable.py
+++ b/pypy/interpreter/astcompiler/symtable.py
@@ -42,6 +42,7 @@
self.has_free = False
self.child_has_free = False
self.nested = False
+ self.doc_removable = False
def lookup(self, name):
"""Find the scope of identifier 'name'."""
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py
b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -812,6 +812,37 @@
"""
self.simple_test(source, 'ok', 1)
+ def test_remove_docstring(self):
+ source = '"module_docstring"\n' + """if 1:
+ def f1():
+ 'docstring'
+ def f2():
+ 'docstring'
+ return 'docstring'
+ class C1():
+ 'docstring'
+ class C2():
+ __doc__ = 'docstring'
+ class C3():
+ field = 'not docstring'
+ class C4():
+ 'docstring'
+ field = 'docstring'
+ """
+ code_w = compile_with_astcompiler(source, 'exec', self.space)
+ code_w.remove_docstrings(self.space)
+ dict_w = self.space.newdict();
+ code_w.exec_code(self.space, dict_w, dict_w)
+
+ yield self.check, dict_w, "f1.__doc__", None
+ yield self.check, dict_w, "f2.__doc__", 'docstring'
+ yield self.check, dict_w, "C1.__doc__", None
+ yield self.check, dict_w, "C2.__doc__", 'docstring'
+ yield self.check, dict_w, "C3.field", 'not docstring'
+ yield self.check, dict_w, "C4.field", 'docstring'
+ yield self.check, dict_w, "C4.__doc__", 'docstring'
+ yield self.check, dict_w, "C4.__doc__", 'docstring'
+ yield self.check, dict_w, "__doc__", None
class AppTestCompiler:
diff --git a/pypy/interpreter/pycode.py b/pypy/interpreter/pycode.py
--- a/pypy/interpreter/pycode.py
+++ b/pypy/interpreter/pycode.py
@@ -12,7 +12,7 @@
from pypy.interpreter.gateway import unwrap_spec
from pypy.interpreter.astcompiler.consts import (
CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS, CO_NESTED,
- CO_GENERATOR)
+ CO_GENERATOR, CO_KILL_DOCSTRING)
from pypy.tool.stdlib_opcode import opcodedesc, HAVE_ARGUMENT
from rpython.rlib.rarithmetic import intmask
from rpython.rlib.objectmodel import compute_hash
@@ -218,6 +218,13 @@
return w_first
return space.w_None
+ def remove_docstrings(self, space):
+ if self.co_flags & CO_KILL_DOCSTRING:
+ self.co_consts_w[0] = space.w_None
+ for co_w in self.co_consts_w:
+ if isinstance(co_w, PyCode):
+ co_w.remove_docstrings(space)
+
def _to_code(self):
"""For debugging only."""
consts = [None] * len(self.co_consts_w)
diff --git a/pypy/module/imp/importing.py b/pypy/module/imp/importing.py
--- a/pypy/module/imp/importing.py
+++ b/pypy/module/imp/importing.py
@@ -913,6 +913,13 @@
if not space.is_true(space.sys.get('dont_write_bytecode')):
write_compiled_module(space, code_w, cpathname, mode, mtime)
+ try:
+ optimize = space.sys.get_flag('optimize')
+ except:
+ optimize = 0
+ if optimize >= 2:
+ code_w.remove_docstrings(space)
+
update_code_filenames(space, code_w, pathname)
exec_code_module(space, w_mod, code_w)
@@ -1007,6 +1014,13 @@
"Bad magic number in %s", cpathname)
#print "loading pyc file:", cpathname
code_w = read_compiled_module(space, cpathname, source)
+ try:
+ optimize = space.sys.get_flag('optimize')
+ except:
+ optimize = 0
+ if optimize >= 2:
+ code_w.remove_docstrings(space)
+
exec_code_module(space, w_mod, code_w)
return w_mod
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit