[pypy-commit] pypy default: cleanup signal module and fix win32 behavior

bdkearns noreply at buildbot.pypy.org
Fri Feb 8 13:52:16 CET 2013


Author: Brian Kearns <bdkearns at gmail.com>
Branch: 
Changeset: r60972:ace3ca8195f3
Date: 2013-02-08 07:51 -0500
http://bitbucket.org/pypy/pypy/changeset/ace3ca8195f3/

Log:	cleanup signal module and fix win32 behavior

diff --git a/pypy/module/signal/interp_signal.py b/pypy/module/signal/interp_signal.py
--- a/pypy/module/signal/interp_signal.py
+++ b/pypy/module/signal/interp_signal.py
@@ -115,6 +115,11 @@
 class Handlers:
     def __init__(self, space):
         self.handlers_w = {}
+        for signum in range(1, NSIG):
+            if WIN32 and signum not in signal_values:
+                self.handlers_w[signum] = space.w_None
+            else:
+                self.handlers_w[signum] = space.wrap(SIG_DFL)
 
 def _get_handlers(space):
     return space.fromcache(Handlers).handlers_w
@@ -144,17 +149,12 @@
     Return the current action for the given signal.  The return value can be:
     SIG_IGN -- if the signal is being ignored
     SIG_DFL -- if the default action for the signal is in effect
-    None -- if an unknown handler is in effect (XXX UNIMPLEMENTED)
+    None -- if an unknown handler is in effect
     anything else -- the callable Python object used as a handler
     """
-    if WIN32:
-        check_signum_exists(space, signum)
-    else:
-        check_signum_in_range(space, signum)
+    check_signum_in_range(space, signum)
     handlers_w = _get_handlers(space)
-    if signum in handlers_w:
-        return handlers_w[signum]
-    return space.wrap(SIG_DFL)
+    return handlers_w[signum]
 
 
 def default_int_handler(space, w_signum, w_frame):
@@ -180,13 +180,6 @@
     return space.w_None
 
 
-def check_signum_exists(space, signum):
-    if signum in signal_values:
-        return
-    raise OperationError(space.w_ValueError,
-                         space.wrap("invalid signal value"))
-
-
 def check_signum_in_range(space, signum):
     if 1 <= signum < NSIG:
         return
@@ -208,11 +201,13 @@
     A signal handler function is called with two arguments:
     the first is the signal number, the second is the interrupted stack frame.
     """
+    if WIN32 and signum not in signal_values:
+        raise OperationError(space.w_ValueError,
+                             space.wrap("invalid signal value"))
     if not space.threadlocals.ismainthread():
         raise OperationError(space.w_ValueError,
-                             space.wrap("signal() must be called from the "
-                                        "main thread"))
-    old_handler = getsignal(space, signum)
+                             space.wrap("signal only works in main thread"))
+    check_signum_in_range(space, signum)
 
     if space.eq_w(w_handler, space.wrap(SIG_DFL)):
         pypysig_default(signum)
@@ -224,7 +219,9 @@
                                  space.wrap("'handler' must be a callable "
                                             "or SIG_DFL or SIG_IGN"))
         pypysig_setflag(signum)
+
     handlers_w = _get_handlers(space)
+    old_handler = handlers_w[signum]
     handlers_w[signum] = w_handler
     return old_handler
 
@@ -249,7 +246,7 @@
 @jit.dont_look_inside
 @unwrap_spec(signum=int, flag=int)
 def siginterrupt(space, signum, flag):
-    check_signum_exists(space, signum)
+    check_signum_in_range(space, signum)
     if rffi.cast(lltype.Signed, c_siginterrupt(signum, flag)) < 0:
         errno = rposix.get_errno()
         raise OperationError(space.w_RuntimeError, space.wrap(errno))
diff --git a/pypy/module/signal/test/test_signal.py b/pypy/module/signal/test/test_signal.py
--- a/pypy/module/signal/test/test_signal.py
+++ b/pypy/module/signal/test/test_signal.py
@@ -85,7 +85,6 @@
 
         signal.signal(signum, signal.SIG_DFL)
 
-
     def test_default_return(self):
         """
         Test that signal.signal returns SIG_DFL if that is the current handler.
@@ -99,7 +98,6 @@
         finally:
             signal(SIGINT, SIG_DFL)
 
-
     def test_ignore_return(self):
         """
         Test that signal.signal returns SIG_IGN if that is the current handler.
@@ -113,7 +111,6 @@
         finally:
             signal(SIGINT, SIG_DFL)
 
-
     def test_obj_return(self):
         """
         Test that signal.signal returns a Python object if one is the current
@@ -130,7 +127,6 @@
         finally:
             signal(SIGINT, SIG_DFL)
 
-
     def test_getsignal(self):
         """
         Test that signal.getsignal returns the currently installed handler.
@@ -151,17 +147,18 @@
         finally:
             signal(SIGINT, SIG_DFL)
 
-        raises(ValueError, getsignal, 4444)
-        raises(ValueError, signal, 4444, lambda *args: None)
+    def test_check_signum(self):
         import sys
+        from signal import getsignal, signal, NSIG
+
+        # signum out of range fails
+        raises(ValueError, getsignal, NSIG)
+        raises(ValueError, signal, NSIG, lambda *args: None)
+
+        # on windows invalid signal within range should pass getsignal but fail signal
         if sys.platform == 'win32':
-            raises(ValueError, signal, 42, lambda *args: None)
+            assert getsignal(7) == None
             raises(ValueError, signal, 7, lambda *args: None)
-        elif sys.platform == 'darwin' or 'bsd' in sys.platform:
-            raises(ValueError, signal, 42, lambda *args: None)
-        else:
-            signal(42, lambda *args: None)
-            signal(42, SIG_DFL)
 
     def test_alarm(self):
         try:


More information about the pypy-commit mailing list