summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_cmd_line.py22
-rw-r--r--Python/pythonrun.c20
2 files changed, 37 insertions, 5 deletions
diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py
index db94a40..19089a4 100644
--- a/Lib/test/test_cmd_line.py
+++ b/Lib/test/test_cmd_line.py
@@ -13,18 +13,25 @@ def _spawn_python(*args):
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
def _kill_python(p):
+ return _kill_python_and_exit_code(p)[0]
+
+def _kill_python_and_exit_code(p):
p.stdin.close()
data = p.stdout.read()
p.stdout.close()
# try to cleanup the child so we don't appear to leak when running
# with regrtest -R. This should be a no-op on Windows.
subprocess._cleanup()
- return data
+ returncode = p.wait()
+ return data, returncode
class CmdLineTest(unittest.TestCase):
def start_python(self, *args):
+ return self.start_python_and_exit_code(*args)[0]
+
+ def start_python_and_exit_code(self, *args):
p = _spawn_python(*args)
- return _kill_python(p)
+ return _kill_python_and_exit_code(p)
def exit_code(self, *args):
cmd_line = [sys.executable, '-E']
@@ -61,6 +68,17 @@ class CmdLineTest(unittest.TestCase):
version = ('Python %d.%d' % sys.version_info[:2]).encode("ascii")
self.assertTrue(self.start_python('-V').startswith(version))
+ def test_verbose(self):
+ # -v causes imports to write to stderr. If the write to
+ # stderr itself causes an import to happen (for the output
+ # codec), a recursion loop can occur.
+ data, rc = self.start_python_and_exit_code('-v')
+ self.assertEqual(rc, 0)
+ self.assertTrue(b'stack overflow' not in data)
+ data, rc = self.start_python_and_exit_code('-vv')
+ self.assertEqual(rc, 0)
+ self.assertTrue(b'stack overflow' not in data)
+
def test_run_module(self):
# Test expected operation of the '-m' switch
# Switch needs an argument
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 6af7aec..d65d12d 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -512,7 +512,7 @@ Py_Finalize(void)
/* reset file system default encoding */
if (!Py_HasFileSystemDefaultEncoding) {
free((char*)Py_FileSystemDefaultEncoding);
- Py_FileSystemDefaultEncoding = NULL;
+ Py_FileSystemDefaultEncoding = NULL;
}
/* XXX Still allocated:
@@ -733,6 +733,7 @@ initstdio(void)
PyObject *m;
PyObject *std = NULL;
int status = 0, fd;
+ PyObject * encoding_attr;
/* Hack to avoid a nasty recursion issue when Python is invoked
in verbose mode: pre-import the Latin-1 and UTF-8 codecs */
@@ -823,6 +824,19 @@ initstdio(void)
goto error;
}
} /* if (fd < 0) */
+
+ /* Same as hack above, pre-import stderr's codec to avoid recursion
+ when import.c tries to write to stderr in verbose mode. */
+ encoding_attr = PyObject_GetAttrString(std, "encoding");
+ if (encoding_attr != NULL) {
+ const char * encoding;
+ encoding = PyUnicode_AsString(encoding_attr);
+ if (encoding != NULL) {
+ _PyCodec_Lookup(encoding);
+ }
+ }
+ PyErr_Clear(); /* Not a fatal error if codec isn't available */
+
PySys_SetObject("__stderr__", std);
PySys_SetObject("stderr", std);
Py_DECREF(std);
@@ -1900,8 +1914,8 @@ PyOS_CheckStack(void)
alloca(PYOS_STACK_MARGIN * sizeof(void*));
return 0;
} __except (GetExceptionCode() == STATUS_STACK_OVERFLOW ?
- EXCEPTION_EXECUTE_HANDLER :
- EXCEPTION_CONTINUE_SEARCH) {
+ EXCEPTION_EXECUTE_HANDLER :
+ EXCEPTION_CONTINUE_SEARCH) {
int errcode = _resetstkoflw();
if (errcode)
{