summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_cmd_line.py35
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2017-10-24-21-27-32.bpo-31845.8OS-k3.rst1
-rw-r--r--Modules/main.c54
-rw-r--r--Python/pylifecycle.c37
4 files changed, 82 insertions, 45 deletions
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index 28ddb2ba1b..1b584ebb7c 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -12,7 +12,6 @@ from test.support.script_helper import (
spawn_python, kill_python, assert_python_ok, assert_python_failure
)
-
# XXX (ncoghlan): Move to script_helper and make consistent with run_python
def _kill_python_and_exit_code(p):
data = kill_python(p)
@@ -486,6 +485,26 @@ class CmdLineTest(unittest.TestCase):
cwd=tmpdir)
self.assertEqual(out.strip(), b"ok")
+ def test_sys_flags_set(self):
+ # Issue 31845: a startup refactoring broke reading flags from env vars
+ for value, expected in (("", 0), ("1", 1), ("text", 1), ("2", 2)):
+ env_vars = dict(
+ PYTHONDEBUG=value,
+ PYTHONOPTIMIZE=value,
+ PYTHONDONTWRITEBYTECODE=value,
+ PYTHONVERBOSE=value,
+ )
+ code = (
+ "import sys; "
+ "sys.stderr.write(str(sys.flags)); "
+ f"""sys.exit(not (
+ sys.flags.debug == sys.flags.optimize ==
+ sys.flags.dont_write_bytecode == sys.flags.verbose ==
+ {expected}
+ ))"""
+ )
+ with self.subTest(envar_value=value):
+ assert_python_ok('-c', code, **env_vars)
class IgnoreEnvironmentTest(unittest.TestCase):
@@ -506,6 +525,20 @@ class IgnoreEnvironmentTest(unittest.TestCase):
self.run_ignoring_vars("sys.flags.hash_randomization == 1",
PYTHONHASHSEED="0")
+ 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)
+ """
+ self.run_ignoring_vars(
+ expected_outcome,
+ PYTHONDEBUG="1",
+ PYTHONOPTIMIZE="1",
+ PYTHONDONTWRITEBYTECODE="1",
+ PYTHONVERBOSE="1",
+ )
+
def test_main():
test.support.run_unittest(CmdLineTest, IgnoreEnvironmentTest)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-10-24-21-27-32.bpo-31845.8OS-k3.rst b/Misc/NEWS.d/next/Core and Builtins/2017-10-24-21-27-32.bpo-31845.8OS-k3.rst
new file mode 100644
index 0000000000..ddaf630638
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2017-10-24-21-27-32.bpo-31845.8OS-k3.rst
@@ -0,0 +1 @@
+Environment variables are once more read correctly at interpreter startup.
diff --git a/Modules/main.c b/Modules/main.c
index e862113310..846ecb6170 100644
--- a/Modules/main.c
+++ b/Modules/main.c
@@ -522,39 +522,33 @@ read_command_line(int argc, wchar_t **argv, _Py_CommandLineDetails *cmdline)
return 0;
}
-static int
-apply_command_line_and_environment(_Py_CommandLineDetails *cmdline)
+static void
+maybe_set_flag(int *flag, int value)
{
- char *p;
- Py_BytesWarningFlag = cmdline->bytes_warning;
- Py_DebugFlag = cmdline->debug;
- Py_InspectFlag = cmdline->inspect;
- Py_InteractiveFlag = cmdline->interactive;
- Py_IsolatedFlag = cmdline->isolated;
- Py_OptimizeFlag = cmdline->optimization_level;
- Py_DontWriteBytecodeFlag = cmdline->dont_write_bytecode;
- Py_NoUserSiteDirectory = cmdline->no_user_site_directory;
- Py_NoSiteFlag = cmdline->no_site_import;
- Py_UnbufferedStdioFlag = cmdline->use_unbuffered_io;
- Py_VerboseFlag = cmdline->verbosity;
- Py_QuietFlag = cmdline->quiet_flag;
-
- if (!Py_InspectFlag &&
- (p = Py_GETENV("PYTHONINSPECT")) && *p != '\0') {
- Py_InspectFlag = 1;
- cmdline->inspect = 1;
- }
- if (!cmdline->use_unbuffered_io &&
- (p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0') {
- Py_UnbufferedStdioFlag = 1;
- cmdline->use_unbuffered_io = 1;
+ /* Helper to set flag variables from command line options
+ * - uses the higher of the two values if they're both set
+ * - otherwise leaves the flag unset
+ */
+ if (*flag < value) {
+ *flag = value;
}
+}
- if (!Py_NoUserSiteDirectory &&
- (p = Py_GETENV("PYTHONNOUSERSITE")) && *p != '\0') {
- Py_NoUserSiteDirectory = 1;
- cmdline->no_user_site_directory = 1;
- }
+static int
+apply_command_line_and_environment(_Py_CommandLineDetails *cmdline)
+{
+ maybe_set_flag(&Py_BytesWarningFlag, cmdline->bytes_warning);
+ maybe_set_flag(&Py_DebugFlag, cmdline->debug);
+ maybe_set_flag(&Py_InspectFlag, cmdline->inspect);
+ maybe_set_flag(&Py_InteractiveFlag, cmdline->interactive);
+ maybe_set_flag(&Py_IsolatedFlag, cmdline->isolated);
+ maybe_set_flag(&Py_OptimizeFlag, cmdline->optimization_level);
+ maybe_set_flag(&Py_DontWriteBytecodeFlag, cmdline->dont_write_bytecode);
+ maybe_set_flag(&Py_NoUserSiteDirectory, cmdline->no_user_site_directory);
+ maybe_set_flag(&Py_NoSiteFlag, cmdline->no_site_import);
+ maybe_set_flag(&Py_UnbufferedStdioFlag, cmdline->use_unbuffered_io);
+ maybe_set_flag(&Py_VerboseFlag, cmdline->verbosity);
+ maybe_set_flag(&Py_QuietFlag, cmdline->quiet_flag);
/* TODO: Apply PYTHONWARNINGS & -W options to sys module here */
/* TODO: Apply -X options to sys module here */
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 5b13bc4582..4e8bbb662e 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -217,15 +217,18 @@ Py_SetStandardStreamEncoding(const char *encoding, const char *errors)
*/
-static int
-add_flag(int flag, const char *envs)
+static void
+set_flag(int *flag, const char *envs)
{
+ /* Helper to set flag variables from environment variables:
+ * - uses the higher of the two values if they're both set
+ * - otherwise sets the flag to 1
+ */
int env = atoi(envs);
- if (flag < env)
- flag = env;
- if (flag < 1)
- flag = 1;
- return flag;
+ if (*flag < env)
+ *flag = env;
+ if (*flag < 1)
+ *flag = 1;
}
static char*
@@ -612,22 +615,28 @@ void _Py_InitializeCore(const _PyCoreConfig *config)
#endif
if ((p = Py_GETENV("PYTHONDEBUG")) && *p != '\0')
- Py_DebugFlag = add_flag(Py_DebugFlag, p);
+ set_flag(&Py_DebugFlag, p);
if ((p = Py_GETENV("PYTHONVERBOSE")) && *p != '\0')
- Py_VerboseFlag = add_flag(Py_VerboseFlag, p);
+ set_flag(&Py_VerboseFlag, p);
if ((p = Py_GETENV("PYTHONOPTIMIZE")) && *p != '\0')
- Py_OptimizeFlag = add_flag(Py_OptimizeFlag, p);
+ set_flag(&Py_OptimizeFlag, p);
+ if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
+ set_flag(&Py_InspectFlag, p);
if ((p = Py_GETENV("PYTHONDONTWRITEBYTECODE")) && *p != '\0')
- Py_DontWriteBytecodeFlag = add_flag(Py_DontWriteBytecodeFlag, p);
+ set_flag(&Py_DontWriteBytecodeFlag, p);
+ if ((p = Py_GETENV("PYTHONNOUSERSITE")) && *p != '\0')
+ set_flag(&Py_NoUserSiteDirectory, p);
+ if ((p = Py_GETENV("PYTHONUNBUFFERED")) && *p != '\0')
+ set_flag(&Py_UnbufferedStdioFlag, p);
/* The variable is only tested for existence here;
_Py_HashRandomization_Init will check its value further. */
if ((p = Py_GETENV("PYTHONHASHSEED")) && *p != '\0')
- Py_HashRandomizationFlag = add_flag(Py_HashRandomizationFlag, p);
+ set_flag(&Py_HashRandomizationFlag, p);
#ifdef MS_WINDOWS
if ((p = Py_GETENV("PYTHONLEGACYWINDOWSFSENCODING")) && *p != '\0')
- Py_LegacyWindowsFSEncodingFlag = add_flag(Py_LegacyWindowsFSEncodingFlag, p);
+ set_flag(&Py_LegacyWindowsFSEncodingFlag, p);
if ((p = Py_GETENV("PYTHONLEGACYWINDOWSSTDIO")) && *p != '\0')
- Py_LegacyWindowsStdioFlag = add_flag(Py_LegacyWindowsStdioFlag, p);
+ set_flag(&Py_LegacyWindowsStdioFlag, p);
#endif
_Py_HashRandomization_Init(&core_config);