]> granicus.if.org Git - python/commitdiff
Issue #13854: Properly handle non-integer, non-string arg to SystemExit
authorRichard Oudkerk <shibturn@gmail.com>
Wed, 6 Jun 2012 18:04:57 +0000 (19:04 +0100)
committerRichard Oudkerk <shibturn@gmail.com>
Wed, 6 Jun 2012 18:04:57 +0000 (19:04 +0100)
Previously multiprocessing only expected int or str.  It also wrongly
used an exit code of 1 when the argument was a string instead of zero.

Lib/multiprocessing/process.py
Lib/test/test_multiprocessing.py
Misc/NEWS

index 2b61ee9a0d39a2d154975f2a48f16ae5a2da80f3..3262b50f50b1ac332ead3b40234131f7ec065b27 100644 (file)
@@ -271,11 +271,11 @@ class Process(object):
         except SystemExit as e:
             if not e.args:
                 exitcode = 1
-            elif type(e.args[0]) is int:
+            elif isinstance(e.args[0], int):
                 exitcode = e.args[0]
             else:
-                sys.stderr.write(e.args[0] + '\n')
-                exitcode = 1
+                sys.stderr.write(str(e.args[0]) + '\n')
+                exitcode = 0 if isinstance(e.args[0], str) else 1
         except:
             exitcode = 1
             import traceback
index 0d98a1498c74837ed00fc6fa29dbd8efe18564a1..b812e4840b830d0d36b13f904b4b3199f687ce40 100644 (file)
@@ -390,6 +390,36 @@ class _TestSubclassingProcess(BaseTestCase):
         1/0 # MARKER
 
 
+    @classmethod
+    def _test_sys_exit(cls, reason, testfn):
+        sys.stderr = open(testfn, 'w')
+        sys.exit(reason)
+
+    def test_sys_exit(self):
+        # See Issue 13854
+        if self.TYPE == 'threads':
+            return
+
+        testfn = test.support.TESTFN
+        self.addCleanup(test.support.unlink, testfn)
+
+        for reason, code in (([1, 2, 3], 1), ('ignore this', 0)):
+            p = self.Process(target=self._test_sys_exit, args=(reason, testfn))
+            p.daemon = True
+            p.start()
+            p.join(5)
+            self.assertEqual(p.exitcode, code)
+
+            with open(testfn, 'r') as f:
+                self.assertEqual(f.read().rstrip(), str(reason))
+
+        for reason in (True, False, 8):
+            p = self.Process(target=sys.exit, args=(reason,))
+            p.daemon = True
+            p.start()
+            p.join(5)
+            self.assertEqual(p.exitcode, reason)
+
 #
 #
 #
index 071e962690c8f948e3717fc22de85935ecb9a608..3f5c867a39096675f4f257694dfdff553414a54e 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -70,6 +70,9 @@ Core and Builtins
 Library
 -------
 
+- Issue #13854: Make multiprocessing properly handle non-integer
+  non-string argument to SystemExit.
+
 - Issue #12157: Make pool.map() empty iterables correctly.  Initial
   patch by mouad.