From 2da0fceba7dd70334aacbab0708a8cbdff92e31d Mon Sep 17 00:00:00 2001 From: Georg Brandl Date: Mon, 7 Jan 2008 17:09:35 +0000 Subject: Patch #602345 by Neal Norwitz and me: add -B option and PYTHONDONTWRITEBYTECODE envvar to skip writing bytecode. --- Doc/library/sys.rst | 11 +++++++++++ Doc/using/cmdline.rst | 15 +++++++++++++++ Include/pydebug.h | 1 + Misc/NEWS | 4 ++++ Modules/main.c | 20 ++++++++++++++------ Python/import.c | 7 +++++-- Python/pythonrun.c | 3 +++ Python/sysmodule.c | 3 +++ 8 files changed, 56 insertions(+), 8 deletions(-) diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst index 24ce207..a98c5d4 100644 --- a/Doc/library/sys.rst +++ b/Doc/library/sys.rst @@ -507,6 +507,17 @@ always available. when Python is started with the -3 option. +.. data:: dont_write_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 ``-B`` command line option and the ``PYTHONDONTWRITEBYTECODE`` + 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 diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst index 5f6bda5..b113c8f 100644 --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -145,6 +145,14 @@ Generic options Miscellaneous options ~~~~~~~~~~~~~~~~~~~~~ +.. cmdoption:: -B + + If given, Python won't try to write ``.pyc`` or ``.pyo`` files on the + import of source modules. See also :envvar:`PYTHONDONTWRITEBYTECODE`. + + .. versionadded:: 2.6 + + .. cmdoption:: -d Turn on parser debugging output (for wizards only, depending on compilation @@ -411,3 +419,10 @@ Environment variables If this is set, Python ignores case in :keyword:`import` statements. This only works on Windows. + +.. envvar:: PYTHONDONTWRITEBYTECODE + + If given, Python won't try to write ``.pyc`` or ``.pyo`` files on the + import of source modules. + + .. versionadded:: 2.6 diff --git a/Include/pydebug.h b/Include/pydebug.h index 3282dc1..1d24853 100644 --- a/Include/pydebug.h +++ b/Include/pydebug.h @@ -17,6 +17,7 @@ PyAPI_DATA(int) Py_TabcheckFlag; PyAPI_DATA(int) Py_UnicodeFlag; PyAPI_DATA(int) Py_IgnoreEnvironmentFlag; PyAPI_DATA(int) Py_DivisionWarningFlag; +PyAPI_DATA(int) Py_DontWriteBytecodeFlag; /* _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). */ diff --git a/Misc/NEWS b/Misc/NEWS index 3896dd8..dbc0034 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -12,6 +12,10 @@ What's New in Python 2.6 alpha 1? Core and builtins ----------------- +- Patch #602345: Add -B command line option, PYTHONDONTWRITEBYTECODE envvar + and sys.dont_write_bytecode attribute. All these can be set to forbid Python + to attempt to write compiled bytecode files. + - Improve some exception messages when Windows fails to load an extension module. Now we get for example '%1 is not a valid Win32 application' instead of 'error code 193'. diff --git a/Modules/main.c b/Modules/main.c index 26f8780..71c9c59 100644 --- a/Modules/main.c +++ b/Modules/main.c @@ -40,7 +40,7 @@ static char **orig_argv; static int orig_argc; /* command line options */ -#define BASE_OPTS "3c:dEhim:OQ:StuUvVW:xX?" +#define BASE_OPTS "3Bc:dEhim:OQ:StuUvVW:xX?" #ifndef RISCOS #define PROGRAM_OPTS BASE_OPTS @@ -59,39 +59,42 @@ static char *usage_line = /* Long usage message, split into parts < 512 bytes */ static char *usage_1 = "\ Options and arguments (and corresponding environment variables):\n\ +-B : don't write .py[co] files on import; also PYTHONDONTWRITEBYTECODE=x\n\ -c cmd : program passed in as string (terminates option list)\n\ -d : debug output from parser; also PYTHONDEBUG=x\n\ -E : ignore environment variables (such as PYTHONPATH)\n\ -h : print this help message and exit (also --help)\n\ -i : inspect interactively after running script; forces a prompt even\n\ - if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\ "; static char *usage_2 = "\ + if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\ -m mod : run library module as a script (terminates option list)\n\ -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\ -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 @@ usage(int exitcode, char* program) 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) { @@ -337,6 +341,10 @@ Py_Main(int argc, char **argv) Py_OptimizeFlag++; break; + case 'B': + Py_DontWriteBytecodeFlag++; + break; + case 'S': Py_NoSiteFlag++; break; diff --git a/Python/import.c b/Python/import.c index e191bd5..8094f7d 100644 --- a/Python/import.c +++ b/Python/import.c @@ -950,8 +950,11 @@ load_source_module(char *name, char *pathname, FILE *fp) 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("dont_write_bytecode"); + if (ro == NULL || !PyObject_IsTrue(ro)) + write_compiled_module(co, cpathname, mtime); + } } m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname); Py_DECREF(co); diff --git a/Python/pythonrun.c b/Python/pythonrun.c index adae679..4939f54 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -72,6 +72,7 @@ int Py_VerboseFlag; /* Needed by import.c */ 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_DontWriteBytecodeFlag; /* 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_InitializeEx(int install_sigs) 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("PYTHONDONTWRITEBYTECODE")) && *p != '\0') + Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p); interp = PyInterpreterState_New(); if (interp == NULL) diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 2a6a8c3..bd551b5 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1128,6 +1128,9 @@ _PySys_Init(void) v = Py_BuildValue("(ssz)", "CPython", branch, svn_revision); PyDict_SetItemString(sysdict, "subversion", v); Py_XDECREF(v); + PyDict_SetItemString(sysdict, "dont_write_bytecode", + v = PyBool_FromLong(Py_DontWriteBytecodeFlag)); + Py_XDECREF(v); /* * These release level checks are mutually exclusive and cover * the field, so don't get too fancy with the pre-processor! -- cgit v0.12