diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst --- a/Doc/c-api/init.rst +++ b/Doc/c-api/init.rst @@ -329,7 +329,8 @@ .. c:function:: void PySys_SetArgv(int argc, wchar_t **argv) - This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set to 1. + This function works like :c:func:`PySys_SetArgvEx` with *updatepath* set + to 1 unless the :program:`python` interpreter was started with the :option:`-I`. .. c:function:: void Py_SetPythonHome(wchar_t *home) diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst --- a/Doc/using/cmdline.rst +++ b/Doc/using/cmdline.rst @@ -24,7 +24,7 @@ When invoking Python, you may specify any of these options:: - python [-bBdEhiOqsSuvVWx?] [-c command | -m module-name | script | - ] [args] + python [-bBdEhiIOqsSuvVWx?] [-c command | -m module-name | script | - ] [args] The most common use case is, of course, a simple invocation of a script:: @@ -208,6 +208,15 @@ raises an exception. See also :envvar:`PYTHONINSPECT`. +.. cmdoption:: -I + + Run Python in isolated mode. This also implies -E and -s. + In isolated mode :data:`sys.path` contains neither the script's directory nor + the user's site-packages directory. All :envvar:`PYTHON*` environment + variables are ignored, too. Further restrictions may be imposed to prevent + the user from injecting malicious code. + + .. cmdoption:: -O Turn on basic optimizations. This changes the filename extension for @@ -382,7 +391,7 @@ --------------------- These environment variables influence Python's behavior, they are processed -before the command-line switches other than -E. It is customary that +before the command-line switches other than -E or -I. It is customary that command-line switches override environmental variables where there is a conflict. diff --git a/Include/pydebug.h b/Include/pydebug.h --- a/Include/pydebug.h +++ b/Include/pydebug.h @@ -20,6 +20,7 @@ PyAPI_DATA(int) Py_NoUserSiteDirectory; PyAPI_DATA(int) Py_UnbufferedStdioFlag; PyAPI_DATA(int) Py_HashRandomizationFlag; +PyAPI_DATA(int) Py_IsolatedFlag; /* this is a wrapper around getenv() that pays attention to Py_IgnoreEnvironmentFlag. It should be used for getting variables like diff --git a/Modules/main.c b/Modules/main.c --- a/Modules/main.c +++ b/Modules/main.c @@ -43,7 +43,7 @@ static int orig_argc; /* command line options */ -#define BASE_OPTS L"bBc:dEhiJm:OqRsStuvVW:xX:?" +#define BASE_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?" #define PROGRAM_OPTS BASE_OPTS @@ -65,6 +65,7 @@ static char *usage_2 = "\ -i : inspect interactively after running script; forces a prompt even\n\ if stdin does not appear to be a terminal; also PYTHONINSPECT=x\n\ +-I : isolate Python from the user's enviroment (implies -E and -s)\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\ @@ -392,6 +393,12 @@ Py_InteractiveFlag++; break; + case 'I': + Py_IsolatedFlag++; + Py_NoUserSiteDirectory++; + Py_IgnoreEnvironmentFlag++; + break; + /* case 'J': reserved for Jython */ case 'O': diff --git a/Python/pythonrun.c b/Python/pythonrun.c --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -93,6 +93,7 @@ int Py_NoUserSiteDirectory = 0; /* for -s and site.py */ int Py_UnbufferedStdioFlag = 0; /* Unbuffered binary std{in,out,err} */ int Py_HashRandomizationFlag = 0; /* for -R and PYTHONHASHSEED */ +int Py_IsolatedFlag = 0; /* for -I, isolate from user's env */ PyThreadState *_Py_Finalizing = NULL; diff --git a/Python/sysmodule.c b/Python/sysmodule.c --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -1357,6 +1357,7 @@ {"bytes_warning", "-b"}, {"quiet", "-q"}, {"hash_randomization", "-R"}, + {"isolated", "-I"}, {0} }; @@ -1365,9 +1366,9 @@ flags__doc__, /* doc */ flags_fields, /* fields */ #ifdef RISCOS + 14 +#else 13 -#else - 12 #endif }; @@ -1401,6 +1402,7 @@ SetFlag(Py_BytesWarningFlag); SetFlag(Py_QuietFlag); SetFlag(Py_HashRandomizationFlag); + SetFlag(Py_IsolatedFlag); #undef SetFlag if (PyErr_Occurred()) { @@ -1925,7 +1927,7 @@ void PySys_SetArgv(int argc, wchar_t **argv) { - PySys_SetArgvEx(argc, argv, 1); + PySys_SetArgvEx(argc, argv, Py_IsolatedFlag == 0); } /* Reimplementation of PyFile_WriteString() no calling indirectly