Index: Python/pythonrun.c =================================================================== --- Python/pythonrun.c (Revision 58468) +++ Python/pythonrun.c (Arbeitskopie) @@ -72,6 +72,7 @@ int Py_InteractiveFlag; /* Needed by Py_FdIsInteractive() below */ int Py_InspectFlag; /* Needed to determine whether to exit at SystemError */ int Py_NoSiteFlag; /* Suppress 'import site' */ +int Py_ReadOnlyBytecodeFlag; /* Suppress writing bytecode files (*.py[co]) */ int Py_UseClassExceptionsFlag = 1; /* Needed by bltinmodule.c: deprecated */ int Py_FrozenFlag; /* Needed by getpath.c */ int Py_UnicodeFlag = 0; /* Needed by compile.c */ @@ -172,6 +173,8 @@ Py_VerboseFlag = add_flag(Py_VerboseFlag, p); if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0') Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p); + if ((p = Py_GETENV("PYTHONNOPYCFILES")) && *p != '\0') + Py_ReadOnlyBytecodeFlag = add_flag(Py_ReadOnlyBytecodeFlag, p); interp = PyInterpreterState_New(); if (interp == NULL) Index: Python/import.c =================================================================== --- Python/import.c (Revision 58468) +++ Python/import.c (Arbeitskopie) @@ -951,8 +951,11 @@ if (Py_VerboseFlag) PySys_WriteStderr("import %s # from %s\n", name, pathname); - if (cpathname) - write_compiled_module(co, cpathname, mtime); + if (cpathname) { + PyObject *ro = PySys_GetObject("readonly_bytecode"); + if (ro == NULL || !PyObject_IsTrue(ro)) + write_compiled_module(co, cpathname, mtime); + } } m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname); Py_DECREF(co); Index: Python/sysmodule.c =================================================================== --- Python/sysmodule.c (Revision 58468) +++ Python/sysmodule.c (Arbeitskopie) @@ -1128,6 +1128,9 @@ v = Py_BuildValue("(ssz)", "CPython", branch, svn_revision); PyDict_SetItemString(sysdict, "subversion", v); Py_XDECREF(v); + PyDict_SetItemString(sysdict, "readonly_bytecode", + v = PyBool_FromLong(Py_ReadOnlyBytecodeFlag)); + Py_XDECREF(v); /* * These release level checks are mutually exclusive and cover * the field, so don't get too fancy with the pre-processor! Index: Include/pydebug.h =================================================================== --- Include/pydebug.h (Revision 58468) +++ Include/pydebug.h (Arbeitskopie) @@ -17,6 +17,7 @@ PyAPI_DATA(int) Py_UnicodeFlag; PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; PyAPI_DATA(int) Py_DivisionWarningFlag; +PyAPI_DATA(int) Py_ReadOnlyBytecodeFlag; /* _XXX Py_QnewFlag should go away in 3.0. It's true iff -Qnew is passed, on the command line, and is used in 2.2 by ceval.c to make all "/" divisions true divisions (which they will be in 3.0). */ Index: Doc/library/sys.rst =================================================================== --- Doc/library/sys.rst (Revision 58468) +++ Doc/library/sys.rst (Arbeitskopie) @@ -457,6 +457,17 @@ implement a dynamic prompt. +.. data:: readonly_bytecode + + If this is true, Python won't try to write ``.pyc`` or ``.pyo`` files on the + import of source modules. This value is initially set to ``True`` or ``False`` + depending on the ``-R`` command line option and the ``PYTHONNOPYCFILES`` + environment variable, but you can set it yourself to control bytecode file + generation. + + .. versionadded:: 2.6 + + .. function:: setcheckinterval(interval) Set the interpreter's "check interval". This integer value determines how often Index: Modules/main.c =================================================================== --- Modules/main.c (Revision 58468) +++ Modules/main.c (Arbeitskopie) @@ -40,7 +40,7 @@ static int orig_argc; /* command line options */ -#define BASE_OPTS "3c:dEhim:OQ:StuUvVW:xX?" +#define BASE_OPTS "3c:dEhim:OQ:RStuUvVW:xX?" #ifndef RISCOS #define PROGRAM_OPTS BASE_OPTS @@ -71,27 +71,30 @@ -O : optimize generated bytecode slightly; also PYTHONOPTIMIZE=x\n\ -OO : remove doc-strings in addition to the -O optimizations\n\ -Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\ +-R : don't write .py[co] files on import; also PYTHONNOPYCFILES=x\n\ -S : don't imply 'import site' on initialization\n\ -t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\ --u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x\n\ "; static char *usage_3 = "\ +-u : unbuffered binary stdout and stderr; also PYTHONUNBUFFERED=x\n\ see man page for details on internal buffering relating to '-u'\n\ -v : verbose (trace import statements); also PYTHONVERBOSE=x\n\ can be supplied multiple times to increase verbosity\n\ -V : print the Python version number and exit (also --version)\n\ -W arg : warning control; arg is action:message:category:module:lineno\n\ -x : skip first line of source, allowing use of non-Unix forms of #!cmd\n\ +"; +static char *usage_4 = "\ -3 : warn about Python 3.x incompatibilities\n\ file : program read from script file\n\ - : program read from stdin (default; interactive mode if a tty)\n\ -"; -static char *usage_4 = "\ arg ...: arguments passed to program in sys.argv[1:]\n\n\ Other environment variables:\n\ PYTHONSTARTUP: file executed on interactive startup (no default)\n\ PYTHONPATH : '%c'-separated list of directories prefixed to the\n\ default module search path. The result is sys.path.\n\ +"; +static char *usage_5 = "\ PYTHONHOME : alternate directory (or %c).\n\ The default module search path uses %s.\n\ PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\ @@ -110,7 +113,8 @@ fprintf(f, usage_1); fprintf(f, usage_2); fprintf(f, usage_3); - fprintf(f, usage_4, DELIM, DELIM, PYTHONHOMEHELP); + fprintf(f, usage_4, DELIM); + fprintf(f, usage_5, DELIM, PYTHONHOMEHELP); } #if defined(__VMS) if (exitcode == 0) { @@ -307,6 +311,10 @@ Py_OptimizeFlag++; break; + case 'R': + Py_ReadOnlyBytecodeFlag++; + break; + case 'S': Py_NoSiteFlag++; break;