Add an "optimize" parameter to compile() to control the optimization level, and provide an interface to it in py_compile, compileall and PyZipFile.
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 765464a..f9b3202 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -543,19 +543,20 @@
     int mode = -1;
     int dont_inherit = 0;
     int supplied_flags = 0;
+    int optimize = -1;
     int is_ast;
     PyCompilerFlags cf;
     PyObject *cmd;
     static char *kwlist[] = {"source", "filename", "mode", "flags",
-                             "dont_inherit", NULL};
+                             "dont_inherit", "optimize", NULL};
     int start[] = {Py_file_input, Py_eval_input, Py_single_input};
     PyObject *result;
 
-    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|ii:compile",  kwlist,
+    if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&s|iii:compile",  kwlist,
                                      &cmd,
                                      PyUnicode_FSConverter, &filename_obj,
                                      &startstr, &supplied_flags,
-                                     &dont_inherit))
+                                     &dont_inherit, &optimize))
         return NULL;
 
     filename = PyBytes_AS_STRING(filename_obj);
@@ -570,6 +571,12 @@
     }
     /* XXX Warn if (supplied_flags & PyCF_MASK_OBSOLETE) != 0? */
 
+    if (optimize < -1 || optimize > 2) {
+        PyErr_SetString(PyExc_ValueError,
+                        "compile(): invalid optimize value");
+        goto error;
+    }
+
     if (!dont_inherit) {
         PyEval_MergeCompilerFlags(&cf);
     }
@@ -604,8 +611,8 @@
                 PyArena_Free(arena);
                 goto error;
             }
-            result = (PyObject*)PyAST_Compile(mod, filename,
-                                              &cf, arena);
+            result = (PyObject*)PyAST_CompileEx(mod, filename,
+                                                &cf, optimize, arena);
             PyArena_Free(arena);
         }
         goto finally;
@@ -615,7 +622,7 @@
     if (str == NULL)
         goto error;
 
-    result = Py_CompileStringFlags(str, filename, start[mode], &cf);
+    result = Py_CompileStringExFlags(str, filename, start[mode], &cf, optimize);
     goto finally;
 
 error:
diff --git a/Python/compile.c b/Python/compile.c
index dfb2c9b..1d6e38c 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -139,6 +139,7 @@
     PyFutureFeatures *c_future; /* pointer to module's __future__ */
     PyCompilerFlags *c_flags;
 
+    int c_optimize;              /* optimization level */
     int c_interactive;           /* true if in interactive mode */
     int c_nestlevel;
 
@@ -175,7 +176,7 @@
 static int compiler_in_loop(struct compiler *);
 
 static int inplace_binop(struct compiler *, operator_ty);
-static int expr_constant(expr_ty e);
+static int expr_constant(struct compiler *, expr_ty);
 
 static int compiler_with(struct compiler *, stmt_ty);
 static int compiler_call_helper(struct compiler *c, int n,
@@ -254,8 +255,8 @@
 }
 
 PyCodeObject *
-PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
-              PyArena *arena)
+PyAST_CompileEx(mod_ty mod, const char *filename, PyCompilerFlags *flags,
+                int optimize, PyArena *arena)
 {
     struct compiler c;
     PyCodeObject *co = NULL;
@@ -283,6 +284,7 @@
     c.c_future->ff_features = merged;
     flags->cf_flags = merged;
     c.c_flags = flags;
+    c.c_optimize = (optimize == -1) ? Py_OptimizeFlag : optimize;
     c.c_nestlevel = 0;
 
     c.c_st = PySymtable_Build(mod, filename, c.c_future);
@@ -1149,7 +1151,7 @@
     if (!asdl_seq_LEN(stmts))
         return 1;
     st = (stmt_ty)asdl_seq_GET(stmts, 0);
-    if (compiler_isdocstring(st) && Py_OptimizeFlag < 2) {
+    if (compiler_isdocstring(st) && c->c_optimize < 2) {
         /* don't generate docstrings if -OO */
         i = 1;
         VISIT(c, expr, st->v.Expr.value);
@@ -1463,7 +1465,7 @@
 
     st = (stmt_ty)asdl_seq_GET(s->v.FunctionDef.body, 0);
     docstring = compiler_isdocstring(st);
-    if (docstring && Py_OptimizeFlag < 2)
+    if (docstring && c->c_optimize < 2)
         first_const = st->v.Expr.value->v.Str.s;
     if (compiler_add_o(c, c->u->u_consts, first_const) < 0)      {
         compiler_exit_scope(c);
@@ -1697,7 +1699,7 @@
     if (end == NULL)
         return 0;
 
-    constant = expr_constant(s->v.If.test);
+    constant = expr_constant(c, s->v.If.test);
     /* constant = 0: "if 0"
      * constant = 1: "if 1", "if 2", ...
      * constant = -1: rest */
@@ -1759,7 +1761,7 @@
 compiler_while(struct compiler *c, stmt_ty s)
 {
     basicblock *loop, *orelse, *end, *anchor = NULL;
-    int constant = expr_constant(s->v.While.test);
+    int constant = expr_constant(c, s->v.While.test);
 
     if (constant == 0) {
         if (s->v.While.orelse)
@@ -2211,7 +2213,7 @@
     static PyObject *assertion_error = NULL;
     basicblock *end;
 
-    if (Py_OptimizeFlag)
+    if (c->c_optimize)
         return 1;
     if (assertion_error == NULL) {
         assertion_error = PyUnicode_InternFromString("AssertionError");
@@ -3011,7 +3013,7 @@
  */
 
 static int
-expr_constant(expr_ty e)
+expr_constant(struct compiler *c, expr_ty e)
 {
     char *id;
     switch (e->kind) {
@@ -3029,7 +3031,7 @@
         if (strcmp(id, "False") == 0) return 0;
         if (strcmp(id, "None") == 0) return 0;
         if (strcmp(id, "__debug__") == 0)
-            return ! Py_OptimizeFlag;
+            return ! c->c_optimize;
         /* fall through */
     default:
         return -1;
@@ -4080,3 +4082,13 @@
     assemble_free(&a);
     return co;
 }
+
+#undef PyAST_Compile
+PyAPI_FUNC(PyCodeObject *)
+PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
+              PyArena *arena)
+{
+    return PyAST_CompileEx(mod, filename, flags, -1, arena);
+}
+
+
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 3f6385d..f7335a2 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -1793,8 +1793,8 @@
 }
 
 PyObject *
-Py_CompileStringFlags(const char *str, const char *filename, int start,
-                      PyCompilerFlags *flags)
+Py_CompileStringExFlags(const char *str, const char *filename, int start,
+                        PyCompilerFlags *flags, int optimize)
 {
     PyCodeObject *co;
     mod_ty mod;
@@ -1812,7 +1812,7 @@
         PyArena_Free(arena);
         return result;
     }
-    co = PyAST_Compile(mod, filename, flags, arena);
+    co = PyAST_CompileEx(mod, filename, flags, optimize, arena);
     PyArena_Free(arena);
     return (PyObject *)co;
 }
@@ -2450,7 +2450,15 @@
 PyAPI_FUNC(PyObject *)
 Py_CompileString(const char *str, const char *p, int s)
 {
-    return Py_CompileStringFlags(str, p, s, NULL);
+    return Py_CompileStringExFlags(str, p, s, NULL, -1);
+}
+
+#undef Py_CompileStringFlags
+PyAPI_FUNC(PyObject *)
+Py_CompileStringFlags(const char *str, const char *p, int s,
+                      PyCompilerFlags *flags)
+{
+    return Py_CompileStringExFlags(str, p, s, flags, -1);
 }
 
 #undef PyRun_InteractiveOne