summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/c-api/init.rst6
-rw-r--r--Doc/using/cmdline.rst17
-rw-r--r--Doc/whatsnew/3.4.rst3
-rw-r--r--Include/pydebug.h1
-rw-r--r--Lib/test/test_cmd_line.py26
-rw-r--r--Lib/test/test_sys.py2
-rw-r--r--Misc/NEWS2
-rw-r--r--Misc/python.man14
-rw-r--r--Modules/main.c9
-rw-r--r--Python/pythonrun.c1
-rw-r--r--Python/sysmodule.c6
11 files changed, 77 insertions, 10 deletions
diff --git a/Doc/c-api/init.rst b/Doc/c-api/init.rst
index 6f847d9..32007d5 100644
--- a/Doc/c-api/init.rst
+++ b/Doc/c-api/init.rst
@@ -329,7 +329,11 @@ Process-wide parameters
.. 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`.
+
+ .. versionchanged:: 3.4 The *updatepath* value depends on :option:`-I`.
.. c:function:: void Py_SetPythonHome(wchar_t *home)
diff --git a/Doc/using/cmdline.rst b/Doc/using/cmdline.rst
index a7273bc..c14f6c7 100644
--- a/Doc/using/cmdline.rst
+++ b/Doc/using/cmdline.rst
@@ -24,7 +24,7 @@ Command line
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::
@@ -175,6 +175,8 @@ Generic options
Python 3.0
+.. _using-on-misc-options:
+
Miscellaneous options
~~~~~~~~~~~~~~~~~~~~~
@@ -213,6 +215,17 @@ Miscellaneous options
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.
+
+ .. versionadded:: 3.4
+
+
.. cmdoption:: -O
Turn on basic optimizations. This changes the filename extension for
@@ -398,7 +411,7 @@ Environment variables
---------------------
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/Doc/whatsnew/3.4.rst b/Doc/whatsnew/3.4.rst
index 6011f8e..0333c11 100644
--- a/Doc/whatsnew/3.4.rst
+++ b/Doc/whatsnew/3.4.rst
@@ -107,7 +107,8 @@ Significantly Improved Library Modules:
Security improvements:
-* None yet.
+* command line option for :ref:`isolated mode <using-on-misc-options>`,
+ :issue:`16499`.
Please read on for a comprehensive list of user-facing changes.
diff --git a/Include/pydebug.h b/Include/pydebug.h
index 97c2f8c..8fe9818 100644
--- a/Include/pydebug.h
+++ b/Include/pydebug.h
@@ -20,6 +20,7 @@ PyAPI_DATA(int) Py_DontWriteBytecodeFlag;
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/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index 3fa8ade..efe4546 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -4,6 +4,7 @@
import test.support, unittest
import os
+import shutil
import sys
import subprocess
import tempfile
@@ -439,6 +440,31 @@ class CmdLineTest(unittest.TestCase):
self.assertEqual(b'', out)
+ def test_isolatedmode(self):
+ self.verify_valid_flag('-I')
+ self.verify_valid_flag('-IEs')
+ rc, out, err = assert_python_ok('-I', '-c',
+ 'from sys import flags as f; '
+ 'print(f.no_user_site, f.ignore_environment, f.isolated)',
+ # dummyvar to prevent extranous -E
+ dummyvar="")
+ self.assertEqual(out.strip(), b'1 1 1')
+ with test.support.temp_cwd() as tmpdir:
+ fake = os.path.join(tmpdir, "uuid.py")
+ main = os.path.join(tmpdir, "main.py")
+ with open(fake, "w") as f:
+ f.write("raise RuntimeError('isolated mode test')\n")
+ with open(main, "w") as f:
+ f.write("import uuid\n")
+ f.write("print('ok')\n")
+ self.assertRaises(subprocess.CalledProcessError,
+ subprocess.check_output,
+ [sys.executable, main], cwd=tmpdir,
+ stderr=subprocess.DEVNULL)
+ out = subprocess.check_output([sys.executable, "-I", main],
+ cwd=tmpdir)
+ self.assertEqual(out.strip(), b"ok")
+
def test_main():
test.support.run_unittest(CmdLineTest)
test.support.reap_children()
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index e31bbc2..65cb8ef 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -515,7 +515,7 @@ class SysModuleTest(unittest.TestCase):
attrs = ("debug",
"inspect", "interactive", "optimize", "dont_write_bytecode",
"no_user_site", "no_site", "ignore_environment", "verbose",
- "bytes_warning", "quiet", "hash_randomization")
+ "bytes_warning", "quiet", "hash_randomization", "isolated")
for attr in attrs:
self.assertTrue(hasattr(sys.flags, attr), attr)
self.assertEqual(type(getattr(sys.flags, attr)), int, attr)
diff --git a/Misc/NEWS b/Misc/NEWS
index b0e392f..e7efb03 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,8 @@ Projected Release date: 2013-09-08
Core and Builtins
-----------------
+- Issue #16400: Add command line option for isolated mode.
+
- Issue #15301: Parsing fd, uid, and gid parameters for builtins
in Modules/posixmodule.c is now far more robust.
diff --git a/Misc/python.man b/Misc/python.man
index bcb3ec8..52aedee 100644
--- a/Misc/python.man
+++ b/Misc/python.man
@@ -26,11 +26,14 @@ python \- an interpreted, interactive, object-oriented programming language
.B \-i
]
[
-.B \-m
-.I module-name
+.B \-I
]
.br
[
+.B \-m
+.I module-name
+]
+[
.B \-q
]
[
@@ -139,6 +142,13 @@ command. It does not read the $PYTHONSTARTUP file. This can be
useful to inspect global variables or a stack trace when a script
raises an exception.
.TP
+.B \-I
+Run Python in isolated mode. This also implies \fB\-E\fP and \fB\-S\fP. In
+isolated mode sys.path contains neither the script’s directory nor the user’s
+site-packages directory. All PYTHON* environment variables are ignored, too.
+Further restrictions may be imposed to prevent the user from injecting
+malicious code.
+.TP
.BI "\-m " module-name
Searches
.I sys.path
diff --git a/Modules/main.c b/Modules/main.c
index 435bd1b..25190b8 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -43,7 +43,7 @@ static wchar_t **orig_argv;
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 @@ Options and arguments (and corresponding environment variables):\n\
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 environment (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\
@@ -426,6 +427,12 @@ Py_Main(int argc, wchar_t **argv)
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
index 86c3206..b0bc549 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -112,6 +112,7 @@ int Py_IgnoreEnvironmentFlag; /* e.g. PYTHONPATH, PYTHONHOME */
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
index 754bcfe..72004f8a 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -1369,6 +1369,7 @@ static PyStructSequence_Field flags_fields[] = {
{"bytes_warning", "-b"},
{"quiet", "-q"},
{"hash_randomization", "-R"},
+ {"isolated", "-I"},
{0}
};
@@ -1376,7 +1377,7 @@ static PyStructSequence_Desc flags_desc = {
"sys.flags", /* name */
flags__doc__, /* doc */
flags_fields, /* fields */
- 12
+ 13
};
static PyObject*
@@ -1406,6 +1407,7 @@ make_flags(void)
SetFlag(Py_BytesWarningFlag);
SetFlag(Py_QuietFlag);
SetFlag(Py_HashRandomizationFlag);
+ SetFlag(Py_IsolatedFlag);
#undef SetFlag
if (PyErr_Occurred()) {
@@ -1944,7 +1946,7 @@ PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
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