[Python-checkins] r80877 - in python/branches/signalfd-issue8407: Doc/library/signal.rst Lib/test/test_signal.py Modules/signalmodule.c

jean-paul.calderone python-checkins at python.org
Thu May 6 20:20:39 CEST 2010


Author: jean-paul.calderone
Date: Thu May  6 20:20:38 2010
New Revision: 80877

Log:
Address almost all review feedback from Antoine Pitrou and Brian Curtin

See http://codereview.appspot.com/1132041/show


Modified:
   python/branches/signalfd-issue8407/Doc/library/signal.rst
   python/branches/signalfd-issue8407/Lib/test/test_signal.py
   python/branches/signalfd-issue8407/Modules/signalmodule.c

Modified: python/branches/signalfd-issue8407/Doc/library/signal.rst
==============================================================================
--- python/branches/signalfd-issue8407/Doc/library/signal.rst	(original)
+++ python/branches/signalfd-issue8407/Doc/library/signal.rst	Thu May  6 20:20:38 2010
@@ -281,7 +281,7 @@
    *mask* is a list of signal numbers which will trigger data on this file
    descriptor.
 
-   *flags* is a bitvector which may include any :const:`signal.SFD_*` flag.
+   *flags* is a bit mask which may include any :const:`signal.SFD_*` flag.
 
    .. versionadded:: 2.7
 

Modified: python/branches/signalfd-issue8407/Lib/test/test_signal.py
==============================================================================
--- python/branches/signalfd-issue8407/Lib/test/test_signal.py	(original)
+++ python/branches/signalfd-issue8407/Lib/test/test_signal.py	Thu May  6 20:20:38 2010
@@ -406,20 +406,16 @@
 
 
 def raiser(*args):
-    """A signal handler which raises SomeException.
-    """
+    """A signal handler which raises SomeException."""
     raise SomeException()
 
 
 
 class SigprocmaskTests(unittest.TestCase):
-    """
-    Tests for sigprocmask.
-    """
+    """Tests for sigprocmask."""
     def _handle_sigusr1(self):
         old_handler = signal.signal(signal.SIGUSR1, raiser)
         self.addCleanup(signal.signal, signal.SIGUSR1, old_handler)
-        return SomeException
 
 
     def test_signature(self):
@@ -432,14 +428,30 @@
 
 
     def test_invalid_how(self):
-        """If a valid other than SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK is
+        """If a value other than SIG_BLOCK, SIG_UNBLOCK, or SIG_SETMASK is
         passed for the how argument to sigprocmask, ValueError is raised.
         """
-        with self.assertRaises(ValueError) as cm:
+        message = "value specified for how \(1700\) invalid"
+        with self.assertRaisesRegexp(ValueError, message):
             signal.sigprocmask(1700, [])
-        exc = cm.exception
-        self.assertTrue(isinstance(exc, ValueError))
-        self.assertEquals(str(exc), "value specified for how (1700) invalid")
+
+
+    def test_invalid_signal_iterable(self):
+        """If iterating over the value passed for the signals parameter to
+        sigprocmask raises an exception, sigprocmask raises that exception.
+        """
+        class BrokenIter(object):
+            def __iter__(self):
+                raise RuntimeError("my __iter__ is broken")
+        with self.assertRaisesRegexp(RuntimeError, "my __iter__ is broken"):
+            signal.sigprocmask(signal.SIG_BLOCK, BrokenIter())
+
+
+    def test_invalid_signal(self):
+        """If an object in the iterable passed for the signals parameter to
+        sigprocmask isn't an integer, TypeError is raised."""
+        with self.assertRaisesRegexp(TypeError, "an integer is required"):
+            signal.sigprocmask(signal.SIG_BLOCK, [object()])
 
 
     def test_return_previous_mask(self):
@@ -457,12 +469,9 @@
         self._handle_sigusr1()
         previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR1])
         os.kill(os.getpid(), signal.SIGUSR1)
-        try:
+        with self.assertRaises(SomeException):
+            # Expect to receive SIGUSR1 after unblocking it.
             signal.sigprocmask(signal.SIG_SETMASK, previous)
-        except SomeException:
-            pass
-        else:
-            self.fail("Expected to receive SIGUSR1 after unblocking it.")
 
 
     def test_unblock(self):
@@ -473,13 +482,18 @@
         previous = signal.sigprocmask(signal.SIG_BLOCK, [signal.SIGUSR1])
         self.addCleanup(signal.sigprocmask, signal.SIG_SETMASK, previous)
         signal.sigprocmask(signal.SIG_UNBLOCK, [signal.SIGUSR1])
-        try:
+
+        with self.assertRaises(SomeException):
             os.kill(os.getpid(), signal.SIGUSR1)
-            time.sleep(1)
-        except SomeException:
-            pass
-        else:
-            self.fail("SomeException was expected but not raised")
+
+
+    def test_long_signals(self):
+        """sigprocmask accepts signal numbers as instances of long."""
+        previous = signal.sigprocmask(
+            signal.SIG_SETMASK, [long(signal.SIGUSR1), long(signal.SIGUSR2)])
+        masked = signal.sigprocmask(signal.SIG_SETMASK, previous)
+        self.assertEquals(masked, [signal.SIGUSR1, signal.SIGUSR2])
+
 
 
 class SignalfdTests(unittest.TestCase):
@@ -524,11 +538,9 @@
         """If a signal number that is out of the valid range is included in the
         sigmask list argument to signalfd, ValueError is raised.
         """
-        with self.assertRaises(ValueError) as cm:
+        message = "signal number -2 out of range"
+        with self.assertRaisesRegexp(ValueError, message):
             signal.signalfd(-1, [-2])
-        exc = cm.exception
-        self.assertTrue(isinstance(exc, ValueError))
-        self.assertEquals(str(exc), "signal number -2 out of range")
 
 
     def test_handle_signals(self):

Modified: python/branches/signalfd-issue8407/Modules/signalmodule.c
==============================================================================
--- python/branches/signalfd-issue8407/Modules/signalmodule.c	(original)
+++ python/branches/signalfd-issue8407/Modules/signalmodule.c	Thu May  6 20:20:38 2010
@@ -468,28 +468,36 @@
 {
     static const char* range_format = "signal number %d out of range";
     char range_buffer[1024];
+    int result = 0;
 
-    PyObject *item, *iterator;
+    PyObject *item, *iterator = NULL;
 
     sigemptyset(mask);
 
     iterator = PyObject_GetIter(iterable);
     if (iterator == NULL) {
-        return -1;
+        result = -1;
+        goto error;
     }
 
-    for (item = PyIter_Next(iterator); item; item = PyIter_Next(iterator)) {
+    while ((item = PyIter_Next(iterator))) {
         int signum = PyInt_AsLong(item);
+        Py_DECREF(item);
         if (signum == -1 && PyErr_Occurred()) {
-            return -1;
+	    result = -1;
+	    goto error;
         }
         if (sigaddset(mask, signum) == -1) {
             PyOS_snprintf(range_buffer, sizeof(range_buffer), range_format, signum);
             PyErr_SetString(PyExc_ValueError, range_buffer);
-            return -1;
+            result = -1;
+            goto error;
         }
     }
-    return 0;
+
+error:
+    Py_XDECREF(iterator);
+    return result;
 }
 
 #if defined(HAVE_PTHREAD_SIGMASK) && !defined(HAVE_BROKEN_PTHREAD_SIGMASK)
@@ -506,7 +514,6 @@
     char how_buffer[1024];
 
     int how, sig;
-    int valid;
     PyObject *signals, *result, *signum;
     sigset_t mask, previous;
 
@@ -518,12 +525,7 @@
         return NULL;
     }
 
-    /*
-     * It seems that invalid values of how are not always discovered.
-     */
-    valid = (how == SIG_BLOCK || how == SIG_UNBLOCK || how == SIG_SETMASK);
-    
-    if (!valid || PY_SIGMASK(how, &mask, &previous) == -1) {
+    if (PY_SIGMASK(how, &mask, &previous) != 0) {
         PyOS_snprintf(how_buffer, sizeof(how_buffer), how_format, how);
         PyErr_SetString(PyExc_ValueError, how_buffer);
         return NULL;
@@ -551,6 +553,7 @@
                 Py_DECREF(result);
                 return NULL;
             }
+            Py_DECREF(signum);
         }
     }
     return result;


More information about the Python-checkins mailing list