Skip to content

Commit a06cb2e

Browse files
committed
bpo-32568: reject sizehint=0 and revert removal of flags value check
Also update tests accordingly.
1 parent 6aa1d21 commit a06cb2e

3 files changed

Lines changed: 36 additions & 16 deletions

File tree

Doc/library/select.rst

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,16 @@ The module defines the following:
5757

5858
(Only supported on Linux 2.5.44 and newer.) Return an edge polling object,
5959
which can be used as Edge or Level Triggered interface for I/O
60-
events. *sizehint* is only used on systems where :c:func:`epoll_create1`
61-
is not available. *flags* is deprecated and completely ignored.
60+
events.
61+
62+
*sizehint* informs epoll about the expected number of events to be
63+
registered. It must be positive, or `-1` to use the default. It is only
64+
used on older systems where :c:func:`epoll_create1` is not available;
65+
otherwise it has no effect (though its value is still checked).
66+
67+
*flags* is deprecated and completely ignored. However, when supplied, its
68+
value must be ``0`` or ``select.EPOLL_CLOEXEC``, otherwise ``OSError`` is
69+
raised.
6270

6371
See the :ref:`epoll-objects` section below for the methods supported by
6472
epolling objects.

Lib/test/test_epoll.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,11 @@ def test_create(self):
7474
ep.close()
7575
self.assertTrue(ep.closed)
7676
self.assertRaises(ValueError, ep.fileno)
77+
7778
if hasattr(select, "EPOLL_CLOEXEC"):
78-
select.epoll(select.EPOLL_CLOEXEC).close()
79+
select.epoll(-1, select.EPOLL_CLOEXEC).close()
7980
select.epoll(flags=select.EPOLL_CLOEXEC).close()
80-
select.epoll(flags=0).close()
81-
# the flags parameter is now ignored
82-
select.epoll(flags=12356).close()
81+
select.epoll(flags=0).close()
8382

8483
def test_badcreate(self):
8584
self.assertRaises(TypeError, select.epoll, 1, 2, 3)
@@ -89,6 +88,13 @@ def test_badcreate(self):
8988
self.assertRaises(TypeError, select.epoll, ['foo'])
9089
self.assertRaises(TypeError, select.epoll, {})
9190

91+
self.assertRaises(ValueError, select.epoll, 0)
92+
self.assertRaises(ValueError, select.epoll, -2)
93+
self.assertRaises(ValueError, select.epoll, sizehint=-2)
94+
95+
if hasattr(select, "EPOLL_CLOEXEC"):
96+
self.assertRaises(OSError, select.epoll, flags=12356)
97+
9298
def test_context_manager(self):
9399
with select.epoll(16) as ep:
94100
self.assertGreater(ep.fileno(), 0)
@@ -118,19 +124,19 @@ def test_add(self):
118124
try:
119125
# TypeError: argument must be an int, or have a fileno() method.
120126
self.assertRaises(TypeError, ep.register, object(),
121-
select.EPOLLIN | select.EPOLLOUT)
127+
select.EPOLLIN | select.EPOLLOUT)
122128
self.assertRaises(TypeError, ep.register, None,
123-
select.EPOLLIN | select.EPOLLOUT)
129+
select.EPOLLIN | select.EPOLLOUT)
124130
# ValueError: file descriptor cannot be a negative integer (-1)
125131
self.assertRaises(ValueError, ep.register, -1,
126-
select.EPOLLIN | select.EPOLLOUT)
132+
select.EPOLLIN | select.EPOLLOUT)
127133
# OSError: [Errno 9] Bad file descriptor
128134
self.assertRaises(OSError, ep.register, 10000,
129-
select.EPOLLIN | select.EPOLLOUT)
135+
select.EPOLLIN | select.EPOLLOUT)
130136
# registering twice also raises an exception
131137
ep.register(server, select.EPOLLIN | select.EPOLLOUT)
132138
self.assertRaises(OSError, ep.register, server,
133-
select.EPOLLIN | select.EPOLLOUT)
139+
select.EPOLLIN | select.EPOLLOUT)
134140
finally:
135141
ep.close()
136142

@@ -161,9 +167,9 @@ def test_control_and_wait(self):
161167

162168
ep = select.epoll(16)
163169
ep.register(server.fileno(),
164-
select.EPOLLIN | select.EPOLLOUT | select.EPOLLET)
170+
select.EPOLLIN | select.EPOLLOUT | select.EPOLLET)
165171
ep.register(client.fileno(),
166-
select.EPOLLIN | select.EPOLLOUT | select.EPOLLET)
172+
select.EPOLLIN | select.EPOLLOUT | select.EPOLLET)
167173

168174
now = time.monotonic()
169175
events = ep.poll(1, 4)

Modules/selectmodule.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1306,12 +1306,18 @@ pyepoll_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
13061306
if (sizehint == -1) {
13071307
sizehint = FD_SETSIZE - 1;
13081308
}
1309-
else if (sizehint < -1) {
1310-
PyErr_SetString(PyExc_ValueError, "sizehint must be positive, 0 or -1");
1309+
else if (sizehint <= 0) {
1310+
PyErr_SetString(PyExc_ValueError, "sizehint must be positive or -1");
13111311
return NULL;
13121312
}
13131313

1314-
return newPyEpoll_Object(type, sizehint, -1);
1314+
#ifdef HAVE_EPOLL_CREATE1
1315+
if (flags && flags != EPOLL_CLOEXEC) {
1316+
PyErr_SetString(PyExc_OSError, "invalid flags");
1317+
return NULL;
1318+
}
1319+
#endif
1320+
return newPyEpoll_Object(type, sizehint, -1);
13151321
}
13161322

13171323

0 commit comments

Comments
 (0)