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:
Victor Stinner 2022-05-06 01:34:11 +02:00 committed by GitHub
parent f6dd14c653
commit ada8b6d1b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 174 additions and 35 deletions

View file

@ -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`

View file

@ -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

View file

@ -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`

View file

@ -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
----------------------

View file

@ -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;

View file

@ -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")

View file

@ -579,13 +579,13 @@ def test_unknown_options(self):
'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 @@ def test_sys_flags_not_set(self):
# 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 @@ def test_sys_flags_not_set(self):
PYTHONOPTIMIZE="1",
PYTHONDONTWRITEBYTECODE="1",
PYTHONVERBOSE="1",
PYTHONSAFEPATH="1",
)
class SyntaxErrorTests(unittest.TestCase):

View file

@ -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 @@ def test_init_from_config(self):
'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 @@ def test_init_compat_env(self):
'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 @@ def test_init_python_env(self):
'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 @@ def test_preinit_parse_argv(self):
}
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 @@ def test_preinit_dont_parse_argv(self):
'isolated': 0,
}
argv = ["python3",
"-E", "-I",
"-E", "-I", "-P",
"-X", "dev",
"-X", "utf8",
"script.py"]
@ -990,6 +996,7 @@ def test_preinit_dont_parse_argv(self):
def test_init_isolated_flag(self):
config = {
'isolated': 1,
'safe_path': 1,
'use_environment': 0,
'user_site_directory': 0,
}
@ -999,6 +1006,7 @@ def test_preinit_isolated1(self):
# _PyPreConfig.isolated=1, _PyCoreConfig.isolated not set
config = {
'isolated': 1,
'safe_path': 1,
'use_environment': 0,
'user_site_directory': 0,
}
@ -1008,6 +1016,7 @@ def test_preinit_isolated2(self):
# _PyPreConfig.isolated=0, _PyCoreConfig.isolated=1
config = {
'isolated': 1,
'safe_path': 1,
'use_environment': 0,
'user_site_directory': 0,
}

View file

@ -522,6 +522,7 @@ def test_args_from_interpreter_flags(self):
['-E'],
['-v'],
['-b'],
['-P'],
['-q'],
['-I'],
# same option multiple times
@ -541,7 +542,8 @@ def test_args_from_interpreter_flags(self):
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):

View file

@ -669,10 +669,10 @@ def test_sys_flags(self):
"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))

View file

@ -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.

View file

@ -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

View file

@ -717,6 +717,7 @@ def search_up(prefix, *landmarks, test=isfile):
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()

View file

@ -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) {

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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},

View file

@ -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);

View file

@ -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;