[pypy-commit] pypy py3.6: un-mess argument handling and test of select.poll().poll(): previously the test

cfbolz pypy.commits at gmail.com
Mon Sep 16 16:58:04 EDT 2019


Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: py3.6
Changeset: r97502:f41451c91702
Date: 2019-09-16 19:23 +0200
http://bitbucket.org/pypy/pypy/changeset/f41451c91702/

Log:	un-mess argument handling and test of select.poll().poll():
	previously the test was passing completely by accident, since the
	argument A() was interpreted as a timeout, not a fileno! Now we also
	support negative timeouts, which means block. also, add docstrings.

diff --git a/pypy/module/select/interp_select.py b/pypy/module/select/interp_select.py
--- a/pypy/module/select/interp_select.py
+++ b/pypy/module/select/interp_select.py
@@ -30,11 +30,23 @@
 
     @unwrap_spec(events="c_ushort")
     def register(self, space, w_fd, events=defaultevents):
+        """
+        Register a file descriptor with the polling object.
+        fd -- either an integer, or an object with a fileno() method returning an
+              int.
+        events -- an optional bitmask describing the type of events to check for
+        """
         fd = space.c_filedescriptor_w(w_fd)
         self.fddict[fd] = events
 
     @unwrap_spec(events="c_ushort")
     def modify(self, space, w_fd, events):
+        """
+        Modify an already registered file descriptor.
+        fd -- either an integer, or an object with a fileno() method returning an
+          int.
+        events -- an optional bitmask describing the type of events to check for
+        """
         fd = space.c_filedescriptor_w(w_fd)
         if fd not in self.fddict:
             raise wrap_oserror(space, OSError(errno.ENOENT, "poll.modify"),
@@ -42,6 +54,9 @@
         self.fddict[fd] = events
 
     def unregister(self, space, w_fd):
+        """
+        Remove a file descriptor being tracked by the polling object.
+        """
         fd = space.c_filedescriptor_w(w_fd)
         try:
             del self.fddict[fd]
@@ -50,21 +65,24 @@
 
     @unwrap_spec(w_timeout=WrappedDefault(None))
     def poll(self, space, w_timeout):
-        """WARNING: the timeout parameter is in **milliseconds**!"""
+        """
+        Polls the set of registered file descriptors, returning a list containing
+        any descriptors that have events or errors to report.
+
+        the timeout parameter is in milliseconds"""
         if space.is_w(w_timeout, space.w_None):
             timeout = -1
             end_time = 0
+        elif space.isinstance_w(w_timeout, space.w_float) or space.isinstance_w(w_timeout, space.w_int):
+            if space.is_true(space.lt(w_timeout, space.newint(0))):
+                timeout = -1
+                end_time = 0
+            else:
+                timeout = space.c_int_w(space.int(w_timeout))
+                end_time = timeutils.monotonic(space) + timeout * 0.001
         else:
-            # we want to be compatible with cpython and also accept things
-            # that can be casted to integer (I think)
-            try:
-                # compute the integer
-                w_timeout = space.int(w_timeout)
-            except OperationError:
-                raise oefmt(space.w_TypeError,
-                            "timeout must be an integer or None")
-            timeout = space.c_int_w(w_timeout)
-            end_time = timeutils.monotonic(space) + timeout * 0.001
+            raise oefmt(space.w_TypeError,
+                        "timeout must be an integer or None")
 
         if self.running:
             raise oefmt(space.w_RuntimeError, "concurrent poll() invocation")
diff --git a/pypy/module/select/test/test_select.py b/pypy/module/select/test/test_select.py
--- a/pypy/module/select/test/test_select.py
+++ b/pypy/module/select/test/test_select.py
@@ -217,9 +217,25 @@
         readend, writeend = self.getpair()
         try:
             class A(object):
-                def __int__(self):
+                def fileno(self):
                     return readend.fileno()
-            select.poll().poll(A()) # assert did not crash
+            poll = select.poll()
+            poll.register(A())
+
+            res = poll.poll(10) # timeout in ms
+            assert res == []
+            res = poll.poll(1.1) # check floats
+            assert res == []
+
+            writeend.send(b"foo!")
+            # can't easily test actual blocking, is done in lib-python tests
+            res = poll.poll()
+            assert res == [(readend.fileno(), 1)]
+
+            # check negative timeout
+            # proper test in lib-python, test_poll_blocks_with_negative_ms
+            res = poll.poll(-0.001)
+            assert res == [(readend.fileno(), 1)]
         finally:
             readend.close()
             writeend.close()
@@ -238,7 +254,6 @@
         pollster.register(0, 65535) # USHRT_MAX
         raises(OverflowError, pollster.register, 0, 65536) # USHRT_MAX + 1
         raises(OverflowError, pollster.poll, 2147483648) # INT_MAX +  1
-        raises(OverflowError, pollster.poll, -2147483648 - 1)
         raises(OverflowError, pollster.poll, 4294967296) # UINT_MAX + 1
         exc = raises(TypeError, pollster.poll, '123')
         assert str(exc.value) == 'timeout must be an integer or None'


More information about the pypy-commit mailing list