]> granicus.if.org Git - python/commitdiff
bpo-30447: Fix/skip the subinterpreters test on some platforms. (#1791)
authorEric Snow <ericsnowcurrently@gmail.com>
Thu, 25 May 2017 00:19:47 +0000 (17:19 -0700)
committerGitHub <noreply@github.com>
Thu, 25 May 2017 00:19:47 +0000 (17:19 -0700)
Lib/test/test_capi.py
Programs/_testembed.c

index 766098134c4ec670fb8af355ba11073ca1996d5a..8ac8af9826569597c638c777d3ba9ee602f54954 100644 (file)
@@ -385,7 +385,7 @@ class EmbeddingTests(unittest.TestCase):
                          (p.returncode, err))
         return out, err
 
-    def test_subinterps(self):
+    def run_repeated_init_and_subinterpreters(self):
         out, err = self.run_embedded_interpreter("repeated_init_and_subinterpreters")
         self.assertEqual(err, "")
 
@@ -404,73 +404,72 @@ class EmbeddingTests(unittest.TestCase):
                       r"id\(modules\) = ([\d]+)$")
         Interp = namedtuple("Interp", "id interp tstate modules")
 
-        main = None
-        lastmain = None
-        numinner = None
         numloops = 0
+        current_run = []
         for line in out.splitlines():
             if line == "--- Pass {} ---".format(numloops):
-                if numinner is not None:
-                    self.assertEqual(numinner, 5)
+                self.assertEqual(len(current_run), 0)
                 if support.verbose:
                     print(line)
-                lastmain = main
-                main = None
-                mainid = 0
                 numloops += 1
-                numinner = 0
                 continue
-            numinner += 1
 
-            self.assertLessEqual(numinner, 5)
+            self.assertLess(len(current_run), 5)
             match = re.match(interp_pat, line)
             if match is None:
                 self.assertRegex(line, interp_pat)
 
-            # The last line in the loop should be the same as the first.
-            if numinner == 5:
-                self.assertEqual(match.groups(), main)
-                continue
-
             # Parse the line from the loop.  The first line is the main
             # interpreter and the 3 afterward are subinterpreters.
             interp = Interp(*match.groups())
             if support.verbose:
                 print(interp)
-            if numinner == 1:
-                main = interp
-                id = str(mainid)
-            else:
-                subid = mainid + numinner - 1
-                id = str(subid)
-
-            # Validate the loop line for each interpreter.
-            self.assertEqual(interp.id, id)
             self.assertTrue(interp.interp)
             self.assertTrue(interp.tstate)
             self.assertTrue(interp.modules)
-            if platform.system() == 'Windows':
-                # XXX Fix on Windows: something is going on with the
-                # pointers in Programs/_testembed.c.  interp.interp
-                # is 0x0 and # interp.modules is the same between
-                # interpreters.
-                continue
-            if interp is main:
-                if lastmain is not None:
-                    # A new main interpreter may have the same interp
-                    # and/or tstate pointer as an earlier finalized/
-                    # destroyed one.  So we do not check interp or
-                    # tstate here.
-                    self.assertNotEqual(interp.modules, lastmain.modules)
-            else:
+            current_run.append(interp)
+
+            # The last line in the loop should be the same as the first.
+            if len(current_run) == 5:
+                main = current_run[0]
+                self.assertEqual(interp, main)
+                yield current_run
+                current_run = []
+
+    def test_subinterps_main(self):
+        for run in self.run_repeated_init_and_subinterpreters():
+            main = run[0]
+
+            self.assertEqual(main.id, '0')
+
+    def test_subinterps_different_ids(self):
+        for run in self.run_repeated_init_and_subinterpreters():
+            main, *subs, _ = run
+
+            mainid = int(main.id)
+            for i, sub in enumerate(subs):
+                self.assertEqual(sub.id, str(mainid + i + 1))
+
+    def test_subinterps_distinct_state(self):
+        for run in self.run_repeated_init_and_subinterpreters():
+            main, *subs, _ = run
+
+            if '0x0' in main:
+                # XXX Fix on Windows (and other platforms): something
+                # is going on with the pointers in Programs/_testembed.c.
+                # interp.interp is 0x0 and interp.modules is the same
+                # between interpreters.
+                raise unittest.SkipTest('platform prints pointers as 0x0')
+
+            for sub in subs:
                 # A new subinterpreter may have the same
                 # PyInterpreterState pointer as a previous one if
                 # the earlier one has already been destroyed.  So
                 # we compare with the main interpreter.  The same
                 # applies to tstate.
-                self.assertNotEqual(interp.interp, main.interp)
-                self.assertNotEqual(interp.tstate, main.tstate)
-                self.assertNotEqual(interp.modules, main.modules)
+                self.assertNotEqual(sub.interp, main.interp)
+                self.assertNotEqual(sub.tstate, main.tstate)
+                self.assertNotEqual(sub.modules, main.modules)
 
     @staticmethod
     def _get_default_pipe_encoding():
index de88404465a75b151d5befd7aaae5fdef90ddc54..c7660f95819ca8ef1b86e11722c037a0366ace60 100644 (file)
@@ -28,7 +28,7 @@ static void print_subinterp(void)
     PyThreadState *ts = PyThreadState_Get();
     PyInterpreterState *interp = ts->interp;
     int64_t id = PyInterpreterState_GetID(interp);
-    printf("interp %lu <0x%" PRIXPTR ">, thread state <0x%" PRIXPTR ">: ",
+    printf("interp %" PRId64 " <0x%" PRIXPTR ">, thread state <0x%" PRIXPTR ">: ",
             id, (uintptr_t)interp, (uintptr_t)ts);
     fflush(stdout);
     PyRun_SimpleString(