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

Reply via email to