mirror of https://github.com/python/cpython
gh-57684: Add -P cmdline option and PYTHONSAFEPATH env var (#31542)
Add the -P command line option and the PYTHONSAFEPATH environment variable to not prepend a potentially unsafe path to sys.path. * Add sys.flags.safe_path flag. * Add PyConfig.safe_path member. * Programs/_bootstrap_python.c uses config.safe_path=0. * Update subprocess._optim_args_from_interpreter_flags() to handle the -P command line option. * Modules/getpath.py sets safe_path to 1 if a "._pth" file is present.
This commit is contained in:
parent
f6dd14c653
commit
ada8b6d1b1
|
@ -543,6 +543,25 @@ PyConfig
|
|||
|
||||
See also the :c:member:`~PyConfig.orig_argv` member.
|
||||
|
||||
.. c:member:: int safe_path
|
||||
|
||||
If equals to zero, ``Py_RunMain()`` prepends a potentially unsafe path to
|
||||
:data:`sys.path` at startup:
|
||||
|
||||
* If :c:member:`argv[0] <PyConfig.argv>` is equal to ``L"-m"``
|
||||
(``python -m module``), prepend the current working directory.
|
||||
* If running a script (``python script.py``), prepend the script's
|
||||
directory. If it's a symbolic link, resolve symbolic links.
|
||||
* Otherwise (``python -c code`` and ``python``), prepend an empty string,
|
||||
which means the current working directory.
|
||||
|
||||
Set to 1 by the :option:`-P` command line option and the
|
||||
:envvar:`PYTHONSAFEPATH` environment variable.
|
||||
|
||||
Default: ``0`` in Python config, ``1`` in isolated config.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
.. c:member:: wchar_t* base_exec_prefix
|
||||
|
||||
:data:`sys.base_exec_prefix`.
|
||||
|
@ -809,13 +828,14 @@ PyConfig
|
|||
|
||||
If greater than 0, enable isolated mode:
|
||||
|
||||
* :data:`sys.path` contains neither the script's directory (computed from
|
||||
``argv[0]`` or the current directory) nor the user's site-packages
|
||||
directory.
|
||||
* Set :c:member:`~PyConfig.safe_path` to 1:
|
||||
don't prepend a potentially unsafe path to :data:`sys.path` at Python
|
||||
startup.
|
||||
* Set :c:member:`~PyConfig.use_environment` to 0.
|
||||
* Set :c:member:`~PyConfig.user_site_directory` to 0: don't add the user
|
||||
site directory to :data:`sys.path`.
|
||||
* Python REPL doesn't import :mod:`readline` nor enable default readline
|
||||
configuration on interactive prompts.
|
||||
* Set :c:member:`~PyConfig.use_environment` and
|
||||
:c:member:`~PyConfig.user_site_directory` to 0.
|
||||
|
||||
Default: ``0`` in Python mode, ``1`` in isolated mode.
|
||||
|
||||
|
@ -1029,12 +1049,13 @@ PyConfig
|
|||
.. c:member:: wchar_t* run_filename
|
||||
|
||||
Filename passed on the command line: trailing command line argument
|
||||
without :option:`-c` or :option:`-m`.
|
||||
without :option:`-c` or :option:`-m`. It is used by the
|
||||
:c:func:`Py_RunMain` function.
|
||||
|
||||
For example, it is set to ``script.py`` by the ``python3 script.py arg``
|
||||
command.
|
||||
command line.
|
||||
|
||||
Used by :c:func:`Py_RunMain`.
|
||||
See also the :c:member:`PyConfig.skip_source_first_line` option.
|
||||
|
||||
Default: ``NULL``.
|
||||
|
||||
|
@ -1419,9 +1440,16 @@ site-package directory to :data:`sys.path`.
|
|||
The following configuration files are used by the path configuration:
|
||||
|
||||
* ``pyvenv.cfg``
|
||||
* ``python._pth`` (Windows only)
|
||||
* ``._pth`` file (ex: ``python._pth``)
|
||||
* ``pybuilddir.txt`` (Unix only)
|
||||
|
||||
If a ``._pth`` file is present:
|
||||
|
||||
* Set :c:member:`~PyConfig.isolated` to 1.
|
||||
* Set :c:member:`~PyConfig.use_environment` to 0.
|
||||
* Set :c:member:`~PyConfig.site_import` to 0.
|
||||
* Set :c:member:`~PyConfig.safe_path` to 1.
|
||||
|
||||
The ``__PYVENV_LAUNCHER__`` environment variable is used to set
|
||||
:c:member:`PyConfig.base_executable`
|
||||
|
||||
|
|
|
@ -520,6 +520,7 @@ always available.
|
|||
:const:`hash_randomization` :option:`-R`
|
||||
:const:`dev_mode` :option:`-X dev <-X>` (:ref:`Python Development Mode <devmode>`)
|
||||
:const:`utf8_mode` :option:`-X utf8 <-X>`
|
||||
:const:`safe_path` :option:`-P`
|
||||
============================= ================================================================
|
||||
|
||||
.. versionchanged:: 3.2
|
||||
|
@ -539,6 +540,9 @@ always available.
|
|||
Mode <devmode>` and the ``utf8_mode`` attribute for the new :option:`-X`
|
||||
``utf8`` flag.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
Added the ``safe_path`` attribute for :option:`-P` option.
|
||||
|
||||
|
||||
.. data:: float_info
|
||||
|
||||
|
@ -1138,15 +1142,19 @@ always available.
|
|||
the environment variable :envvar:`PYTHONPATH`, plus an installation-dependent
|
||||
default.
|
||||
|
||||
As initialized upon program startup, the first item of this list, ``path[0]``,
|
||||
is the directory containing the script that was used to invoke the Python
|
||||
interpreter. If the script directory is not available (e.g. if the interpreter
|
||||
is invoked interactively or if the script is read from standard input),
|
||||
``path[0]`` is the empty string, which directs Python to search modules in the
|
||||
current directory first. Notice that the script directory is inserted *before*
|
||||
the entries inserted as a result of :envvar:`PYTHONPATH`.
|
||||
By default, as initialized upon program startup, a potentially unsafe path
|
||||
is prepended to :data:`sys.path` (*before* the entries inserted as a result
|
||||
of :envvar:`PYTHONPATH`):
|
||||
|
||||
The initialization of :data:`sys.path` is documented at :ref:`sys-path-init`.
|
||||
* ``python -m module`` command line: prepend the current working
|
||||
directory.
|
||||
* ``python script.py`` command line: prepend the script's directory.
|
||||
If it's a symbolic link, resolve symbolic links.
|
||||
* ``python -c code`` and ``python`` (REPL) command lines: prepend an empty
|
||||
string, which means the current working directory.
|
||||
|
||||
To not prepend this potentially unsafe path, use the :option:`-P` command
|
||||
line option or the :envvar:`PYTHONSAFEPATH` environment variable?
|
||||
|
||||
A program is free to modify this list for its own purposes. Only strings
|
||||
and bytes should be added to :data:`sys.path`; all other data types are
|
||||
|
|
|
@ -257,6 +257,8 @@ Miscellaneous options
|
|||
Ignore all :envvar:`PYTHON*` environment variables, e.g.
|
||||
:envvar:`PYTHONPATH` and :envvar:`PYTHONHOME`, that might be set.
|
||||
|
||||
See also the :option:`-P` and :option:`-I` (isolated) options.
|
||||
|
||||
|
||||
.. cmdoption:: -i
|
||||
|
||||
|
@ -271,7 +273,9 @@ Miscellaneous options
|
|||
|
||||
.. cmdoption:: -I
|
||||
|
||||
Run Python in isolated mode. This also implies -E and -s.
|
||||
Run Python in isolated mode. This also implies :option:`-E`, :option:`-P`
|
||||
and :option:`-s` options.
|
||||
|
||||
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
|
||||
|
@ -301,6 +305,23 @@ Miscellaneous options
|
|||
Modify ``.pyc`` filenames according to :pep:`488`.
|
||||
|
||||
|
||||
.. cmdoption:: -P
|
||||
|
||||
Don't prepend a potentially unsafe path to :data:`sys.path`:
|
||||
|
||||
* ``python -m module`` command line: Don't prepend the current working
|
||||
directory.
|
||||
* ``python script.py`` command line: Don't prepend the script's directory.
|
||||
If it's a symbolic link, resolve symbolic links.
|
||||
* ``python -c code`` and ``python`` (REPL) command lines: Don't prepend an
|
||||
empty string, which means the current working directory.
|
||||
|
||||
See also the :envvar:`PYTHONSAFEPATH` environment variable, and :option:`-E`
|
||||
and :option:`-I` (isolated) options.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
.. cmdoption:: -q
|
||||
|
||||
Don't display the copyright and version messages even in interactive mode.
|
||||
|
@ -583,6 +604,14 @@ conflict.
|
|||
within a Python program as the variable :data:`sys.path`.
|
||||
|
||||
|
||||
.. envvar:: PYTHONSAFEPATH
|
||||
|
||||
If this is set to a non-empty string, don't prepend a potentially unsafe
|
||||
path to :data:`sys.path`: see the :option:`-P` option for details.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
.. envvar:: PYTHONPLATLIBDIR
|
||||
|
||||
If this is set to a non-empty string, it overrides the :data:`sys.platlibdir`
|
||||
|
|
|
@ -362,6 +362,11 @@ Other Language Changes
|
|||
pickles instance attributes implemented as :term:`slots <__slots__>`.
|
||||
(Contributed by Serhiy Storchaka in :issue:`26579`.)
|
||||
|
||||
* Add :option:`-P` command line option and :envvar:`PYTHONSAFEPATH` environment
|
||||
variable to not prepend a potentially unsafe path to :data:`sys.path` such as
|
||||
the current directory, the script's directory or an empty string.
|
||||
(Contributed by Victor Stinner in :gh:`57684`.)
|
||||
|
||||
|
||||
Other CPython Implementation Changes
|
||||
====================================
|
||||
|
@ -636,6 +641,9 @@ sys
|
|||
(equivalent to ``sys.exc_info()[1]``).
|
||||
(Contributed by Irit Katriel in :issue:`46328`.)
|
||||
|
||||
* Add the :data:`sys.flags.safe_path <sys.flags>` flag.
|
||||
(Contributed by Victor Stinner in :gh:`57684`.)
|
||||
|
||||
|
||||
sysconfig
|
||||
---------
|
||||
|
@ -1480,6 +1488,8 @@ New Features
|
|||
representation of exceptions.
|
||||
(Contributed by Irit Katriel in :issue:`46343`.)
|
||||
|
||||
* Added the :c:member:`PyConfig.safe_path` member.
|
||||
(Contributed by Victor Stinner in :gh:`57684`.)
|
||||
|
||||
Porting to Python 3.11
|
||||
----------------------
|
||||
|
|
|
@ -176,6 +176,7 @@ typedef struct PyConfig {
|
|||
#endif
|
||||
wchar_t *check_hash_pycs_mode;
|
||||
int use_frozen_modules;
|
||||
int safe_path;
|
||||
|
||||
/* --- Path configuration inputs ------------ */
|
||||
int pathconfig_warnings;
|
||||
|
|
|
@ -313,12 +313,14 @@ def _args_from_interpreter_flags():
|
|||
args.append('-E')
|
||||
if sys.flags.no_user_site:
|
||||
args.append('-s')
|
||||
if sys.flags.safe_path:
|
||||
args.append('-P')
|
||||
|
||||
# -W options
|
||||
warnopts = sys.warnoptions[:]
|
||||
bytes_warning = sys.flags.bytes_warning
|
||||
xoptions = getattr(sys, '_xoptions', {})
|
||||
dev_mode = ('dev' in xoptions)
|
||||
bytes_warning = sys.flags.bytes_warning
|
||||
dev_mode = sys.flags.dev_mode
|
||||
|
||||
if bytes_warning > 1:
|
||||
warnopts.remove("error::BytesWarning")
|
||||
|
|
|
@ -579,13 +579,13 @@ class CmdLineTest(unittest.TestCase):
|
|||
'Cannot run -I tests when PYTHON env vars are required.')
|
||||
def test_isolatedmode(self):
|
||||
self.verify_valid_flag('-I')
|
||||
self.verify_valid_flag('-IEs')
|
||||
self.verify_valid_flag('-IEPs')
|
||||
rc, out, err = assert_python_ok('-I', '-c',
|
||||
'from sys import flags as f; '
|
||||
'print(f.no_user_site, f.ignore_environment, f.isolated)',
|
||||
'print(f.no_user_site, f.ignore_environment, f.isolated, f.safe_path)',
|
||||
# dummyvar to prevent extraneous -E
|
||||
dummyvar="")
|
||||
self.assertEqual(out.strip(), b'1 1 1')
|
||||
self.assertEqual(out.strip(), b'1 1 1 True')
|
||||
with os_helper.temp_cwd() as tmpdir:
|
||||
fake = os.path.join(tmpdir, "uuid.py")
|
||||
main = os.path.join(tmpdir, "main.py")
|
||||
|
@ -880,7 +880,8 @@ class IgnoreEnvironmentTest(unittest.TestCase):
|
|||
# Issue 31845: a startup refactoring broke reading flags from env vars
|
||||
expected_outcome = """
|
||||
(sys.flags.debug == sys.flags.optimize ==
|
||||
sys.flags.dont_write_bytecode == sys.flags.verbose == 0)
|
||||
sys.flags.dont_write_bytecode ==
|
||||
sys.flags.verbose == sys.flags.safe_path == 0)
|
||||
"""
|
||||
self.run_ignoring_vars(
|
||||
expected_outcome,
|
||||
|
@ -888,6 +889,7 @@ class IgnoreEnvironmentTest(unittest.TestCase):
|
|||
PYTHONOPTIMIZE="1",
|
||||
PYTHONDONTWRITEBYTECODE="1",
|
||||
PYTHONVERBOSE="1",
|
||||
PYTHONSAFEPATH="1",
|
||||
)
|
||||
|
||||
class SyntaxErrorTests(unittest.TestCase):
|
||||
|
|
|
@ -479,6 +479,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'_init_main': 1,
|
||||
'_isolated_interpreter': 0,
|
||||
'use_frozen_modules': not Py_DEBUG,
|
||||
'safe_path': 0,
|
||||
'_is_python_build': IGNORE_CONFIG,
|
||||
}
|
||||
if MS_WINDOWS:
|
||||
|
@ -496,6 +497,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
isolated=1,
|
||||
use_environment=0,
|
||||
user_site_directory=0,
|
||||
safe_path=1,
|
||||
dev_mode=0,
|
||||
install_signal_handlers=0,
|
||||
use_hash_seed=0,
|
||||
|
@ -855,6 +857,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'faulthandler': 1,
|
||||
'platlibdir': 'my_platlibdir',
|
||||
'module_search_paths': self.IGNORE_CONFIG,
|
||||
'safe_path': 1,
|
||||
|
||||
'check_hash_pycs_mode': 'always',
|
||||
'pathconfig_warnings': 0,
|
||||
|
@ -889,6 +892,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'warnoptions': ['EnvVar'],
|
||||
'platlibdir': 'env_platlibdir',
|
||||
'module_search_paths': self.IGNORE_CONFIG,
|
||||
'safe_path': 1,
|
||||
}
|
||||
self.check_all_configs("test_init_compat_env", config, preconfig,
|
||||
api=API_COMPAT)
|
||||
|
@ -919,6 +923,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'warnoptions': ['EnvVar'],
|
||||
'platlibdir': 'env_platlibdir',
|
||||
'module_search_paths': self.IGNORE_CONFIG,
|
||||
'safe_path': 1,
|
||||
}
|
||||
self.check_all_configs("test_init_python_env", config, preconfig,
|
||||
api=API_PYTHON)
|
||||
|
@ -959,12 +964,13 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
}
|
||||
config = {
|
||||
'argv': ['script.py'],
|
||||
'orig_argv': ['python3', '-X', 'dev', 'script.py'],
|
||||
'orig_argv': ['python3', '-X', 'dev', '-P', 'script.py'],
|
||||
'run_filename': os.path.abspath('script.py'),
|
||||
'dev_mode': 1,
|
||||
'faulthandler': 1,
|
||||
'warnoptions': ['default'],
|
||||
'xoptions': ['dev'],
|
||||
'safe_path': 1,
|
||||
}
|
||||
self.check_all_configs("test_preinit_parse_argv", config, preconfig,
|
||||
api=API_PYTHON)
|
||||
|
@ -975,7 +981,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
'isolated': 0,
|
||||
}
|
||||
argv = ["python3",
|
||||
"-E", "-I",
|
||||
"-E", "-I", "-P",
|
||||
"-X", "dev",
|
||||
"-X", "utf8",
|
||||
"script.py"]
|
||||
|
@ -990,6 +996,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
def test_init_isolated_flag(self):
|
||||
config = {
|
||||
'isolated': 1,
|
||||
'safe_path': 1,
|
||||
'use_environment': 0,
|
||||
'user_site_directory': 0,
|
||||
}
|
||||
|
@ -999,6 +1006,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
# _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set
|
||||
config = {
|
||||
'isolated': 1,
|
||||
'safe_path': 1,
|
||||
'use_environment': 0,
|
||||
'user_site_directory': 0,
|
||||
}
|
||||
|
@ -1008,6 +1016,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
|
|||
# _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1
|
||||
config = {
|
||||
'isolated': 1,
|
||||
'safe_path': 1,
|
||||
'use_environment': 0,
|
||||
'user_site_directory': 0,
|
||||
}
|
||||
|
|
|
@ -522,6 +522,7 @@ class TestSupport(unittest.TestCase):
|
|||
['-E'],
|
||||
['-v'],
|
||||
['-b'],
|
||||
['-P'],
|
||||
['-q'],
|
||||
['-I'],
|
||||
# same option multiple times
|
||||
|
@ -541,7 +542,8 @@ class TestSupport(unittest.TestCase):
|
|||
with self.subTest(opts=opts):
|
||||
self.check_options(opts, 'args_from_interpreter_flags')
|
||||
|
||||
self.check_options(['-I', '-E', '-s'], 'args_from_interpreter_flags',
|
||||
self.check_options(['-I', '-E', '-s', '-P'],
|
||||
'args_from_interpreter_flags',
|
||||
['-I'])
|
||||
|
||||
def test_optim_args_from_interpreter_flags(self):
|
||||
|
|
|
@ -669,10 +669,10 @@ class SysModuleTest(unittest.TestCase):
|
|||
"dont_write_bytecode", "no_user_site", "no_site",
|
||||
"ignore_environment", "verbose", "bytes_warning", "quiet",
|
||||
"hash_randomization", "isolated", "dev_mode", "utf8_mode",
|
||||
"warn_default_encoding")
|
||||
"warn_default_encoding", "safe_path")
|
||||
for attr in attrs:
|
||||
self.assertTrue(hasattr(sys.flags, attr), attr)
|
||||
attr_type = bool if attr == "dev_mode" else int
|
||||
attr_type = bool if attr in ("dev_mode", "safe_path") else int
|
||||
self.assertEqual(type(getattr(sys.flags, attr)), attr_type, attr)
|
||||
self.assertTrue(repr(sys.flags))
|
||||
self.assertEqual(len(sys.flags), len(attrs))
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
Add the :option:`-P` command line option and the :envvar:`PYTHONSAFEPATH`
|
||||
environment variable to not prepend a potentially unsafe path to
|
||||
:data:`sys.path`. Patch by Victor Stinner.
|
|
@ -43,6 +43,9 @@ python \- an interpreted, interactive, object-oriented programming language
|
|||
.B \-OO
|
||||
]
|
||||
[
|
||||
.B \-P
|
||||
]
|
||||
[
|
||||
.B \-s
|
||||
]
|
||||
[
|
||||
|
@ -154,7 +157,7 @@ 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
|
||||
Run Python in isolated mode. This also implies \fB\-E\fP, \fB\-P\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
|
||||
|
@ -177,6 +180,11 @@ adding .opt-1 before the .pyc extension.
|
|||
Do \fB-O\fP and also discard docstrings; change the filename for
|
||||
compiled (bytecode) files by adding .opt-2 before the .pyc extension.
|
||||
.TP
|
||||
.B \-P
|
||||
Don't automatically prepend a potentially unsafe path to \fBsys.path\fP such
|
||||
as the current directory, the script's directory or an empty string. See also the
|
||||
\fBPYTHONSAFEPATH\fP environment variable.
|
||||
.TP
|
||||
.B \-q
|
||||
Do not print the version and copyright messages. These messages are
|
||||
also suppressed in non-interactive mode.
|
||||
|
@ -398,6 +406,10 @@ needed for developing Python extensions and embedding the
|
|||
interpreter.
|
||||
.RE
|
||||
.SH ENVIRONMENT VARIABLES
|
||||
.IP PYTHONSAFEPATH
|
||||
If this is set to a non-empty string, don't automatically prepend a potentially
|
||||
unsafe path to \fBsys.path\fP such as the current directory, the script's
|
||||
directory or an empty string. See also the \fB\-P\fP option.
|
||||
.IP PYTHONHOME
|
||||
Change the location of the standard Python libraries. By default, the
|
||||
libraries are searched in ${prefix}/lib/python<version> and
|
||||
|
|
|
@ -717,6 +717,7 @@ if pth:
|
|||
config['isolated'] = 1
|
||||
config['use_environment'] = 0
|
||||
config['site_import'] = 0
|
||||
config['safe_path'] = 1
|
||||
pythonpath = []
|
||||
for line in pth:
|
||||
line = line.partition('#')[0].strip()
|
||||
|
|
|
@ -570,7 +570,7 @@ pymain_run_python(int *exitcode)
|
|||
goto error;
|
||||
}
|
||||
}
|
||||
else if (!config->isolated) {
|
||||
else if (!config->safe_path) {
|
||||
PyObject *path0 = NULL;
|
||||
int res = _PyPathConfig_ComputeSysPath0(&config->argv, &path0);
|
||||
if (res < 0) {
|
||||
|
|
|
@ -71,6 +71,7 @@ main(int argc, char **argv)
|
|||
config.parse_argv = 1;
|
||||
// add current script dir to sys.path
|
||||
config.isolated = 0;
|
||||
config.safe_path = 0;
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
status = PyConfig_SetArgv(&config, argc, argv);
|
||||
|
|
|
@ -676,6 +676,8 @@ static int test_init_from_config(void)
|
|||
Py_FrozenFlag = 0;
|
||||
config.pathconfig_warnings = 0;
|
||||
|
||||
config.safe_path = 1;
|
||||
|
||||
config._isolated_interpreter = 1;
|
||||
|
||||
init_from_config_clear(&config);
|
||||
|
@ -742,6 +744,7 @@ static void set_most_env_vars(void)
|
|||
putenv("PYTHONFAULTHANDLER=1");
|
||||
putenv("PYTHONIOENCODING=iso8859-1:replace");
|
||||
putenv("PYTHONPLATLIBDIR=env_platlibdir");
|
||||
putenv("PYTHONSAFEPATH=1");
|
||||
}
|
||||
|
||||
|
||||
|
@ -823,6 +826,10 @@ static int test_init_isolated_flag(void)
|
|||
|
||||
Py_IsolatedFlag = 0;
|
||||
config.isolated = 1;
|
||||
// These options are set to 1 by isolated=1
|
||||
config.safe_path = 0;
|
||||
config.use_environment = 1;
|
||||
config.user_site_directory = 1;
|
||||
|
||||
config_set_program_name(&config);
|
||||
set_all_env_vars();
|
||||
|
@ -901,6 +908,7 @@ static int test_preinit_dont_parse_argv(void)
|
|||
wchar_t *argv[] = {L"python3",
|
||||
L"-E",
|
||||
L"-I",
|
||||
L"-P",
|
||||
L"-X", L"dev",
|
||||
L"-X", L"utf8",
|
||||
L"script.py"};
|
||||
|
@ -934,7 +942,7 @@ static int test_preinit_parse_argv(void)
|
|||
|
||||
/* Pre-initialize implicitly using argv: make sure that -X dev
|
||||
is used to configure the allocation in preinitialization */
|
||||
wchar_t *argv[] = {L"python3", L"-X", L"dev", L"script.py"};
|
||||
wchar_t *argv[] = {L"python3", L"-X", L"dev", L"-P", L"script.py"};
|
||||
config_set_argv(&config, Py_ARRAY_LENGTH(argv), argv);
|
||||
config_set_program_name(&config);
|
||||
init_from_config_clear(&config);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "Python.h"
|
||||
#include "pycore_fileutils.h" // _Py_add_relfile()
|
||||
#include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0()
|
||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||
|
||||
#ifdef HAVE_DIRECT_H
|
||||
|
|
|
@ -41,7 +41,7 @@ static const wchar_t *opt_ptr = L"";
|
|||
|
||||
/* Python command line short and long options */
|
||||
|
||||
#define SHORT_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?"
|
||||
#define SHORT_OPTS L"bBc:dEhiIJm:OPqRsStuvVW:xX:?"
|
||||
|
||||
static const _PyOS_LongOption longopts[] = {
|
||||
{L"check-hash-based-pycs", 1, 0},
|
||||
|
|
|
@ -49,6 +49,7 @@ static const char usage_2[] = "\
|
|||
.pyc extension; also PYTHONOPTIMIZE=x\n\
|
||||
-OO : do -O changes and also discard docstrings; add .opt-2 before\n\
|
||||
.pyc extension\n\
|
||||
-P : don't add sys.path[0]\n\
|
||||
-q : don't print version and copyright messages on interactive startup\n\
|
||||
-s : don't add user site directory to sys.path; also PYTHONNOUSERSITE\n\
|
||||
-S : don't imply 'import site' on initialization\n\
|
||||
|
@ -113,6 +114,7 @@ PYTHONPATH : '%lc'-separated list of directories prefixed to the\n\
|
|||
default module search path. The result is sys.path.\n\
|
||||
";
|
||||
static const char usage_5[] =
|
||||
"PYTHONSAFEPATH: don't prepend a potentially unsafe path to sys.path.\n"
|
||||
"PYTHONHOME : alternate <prefix> directory (or <prefix>%lc<exec_prefix>).\n"
|
||||
" The default module search path uses %s.\n"
|
||||
"PYTHONPLATLIBDIR : override sys.platlibdir.\n"
|
||||
|
@ -647,6 +649,10 @@ config_check_consistency(const PyConfig *config)
|
|||
assert(config->check_hash_pycs_mode != NULL);
|
||||
assert(config->_install_importlib >= 0);
|
||||
assert(config->pathconfig_warnings >= 0);
|
||||
assert(config->_is_python_build >= 0);
|
||||
assert(config->safe_path >= 0);
|
||||
// config->use_frozen_modules is initialized later
|
||||
// by _PyConfig_InitImportConfig().
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
@ -737,6 +743,7 @@ _PyConfig_InitCompatConfig(PyConfig *config)
|
|||
#else
|
||||
config->use_frozen_modules = 1;
|
||||
#endif
|
||||
config->safe_path = 0;
|
||||
config->_is_python_build = 0;
|
||||
config->code_debug_ranges = 1;
|
||||
}
|
||||
|
@ -792,6 +799,7 @@ PyConfig_InitIsolatedConfig(PyConfig *config)
|
|||
config->use_hash_seed = 0;
|
||||
config->faulthandler = 0;
|
||||
config->tracemalloc = 0;
|
||||
config->safe_path = 1;
|
||||
config->pathconfig_warnings = 0;
|
||||
#ifdef MS_WINDOWS
|
||||
config->legacy_windows_stdio = 0;
|
||||
|
@ -959,6 +967,7 @@ _PyConfig_Copy(PyConfig *config, const PyConfig *config2)
|
|||
COPY_ATTR(_init_main);
|
||||
COPY_ATTR(_isolated_interpreter);
|
||||
COPY_ATTR(use_frozen_modules);
|
||||
COPY_ATTR(safe_path);
|
||||
COPY_WSTRLIST(orig_argv);
|
||||
COPY_ATTR(_is_python_build);
|
||||
|
||||
|
@ -1065,6 +1074,7 @@ _PyConfig_AsDict(const PyConfig *config)
|
|||
SET_ITEM_INT(_isolated_interpreter);
|
||||
SET_ITEM_WSTRLIST(orig_argv);
|
||||
SET_ITEM_INT(use_frozen_modules);
|
||||
SET_ITEM_INT(safe_path);
|
||||
SET_ITEM_INT(_is_python_build);
|
||||
|
||||
return dict;
|
||||
|
@ -1350,6 +1360,7 @@ _PyConfig_FromDict(PyConfig *config, PyObject *dict)
|
|||
GET_UINT(_init_main);
|
||||
GET_UINT(_isolated_interpreter);
|
||||
GET_UINT(use_frozen_modules);
|
||||
GET_UINT(safe_path);
|
||||
GET_UINT(_is_python_build);
|
||||
|
||||
#undef CHECK_VALUE
|
||||
|
@ -1633,6 +1644,10 @@ config_read_env_vars(PyConfig *config)
|
|||
}
|
||||
}
|
||||
|
||||
if (config_get_env(config, "PYTHONSAFEPATH")) {
|
||||
config->safe_path = 1;
|
||||
}
|
||||
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
|
@ -2000,6 +2015,7 @@ config_init_import(PyConfig *config, int compute_path_config)
|
|||
"(expected \"on\" or \"off\")");
|
||||
}
|
||||
|
||||
assert(config->use_frozen_modules >= 0);
|
||||
return _PyStatus_OK();
|
||||
}
|
||||
|
||||
|
@ -2327,6 +2343,10 @@ config_parse_cmdline(PyConfig *config, PyWideStringList *warnoptions,
|
|||
config->optimization_level++;
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
config->safe_path = 1;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
config->write_bytecode = 0;
|
||||
break;
|
||||
|
@ -2849,6 +2869,7 @@ _PyConfig_Read(PyConfig *config, int compute_path_config)
|
|||
|
||||
assert(config->isolated >= 0);
|
||||
if (config->isolated) {
|
||||
config->safe_path = 1;
|
||||
config->use_environment = 0;
|
||||
config->user_site_directory = 0;
|
||||
}
|
||||
|
@ -2994,6 +3015,7 @@ _Py_DumpPathConfig(PyThreadState *tstate)
|
|||
PySys_WriteStderr(" isolated = %i\n", config->isolated);
|
||||
PySys_WriteStderr(" environment = %i\n", config->use_environment);
|
||||
PySys_WriteStderr(" user site = %i\n", config->user_site_directory);
|
||||
PySys_WriteStderr(" safe_path = %i\n", config->safe_path);
|
||||
PySys_WriteStderr(" import site = %i\n", config->site_import);
|
||||
PySys_WriteStderr(" is in build tree = %i\n", config->_is_python_build);
|
||||
DUMP_CONFIG("stdlib dir", stdlib_dir);
|
||||
|
|
|
@ -2479,6 +2479,7 @@ static PyStructSequence_Field flags_fields[] = {
|
|||
{"dev_mode", "-X dev"},
|
||||
{"utf8_mode", "-X utf8"},
|
||||
{"warn_default_encoding", "-X warn_default_encoding"},
|
||||
{"safe_path", "-P"},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -2486,7 +2487,7 @@ static PyStructSequence_Desc flags_desc = {
|
|||
"sys.flags", /* name */
|
||||
flags__doc__, /* doc */
|
||||
flags_fields, /* fields */
|
||||
16
|
||||
17
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -2526,6 +2527,7 @@ set_flags_from_config(PyInterpreterState *interp, PyObject *flags)
|
|||
SetFlagObj(PyBool_FromLong(config->dev_mode));
|
||||
SetFlag(preconfig->utf8_mode);
|
||||
SetFlag(config->warn_default_encoding);
|
||||
SetFlagObj(PyBool_FromLong(config->safe_path));
|
||||
#undef SetFlagObj
|
||||
#undef SetFlag
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue