summaryrefslogtreecommitdiffstats
path: root/Lib/test/test_capi.py
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2017-11-30 22:36:49 (GMT)
committerGitHub <noreply@github.com>2017-11-30 22:36:49 (GMT)
commite10c9de9d74fd4c26b32e6719d96f04a5be6987d (patch)
treed52af6d26b53ff529cfab22ea50bb6b5faea7a03 /Lib/test/test_capi.py
parent29cb50ba347d9dc18e0720bef8e9caedd012a3cd (diff)
downloadcpython-e10c9de9d74fd4c26b32e6719d96f04a5be6987d.zip
cpython-e10c9de9d74fd4c26b32e6719d96f04a5be6987d.tar.gz
cpython-e10c9de9d74fd4c26b32e6719d96f04a5be6987d.tar.bz2
bpo-20891: Fix PyGILState_Ensure() (#4650) (#4655)
When PyGILState_Ensure() is called in a non-Python thread before PyEval_InitThreads(), only call PyEval_InitThreads() after calling PyThreadState_New() to fix a crash. Add an unit test in test_embed. Enhance also embedded tests, backport from master: * Add test_pre_initialization_api() * Set PYTHONIOENCODING environment variable in test_forced_io_encoding() (cherry picked from commit b4d1e1f7c1af6ae33f0e371576c8bcafedb099db)
Diffstat (limited to 'Lib/test/test_capi.py')
-rw-r--r--Lib/test/test_capi.py46
1 files changed, 37 insertions, 9 deletions
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index 3a29b69..6e4286e 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -401,23 +401,30 @@ class EmbeddingTests(unittest.TestCase):
def tearDown(self):
os.chdir(self.oldcwd)
- def run_embedded_interpreter(self, *args):
+ def run_embedded_interpreter(self, *args, env=None):
"""Runs a test in the embedded interpreter"""
cmd = [self.test_exe]
cmd.extend(args)
+ if env is not None and sys.platform == 'win32':
+ # Windows requires at least the SYSTEMROOT environment variable to
+ # start Python.
+ env = env.copy()
+ env['SYSTEMROOT'] = os.environ['SYSTEMROOT']
+
p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
- universal_newlines=True)
+ universal_newlines=True,
+ env=env)
(out, err) = p.communicate()
self.assertEqual(p.returncode, 0,
"bad returncode %d, stderr is %r" %
(p.returncode, err))
return out, err
- def test_subinterps(self):
+ def test_repeated_init_and_subinterpreters(self):
# This is just a "don't crash" test
- out, err = self.run_embedded_interpreter()
+ out, err = self.run_embedded_interpreter('repeated_init_and_subinterpreters')
if support.verbose:
print()
print(out)
@@ -435,13 +442,14 @@ class EmbeddingTests(unittest.TestCase):
def test_forced_io_encoding(self):
# Checks forced configuration of embedded interpreter IO streams
- out, err = self.run_embedded_interpreter("forced_io_encoding")
+ env = dict(os.environ, PYTHONIOENCODING="utf-8:surrogateescape")
+ out, err = self.run_embedded_interpreter("forced_io_encoding", env=env)
if support.verbose:
print()
print(out)
print(err)
- expected_errors = sys.__stdout__.errors
- expected_stdin_encoding = sys.__stdin__.encoding
+ expected_stream_encoding = "utf-8"
+ expected_errors = "surrogateescape"
expected_pipe_encoding = self._get_default_pipe_encoding()
expected_output = '\n'.join([
"--- Use defaults ---",
@@ -469,13 +477,33 @@ class EmbeddingTests(unittest.TestCase):
"stdout: latin-1:replace",
"stderr: latin-1:backslashreplace"])
expected_output = expected_output.format(
- in_encoding=expected_stdin_encoding,
- out_encoding=expected_pipe_encoding,
+ in_encoding=expected_stream_encoding,
+ out_encoding=expected_stream_encoding,
errors=expected_errors)
# This is useful if we ever trip over odd platform behaviour
self.maxDiff = None
self.assertEqual(out.strip(), expected_output)
+ def test_pre_initialization_api(self):
+ """
+ Checks the few parts of the C-API that work before the runtine
+ is initialized (via Py_Initialize()).
+ """
+ env = dict(os.environ, PYTHONPATH=os.pathsep.join(sys.path))
+ out, err = self.run_embedded_interpreter("pre_initialization_api", env=env)
+ self.assertEqual(out, '')
+ self.assertEqual(err, '')
+
+ def test_bpo20891(self):
+ """
+ bpo-20891: Calling PyGILState_Ensure in a non-Python thread before
+ calling PyEval_InitThreads() must not crash. PyGILState_Ensure() must
+ call PyEval_InitThreads() for us in this case.
+ """
+ out, err = self.run_embedded_interpreter("bpo20891")
+ self.assertEqual(out, '')
+ self.assertEqual(err, '')
+
class SkipitemTest(unittest.TestCase):